summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/html
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/WebKit/Source/core/html
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/html')
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ClassList.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ClassList.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h208
-rw-r--r--chromium/third_party/WebKit/Source/core/html/CollectionType.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/DOMFormData.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp165
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormData.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormDataList.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormDataList.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp215
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp167
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp298
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp666
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCollection.h152
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp (renamed from chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp)45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl (renamed from chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl)1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDocument.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp372
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLElement.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLElement.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp141
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp157
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp565
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp349
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp190
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImport.h193
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp181
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp175
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp402
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h202
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp258
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp1580
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h349
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp138
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLModElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp (renamed from chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp)35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp (renamed from chromium/third_party/WebKit/Source/core/html/ime/Composition.h)45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp159
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp107
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp399
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp (renamed from chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp)9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl (renamed from chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl)4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp163
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp176
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp123
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp107
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp89
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp (renamed from chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h)27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h (renamed from chromium/third_party/WebKit/Source/core/html/ime/Composition.idl)31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageData.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageData.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageData.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageDocument.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelableElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkManifest.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp67
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkResource.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkResource.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaController.cpp249
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaController.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaController.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaDocument.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaError.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaError.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PluginDocument.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PublicURLManager.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/html/RadioNodeList.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextDocument.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextDocument.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextMetrics.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextMetrics.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/URLRegistry.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ValidityState.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ValidityState.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp87
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp1395
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h143
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl266
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DataView.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Path.idl68
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h (renamed from chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h)44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl41
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp211
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp5569
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h887
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl641
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp5728
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h914
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl689
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FormController.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp216
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputType.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp (renamed from chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp)87
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h (renamed from chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h)21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/StepRange.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp144
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp143
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h147
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp236
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h (renamed from chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h)77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h (renamed from chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h)12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp229
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h (renamed from chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h)86
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h (renamed from chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h)51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp184
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h (renamed from chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h)58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp (renamed from chromium/third_party/WebKit/Source/core/html/LinkImport.cpp)88
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h (renamed from chromium/third_party/WebKit/Source/core/html/LinkImport.h)22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp114
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp224
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp106
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp201
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp279
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp186
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp439
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h106
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp371
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp8
-rwxr-xr-xchromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table133
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h104
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h107
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp128
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h84
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp411
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h130
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp410
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h137
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp225
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp172
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp277
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp118
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrack.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp71
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp (renamed from chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp)55
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackBase.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h139
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp357
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp190
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp149
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp171
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h233
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp352
648 files changed, 25858 insertions, 21668 deletions
diff --git a/chromium/third_party/WebKit/Source/core/html/ClassList.cpp b/chromium/third_party/WebKit/Source/core/html/ClassList.cpp
index ba44f7b0b0d..a6c8156260a 100644
--- a/chromium/third_party/WebKit/Source/core/html/ClassList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ClassList.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "core/html/ClassList.h"
+#include "core/dom/Document.h"
namespace WebCore {
@@ -32,6 +33,7 @@ using namespace HTMLNames;
ClassList::ClassList(Element* element) : m_element(element) { }
+#if !ENABLE(OILPAN)
void ClassList::ref()
{
m_element->ref();
@@ -41,6 +43,7 @@ void ClassList::deref()
{
m_element->deref();
}
+#endif
unsigned ClassList::length() const
{
@@ -70,4 +73,10 @@ const SpaceSplitString& ClassList::classNames() const
return m_element->elementData()->classNames();
}
+void ClassList::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ DOMTokenList::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ClassList.h b/chromium/third_party/WebKit/Source/core/html/ClassList.h
index cc2217fab5e..13444d97253 100644
--- a/chromium/third_party/WebKit/Source/core/html/ClassList.h
+++ b/chromium/third_party/WebKit/Source/core/html/ClassList.h
@@ -25,7 +25,7 @@
#ifndef ClassList_h
#define ClassList_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/DOMTokenList.h"
#include "core/dom/Element.h"
#include "core/dom/SpaceSplitString.h"
@@ -38,15 +38,17 @@ class Element;
typedef int ExceptionCode;
-class ClassList : public DOMTokenList {
+class ClassList FINAL : public DOMTokenList {
public:
- static PassOwnPtr<ClassList> create(Element* element)
+ static PassOwnPtrWillBeRawPtr<ClassList> create(Element* element)
{
- return adoptPtr(new ClassList(element));
+ return adoptPtrWillBeNoop(new ClassList(element));
}
+#if !ENABLE(OILPAN)
virtual void ref() OVERRIDE;
virtual void deref() OVERRIDE;
+#endif
virtual unsigned length() const OVERRIDE;
virtual const AtomicString item(unsigned index) const OVERRIDE;
@@ -55,17 +57,19 @@ public:
void clearValueForQuirksMode() { m_classNamesForQuirksMode = nullptr; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ClassList(Element*);
+ explicit ClassList(Element*);
virtual bool containsInternal(const AtomicString&) const OVERRIDE;
const SpaceSplitString& classNames() const;
- virtual AtomicString value() const OVERRIDE { return m_element->getAttribute(HTMLNames::classAttr); }
+ virtual const AtomicString& value() const OVERRIDE { return m_element->getAttribute(HTMLNames::classAttr); }
virtual void setValue(const AtomicString& value) OVERRIDE { m_element->setAttribute(HTMLNames::classAttr, value); }
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
mutable OwnPtr<SpaceSplitString> m_classNamesForQuirksMode;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h b/chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h
new file mode 100644
index 00000000000..865104ba059
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. 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 CollectionIndexCache_h
+#define CollectionIndexCache_h
+
+#include "core/dom/Element.h"
+
+namespace WebCore {
+
+template <typename Collection, typename NodeType>
+class CollectionIndexCache {
+ DISALLOW_ALLOCATION();
+public:
+ CollectionIndexCache();
+
+ bool isEmpty(const Collection& collection)
+ {
+ if (isCachedNodeCountValid())
+ return !cachedNodeCount();
+ if (cachedNode())
+ return false;
+ return !nodeAt(collection, 0);
+ }
+ bool hasExactlyOneNode(const Collection& collection)
+ {
+ if (isCachedNodeCountValid())
+ return cachedNodeCount() == 1;
+ if (cachedNode())
+ return !cachedNodeIndex() && !nodeAt(collection, 1);
+ return nodeAt(collection, 0) && !nodeAt(collection, 1);
+ }
+
+ unsigned nodeCount(const Collection&);
+ NodeType* nodeAt(const Collection&, unsigned index);
+
+ void invalidate();
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_currentNode);
+ }
+
+private:
+ NodeType* nodeBeforeCachedNode(const Collection&, unsigned index);
+ NodeType* nodeAfterCachedNode(const Collection&, unsigned index);
+
+ ALWAYS_INLINE NodeType* cachedNode() const { return m_currentNode; }
+ ALWAYS_INLINE unsigned cachedNodeIndex() const { ASSERT(cachedNode()); return m_cachedNodeIndex; }
+ ALWAYS_INLINE void setCachedNode(NodeType* node, unsigned index)
+ {
+ ASSERT(node);
+ m_currentNode = node;
+ m_cachedNodeIndex = index;
+ }
+
+ ALWAYS_INLINE bool isCachedNodeCountValid() const { return m_isLengthCacheValid; }
+ ALWAYS_INLINE unsigned cachedNodeCount() const { return m_cachedNodeCount; }
+ ALWAYS_INLINE void setCachedNodeCount(unsigned length)
+ {
+ m_cachedNodeCount = length;
+ m_isLengthCacheValid = true;
+ }
+
+ RawPtrWillBeMember<NodeType> m_currentNode;
+ unsigned m_cachedNodeCount;
+ unsigned m_cachedNodeIndex;
+ unsigned m_isLengthCacheValid : 1;
+};
+
+template <typename Collection, typename NodeType>
+CollectionIndexCache<Collection, NodeType>::CollectionIndexCache()
+ : m_currentNode(nullptr)
+ , m_cachedNodeCount(0)
+ , m_cachedNodeIndex(0)
+ , m_isLengthCacheValid(false)
+{
+}
+
+template <typename Collection, typename NodeType>
+void CollectionIndexCache<Collection, NodeType>::invalidate()
+{
+ m_currentNode = nullptr;
+ m_isLengthCacheValid = false;
+}
+
+template <typename Collection, typename NodeType>
+inline unsigned CollectionIndexCache<Collection, NodeType>::nodeCount(const Collection& collection)
+{
+ if (isCachedNodeCountValid())
+ return cachedNodeCount();
+
+ nodeAt(collection, UINT_MAX);
+ ASSERT(isCachedNodeCountValid());
+
+ return cachedNodeCount();
+}
+
+template <typename Collection, typename NodeType>
+inline NodeType* CollectionIndexCache<Collection, NodeType>::nodeAt(const Collection& collection, unsigned index)
+{
+ if (isCachedNodeCountValid() && index >= cachedNodeCount())
+ return 0;
+
+ if (cachedNode()) {
+ if (index > cachedNodeIndex())
+ return nodeAfterCachedNode(collection, index);
+ if (index < cachedNodeIndex())
+ return nodeBeforeCachedNode(collection, index);
+ return cachedNode();
+ }
+
+ // No valid cache yet, let's find the first matching element.
+ ASSERT(!isCachedNodeCountValid());
+ NodeType* firstNode = collection.traverseToFirstElement();
+ if (!firstNode) {
+ // The collection is empty.
+ setCachedNodeCount(0);
+ return 0;
+ }
+ setCachedNode(firstNode, 0);
+ return index ? nodeAfterCachedNode(collection, index) : firstNode;
+}
+
+template <typename Collection, typename NodeType>
+inline NodeType* CollectionIndexCache<Collection, NodeType>::nodeBeforeCachedNode(const Collection& collection, unsigned index)
+{
+ ASSERT(cachedNode()); // Cache should be valid.
+ unsigned currentIndex = cachedNodeIndex();
+ ASSERT(currentIndex > index);
+
+ // Determine if we should traverse from the beginning of the collection instead of the cached node.
+ bool firstIsCloser = index < currentIndex - index;
+ if (firstIsCloser || !collection.canTraverseBackward()) {
+ NodeType* firstNode = collection.traverseToFirstElement();
+ ASSERT(firstNode);
+ setCachedNode(firstNode, 0);
+ return index ? nodeAfterCachedNode(collection, index) : firstNode;
+ }
+
+ // Backward traversal from the cached node to the requested index.
+ ASSERT(collection.canTraverseBackward());
+ NodeType* currentNode = collection.traverseBackwardToOffset(index, *cachedNode(), currentIndex);
+ ASSERT(currentNode);
+ setCachedNode(currentNode, currentIndex);
+ return currentNode;
+}
+
+template <typename Collection, typename NodeType>
+inline NodeType* CollectionIndexCache<Collection, NodeType>::nodeAfterCachedNode(const Collection& collection, unsigned index)
+{
+ ASSERT(cachedNode()); // Cache should be valid.
+ unsigned currentIndex = cachedNodeIndex();
+ ASSERT(currentIndex < index);
+
+ // Determine if we should traverse from the end of the collection instead of the cached node.
+ bool lastIsCloser = isCachedNodeCountValid() && cachedNodeCount() - index < index - currentIndex;
+ if (lastIsCloser && collection.canTraverseBackward()) {
+ NodeType* lastItem = collection.traverseToLastElement();
+ ASSERT(lastItem);
+ setCachedNode(lastItem, cachedNodeCount() - 1);
+ if (index < cachedNodeCount() - 1)
+ return nodeBeforeCachedNode(collection, index);
+ return lastItem;
+ }
+
+ // Forward traversal from the cached node to the requested index.
+ NodeType* currentNode = collection.traverseForwardToOffset(index, *cachedNode(), currentIndex);
+ if (!currentNode) {
+ // Did not find the node. On plus side, we now know the length.
+ setCachedNodeCount(currentIndex + 1);
+ return 0;
+ }
+ setCachedNode(currentNode, currentIndex);
+ return currentNode;
+}
+
+} // namespace WebCore
+
+#endif // CollectionIndexCache_h
diff --git a/chromium/third_party/WebKit/Source/core/html/CollectionType.h b/chromium/third_party/WebKit/Source/core/html/CollectionType.h
index 9db25d42e2e..f57a0c223b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/CollectionType.h
+++ b/chromium/third_party/WebKit/Source/core/html/CollectionType.h
@@ -36,10 +36,6 @@ enum CollectionType {
DocScripts, // all <script> elements
DocAll, // "all" elements (IE)
- // Named collection types cached in the document.
- WindowNamedItems,
- DocumentNamedItems,
-
// Unnamed HTMLCollection types cached in elements.
NodeChildren, // first-level children (ParentNode DOM interface)
TableTBodies, // all <tbody> elements in this table
@@ -52,21 +48,38 @@ enum CollectionType {
MapAreas,
FormControls,
+ // Named HTMLCollection types cached in the document.
+ WindowNamedItems,
+ DocumentNamedItems,
+
+ // Named HTMLCollection types cached in elements.
+ ClassCollectionType,
+ TagCollectionType,
+ HTMLTagCollectionType,
+
// Live NodeList.
- ChildNodeListType,
- ClassNodeListType,
NameNodeListType,
- TagNodeListType,
- HTMLTagNodeListType,
RadioNodeListType,
+ RadioImgNodeListType,
LabelsNodeListType,
};
-static const CollectionType FirstNodeListType = ChildNodeListType;
+static const CollectionType FirstNamedCollectionType = WindowNamedItems;
+static const CollectionType FirstLiveNodeListType = NameNodeListType;
+
+inline bool isUnnamedHTMLCollectionType(CollectionType type)
+{
+ return type < FirstNamedCollectionType;
+}
+
+inline bool isHTMLCollectionType(CollectionType type)
+{
+ return type < FirstLiveNodeListType;
+}
-inline bool isNodeList(CollectionType type)
+inline bool isLiveNodeListType(CollectionType type)
{
- return type >= FirstNodeListType;
+ return type >= FirstLiveNodeListType;
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/DOMFormData.h b/chromium/third_party/WebKit/Source/core/html/DOMFormData.h
index c522b72a0c8..58ce890a29d 100644
--- a/chromium/third_party/WebKit/Source/core/html/DOMFormData.h
+++ b/chromium/third_party/WebKit/Source/core/html/DOMFormData.h
@@ -32,6 +32,7 @@
#define DOMFormData_h
#include "core/html/FormDataList.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -45,10 +46,17 @@ namespace WebCore {
class Blob;
class HTMLFormElement;
-class DOMFormData : public FormDataList, public ScriptWrappable, public RefCounted<DOMFormData> {
+class DOMFormData : public RefCountedWillBeGarbageCollectedFinalized<DOMFormData>, public FormDataList, public ScriptWrappable {
public:
- static PassRefPtr<DOMFormData> create(HTMLFormElement* form) { return adoptRef(new DOMFormData(form)); }
- static PassRefPtr<DOMFormData> create(const WTF::TextEncoding& encoding) { return adoptRef(new DOMFormData(encoding)); }
+ static PassRefPtrWillBeRawPtr<DOMFormData> create(HTMLFormElement* form = 0)
+ {
+ return adoptRefWillBeNoop(new DOMFormData(form));
+ }
+
+ static PassRefPtrWillBeRawPtr<DOMFormData> create(const WTF::TextEncoding& encoding)
+ {
+ return adoptRefWillBeNoop(new DOMFormData(encoding));
+ }
void append(const String& name, const String& value);
void append(const String& name, Blob*, const String& filename = String());
diff --git a/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp
new file mode 100644
index 00000000000..223f8a90cf8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/DocumentNameCollection.h"
+
+#include "core/html/HTMLEmbedElement.h"
+#include "core/html/HTMLFormElement.h"
+#include "core/html/HTMLObjectElement.h"
+
+namespace WebCore {
+
+DocumentNameCollection::DocumentNameCollection(ContainerNode& document, const AtomicString& name)
+ : HTMLNameCollection(document, DocumentNamedItems, name)
+{
+}
+
+bool DocumentNameCollection::elementMatches(const Element& element) const
+{
+ // Match 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 (isHTMLFormElement(element) || isHTMLIFrameElement(element) || (isHTMLEmbedElement(element) && toHTMLEmbedElement(element).isExposed()))
+ return element.getNameAttribute() == m_name;
+ if (isHTMLAppletElement(element) || (isHTMLObjectElement(element) && toHTMLObjectElement(element).isExposed()))
+ return element.getNameAttribute() == m_name || element.getIdAttribute() == m_name;
+ if (isHTMLImageElement(element))
+ return element.getNameAttribute() == m_name || (element.getIdAttribute() == m_name && element.hasName());
+ return false;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h
new file mode 100644
index 00000000000..2789bacfb9b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DocumentNameCollection_h
+#define DocumentNameCollection_h
+
+#include "core/html/HTMLNameCollection.h"
+
+namespace WebCore {
+
+class DocumentNameCollection FINAL : public HTMLNameCollection {
+public:
+ static PassRefPtrWillBeRawPtr<DocumentNameCollection> create(ContainerNode& document, CollectionType type, const AtomicString& name)
+ {
+ ASSERT_UNUSED(type, type == DocumentNamedItems);
+ return adoptRefWillBeNoop(new DocumentNameCollection(document, name));
+ }
+
+ bool elementMatches(const Element&) const;
+
+private:
+ DocumentNameCollection(ContainerNode& document, const AtomicString& name);
+};
+
+DEFINE_TYPE_CASTS(DocumentNameCollection, LiveNodeListBase, collection, collection->type() == DocumentNamedItems, collection.type() == DocumentNamedItems);
+
+} // namespace WebCore
+
+#endif // DocumentNameCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
index ce1f4b58ddb..41c49e81d43 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/FormAssociatedElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/IdTargetObserver.h"
#include "core/html/HTMLFormControlElement.h"
#include "core/html/HTMLFormElement.h"
@@ -36,20 +36,21 @@ namespace WebCore {
using namespace HTMLNames;
-class FormAttributeTargetObserver : IdTargetObserver {
- WTF_MAKE_FAST_ALLOCATED;
+class FormAttributeTargetObserver : public IdTargetObserver {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<FormAttributeTargetObserver> create(const AtomicString& id, FormAssociatedElement*);
+ static PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> create(const AtomicString& id, FormAssociatedElement*);
+ virtual void trace(Visitor*) OVERRIDE;
virtual void idTargetChanged() OVERRIDE;
private:
FormAttributeTargetObserver(const AtomicString& id, FormAssociatedElement*);
- FormAssociatedElement* m_element;
+ RawPtrWillBeMember<FormAssociatedElement> m_element;
};
FormAssociatedElement::FormAssociatedElement()
- : m_form(0)
+ : m_formWasSetByParser(false)
{
}
@@ -58,6 +59,13 @@ FormAssociatedElement::~FormAssociatedElement()
// We can't call setForm here because it contains virtual calls.
}
+void FormAssociatedElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_formAttributeTargetObserver);
+ visitor->trace(m_form);
+ visitor->trace(m_validityState);
+}
+
ValidityState* FormAssociatedElement::validity()
{
if (!m_validityState)
@@ -70,15 +78,14 @@ void FormAssociatedElement::didMoveToNewDocument(Document& oldDocument)
{
HTMLElement* element = toHTMLElement(this);
if (element->fastHasAttribute(formAttr))
- m_formAttributeTargetObserver = nullptr;
+ setFormAttributeTargetObserver(nullptr);
}
void FormAssociatedElement::insertedInto(ContainerNode* insertionPoint)
{
- if (m_form && insertionPoint->highestAncestor() != m_form->highestAncestor())
- setForm(0);
+ if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_form->highestAncestorOrSelf())
+ resetFormOwner();
- resetFormOwner();
if (!insertionPoint->inDocument())
return;
@@ -91,52 +98,71 @@ void FormAssociatedElement::removedFrom(ContainerNode* insertionPoint)
{
HTMLElement* element = toHTMLElement(this);
if (insertionPoint->inDocument() && element->fastHasAttribute(formAttr))
- m_formAttributeTargetObserver = nullptr;
+ setFormAttributeTargetObserver(nullptr);
// 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 && element->highestAncestor() != m_form->highestAncestor())
- setForm(0);
+ if (m_form && element->highestAncestorOrSelf() != m_form->highestAncestorOrSelf())
+ resetFormOwner();
}
-HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element, HTMLFormElement* currentAssociatedForm)
+HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element)
{
const AtomicString& formId(element->fastGetAttribute(formAttr));
+ // 3. If the element is reassociateable, has a form content attribute, and
+ // is itself in a Document, then run these substeps:
if (!formId.isNull() && element->inDocument()) {
- // 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
- // treeScope()->getElementById() over the given element.
- HTMLFormElement* newForm = 0;
+ // 3.1. If the first element in the Document to have an ID that is
+ // case-sensitively equal to the element's form content attribute's
+ // value is a form element, then associate the form-associated element
+ // with that form element.
+ // 3.2. Abort the "reset the form owner" steps.
Element* newFormCandidate = element->treeScope().getElementById(formId);
- if (newFormCandidate && newFormCandidate->hasTagName(formTag))
- newForm = toHTMLFormElement(newFormCandidate);
- return newForm;
+ return isHTMLFormElement(newFormCandidate) ? toHTMLFormElement(newFormCandidate) : 0;
}
-
- if (!currentAssociatedForm)
- return element->findFormAncestor();
-
- return currentAssociatedForm;
+ // 4. Otherwise, if the form-associated element in question has an ancestor
+ // form element, then associate the form-associated element with the nearest
+ // such ancestor form element.
+ return element->findFormAncestor();
}
-void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
+void FormAssociatedElement::formRemovedFromTree(const Node& formRoot)
{
ASSERT(m_form);
- if (toHTMLElement(this)->highestAncestor() == formRoot)
+ if (toHTMLElement(this)->highestAncestorOrSelf() == formRoot)
return;
- setForm(0);
+ resetFormOwner();
+}
+
+void FormAssociatedElement::associateByParser(HTMLFormElement* form)
+{
+ if (form && form->inDocument()) {
+ m_formWasSetByParser = true;
+ setForm(form);
+ form->didAssociateByParser();
+ }
}
void FormAssociatedElement::setForm(HTMLFormElement* newForm)
{
- if (m_form == newForm)
+ if (m_form.get() == newForm)
return;
willChangeForm();
if (m_form)
- m_form->removeFormElement(this);
- m_form = newForm;
- if (m_form)
- m_form->registerFormElement(*this);
+ m_form->disassociate(*this);
+ if (newForm) {
+#if ENABLE(OILPAN)
+ m_form = newForm;
+#else
+ m_form = newForm->createWeakPtr();
+#endif
+ m_form->associate(*this);
+ } else {
+#if ENABLE(OILPAN)
+ m_form = nullptr;
+#else
+ m_form = WeakPtr<HTMLFormElement>();
+#endif
+ }
didChangeForm();
}
@@ -148,41 +174,31 @@ void FormAssociatedElement::didChangeForm()
{
}
-void FormAssociatedElement::formWillBeDestroyed()
-{
- ASSERT(m_form);
- if (!m_form)
- return;
- willChangeForm();
- m_form = 0;
- didChangeForm();
-}
-
void FormAssociatedElement::resetFormOwner()
{
- HTMLFormElement* originalForm = m_form;
- setForm(findAssociatedForm(toHTMLElement(this), m_form));
+ m_formWasSetByParser = false;
HTMLElement* element = toHTMLElement(this);
- if (m_form && m_form != originalForm && m_form->inDocument())
+ const AtomicString& formId(element->fastGetAttribute(formAttr));
+ HTMLFormElement* nearestForm = element->findFormAncestor();
+ // 1. If the element's form owner is not null, and either the element is not
+ // reassociateable or its form content attribute is not present, and the
+ // element's form owner is its nearest form element ancestor after the
+ // change to the ancestor chain, then do nothing, and abort these steps.
+ if (m_form && formId.isNull() && m_form.get() == nearestForm)
+ return;
+
+ HTMLFormElement* originalForm = m_form.get();
+ setForm(findAssociatedForm(element));
+ // FIXME: Move didAssociateFormControl call to didChangeForm or
+ // HTMLFormElement::associate.
+ if (m_form && m_form.get() != originalForm && m_form->inDocument())
element->document().didAssociateFormControl(element);
}
void FormAssociatedElement::formAttributeChanged()
{
- HTMLElement* element = toHTMLElement(this);
- if (!element->fastHasAttribute(formAttr)) {
- // The form attribute removed. We need to reset form owner here.
- HTMLFormElement* originalForm = m_form;
- setForm(element->findFormAncestor());
- HTMLElement* element = toHTMLElement(this);
- if (m_form && m_form != originalForm && m_form->inDocument())
- element->document().didAssociateFormControl(element);
- m_formAttributeTargetObserver = nullptr;
- } else {
- resetFormOwner();
- if (element->inDocument())
- resetFormAttributeTargetObserver();
- }
+ resetFormOwner();
+ resetFormAttributeTargetObserver();
}
bool FormAssociatedElement::customError() const
@@ -253,10 +269,21 @@ void FormAssociatedElement::setCustomValidity(const String& error)
m_customValidationMessage = error;
}
+void FormAssociatedElement::setFormAttributeTargetObserver(PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> newObserver)
+{
+ if (m_formAttributeTargetObserver)
+ m_formAttributeTargetObserver->unregister();
+ m_formAttributeTargetObserver = newObserver;
+}
+
void FormAssociatedElement::resetFormAttributeTargetObserver()
{
- ASSERT(toHTMLElement(this)->inDocument());
- m_formAttributeTargetObserver = FormAttributeTargetObserver::create(toHTMLElement(this)->fastGetAttribute(formAttr), this);
+ HTMLElement* element = toHTMLElement(this);
+ const AtomicString& formId(element->fastGetAttribute(formAttr));
+ if (!formId.isNull() && element->inDocument())
+ setFormAttributeTargetObserver(FormAttributeTargetObserver::create(formId, this));
+ else
+ setFormAttributeTargetObserver(nullptr);
}
void FormAssociatedElement::formAttributeTargetChanged()
@@ -299,9 +326,9 @@ HTMLElement& toHTMLElement(FormAssociatedElement& associatedElement)
return const_cast<HTMLElement&>(toHTMLElement(static_cast<const FormAssociatedElement&>(associatedElement)));
}
-PassOwnPtr<FormAttributeTargetObserver> FormAttributeTargetObserver::create(const AtomicString& id, FormAssociatedElement* element)
+PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> FormAttributeTargetObserver::create(const AtomicString& id, FormAssociatedElement* element)
{
- return adoptPtr(new FormAttributeTargetObserver(id, element));
+ return adoptPtrWillBeNoop(new FormAttributeTargetObserver(id, element));
}
FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id, FormAssociatedElement* element)
@@ -310,6 +337,12 @@ FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id,
{
}
+void FormAttributeTargetObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ IdTargetObserver::trace(visitor);
+}
+
void FormAttributeTargetObserver::idTargetChanged()
{
m_element->formAttributeTargetChanged();
diff --git a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h
index 15f2fa1fbc8..e41483a55c0 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h
@@ -24,6 +24,8 @@
#ifndef FormAssociatedElement_h
#define FormAssociatedElement_h
+#include "platform/heap/Handle.h"
+#include "wtf/WeakPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -39,15 +41,17 @@ class ValidationMessage;
class ValidityState;
class VisibleSelection;
-class FormAssociatedElement {
+class FormAssociatedElement : public WillBeGarbageCollectedMixin {
public:
virtual ~FormAssociatedElement();
+#if !ENABLE(OILPAN)
void ref() { refFormAssociatedElement(); }
void deref() { derefFormAssociatedElement(); }
+#endif
- static HTMLFormElement* findAssociatedForm(const HTMLElement*, HTMLFormElement*);
- HTMLFormElement* form() const { return m_form; }
+ static HTMLFormElement* findAssociatedForm(const HTMLElement*);
+ HTMLFormElement* form() const { return m_form.get(); }
ValidityState* validity();
virtual bool isFormControlElement() const = 0;
@@ -63,11 +67,9 @@ public:
// Return true for a successful control (see HTML4-17.13.2).
virtual bool appendFormData(FormDataList&, bool) { return false; }
- void formWillBeDestroyed();
-
void resetFormOwner();
- void formRemovedFromTree(const Node* formRoot);
+ void formRemovedFromTree(const Node& formRoot);
// ValidityState attribute implementations
bool customError() const;
@@ -88,14 +90,20 @@ public:
void formAttributeTargetChanged();
+ typedef WillBeHeapVector<RawPtrWillBeMember<FormAssociatedElement> > List;
+
protected:
FormAssociatedElement();
+ void trace(Visitor*);
void insertedInto(ContainerNode*);
void removedFrom(ContainerNode*);
void didMoveToNewDocument(Document& oldDocument);
+ // FIXME: Remove usage of setForm. resetFormOwner should be enough, and
+ // setForm is confusing.
void setForm(HTMLFormElement*);
+ void associateByParser(HTMLFormElement*);
void formAttributeChanged();
// If you add an override of willChangeForm() or didChangeForm() to a class
@@ -107,15 +115,23 @@ protected:
String customValidationMessage() const;
private:
+#if !ENABLE(OILPAN)
virtual void refFormAssociatedElement() = 0;
virtual void derefFormAssociatedElement() = 0;
+#endif
+ void setFormAttributeTargetObserver(PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver>);
void resetFormAttributeTargetObserver();
- OwnPtr<FormAttributeTargetObserver> m_formAttributeTargetObserver;
- HTMLFormElement* m_form;
- OwnPtr<ValidityState> m_validityState;
+ OwnPtrWillBeMember<FormAttributeTargetObserver> m_formAttributeTargetObserver;
+#if ENABLE(OILPAN)
+ Member<HTMLFormElement> m_form;
+#else
+ WeakPtr<HTMLFormElement> m_form;
+#endif
+ OwnPtrWillBeMember<ValidityState> m_validityState;
String m_customValidationMessage;
+ bool m_formWasSetByParser;
};
HTMLElement* toHTMLElement(FormAssociatedElement*);
diff --git a/chromium/third_party/WebKit/Source/core/html/FormData.idl b/chromium/third_party/WebKit/Source/core/html/FormData.idl
index 73dcbfb9479..49914a7b35c 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormData.idl
+++ b/chromium/third_party/WebKit/Source/core/html/FormData.idl
@@ -28,14 +28,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#formdata
+
[
- Constructor([Default=Undefined] optional HTMLFormElement form),
- ImplementedAs=DOMFormData
+ Constructor(optional HTMLFormElement form),
+ Exposed=Window&Worker,
+ ImplementedAs=DOMFormData,
+ WillBeGarbageCollected,
] interface FormData {
- // void append(DOMString name, DOMString value);
- // void append(DOMString name, Blob value, optional DOMString filename);
- [Custom] void append([Default=Undefined] optional DOMString name,
- [Default=Undefined] optional DOMString value,
- [Default=Undefined] optional DOMString filename);
+ void append(DOMString name, Blob value, optional DOMString filename);
+ void append(DOMString name, DOMString value);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp b/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp
index b564d2cc102..39aa18ddaed 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp
@@ -43,22 +43,22 @@ void FormDataList::appendString(const CString& string)
m_items.append(string);
}
-void FormDataList::appendBlob(PassRefPtr<Blob> blob, const String& filename)
+void FormDataList::appendBlob(PassRefPtrWillBeRawPtr<Blob> blob, const String& filename)
{
m_items.append(Item(blob, filename));
}
-PassRefPtr<FormData> FormDataList::createFormData(const WTF::TextEncoding& encoding, FormData::EncodingType encodingType)
+PassRefPtr<FormData> FormDataList::createFormData(FormData::EncodingType encodingType)
{
RefPtr<FormData> result = FormData::create();
- appendKeyValuePairItemsTo(result.get(), encoding, false, encodingType);
+ appendKeyValuePairItemsTo(result.get(), m_encoding, false, encodingType);
return result.release();
}
-PassRefPtr<FormData> FormDataList::createMultiPartFormData(const WTF::TextEncoding& encoding)
+PassRefPtr<FormData> FormDataList::createMultiPartFormData()
{
RefPtr<FormData> result = FormData::create();
- appendKeyValuePairItemsTo(result.get(), encoding, true);
+ appendKeyValuePairItemsTo(result.get(), m_encoding, true);
return result.release();
}
@@ -69,7 +69,7 @@ void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::Text
Vector<char> encodedData;
- const Vector<FormDataList::Item>& items = this->items();
+ const WillBeHeapVector<Item>& items = this->items();
size_t formDataListSize = items.size();
ASSERT(!(formDataListSize % 2));
for (size_t i = 0; i < formDataListSize; i += 2) {
@@ -130,12 +130,7 @@ void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::Text
}
formData->appendData("\r\n", 2);
} else {
- // Omit the name "isindex" if it's the first form data element.
- // FIXME: Why is this a good rule? Is this obsolete now?
- if (encodedData.isEmpty() && key.data() == "isindex")
- FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
- else
- FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
+ FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
}
}
@@ -145,4 +140,14 @@ void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::Text
formData->appendData(encodedData.data(), encodedData.size());
}
+void FormDataList::trace(Visitor* visitor)
+{
+ visitor->trace(m_items);
+}
+
+void FormDataList::Item::trace(Visitor* visitor)
+{
+ visitor->trace(m_blob);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/FormDataList.h b/chromium/third_party/WebKit/Source/core/html/FormDataList.h
index 123e566f621..301365951d1 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormDataList.h
+++ b/chromium/third_party/WebKit/Source/core/html/FormDataList.h
@@ -22,6 +22,7 @@
#define FormDataList_h
#include "core/fileapi/Blob.h"
+#include "platform/heap/Handle.h"
#include "platform/network/FormData.h"
#include "wtf/Forward.h"
#include "wtf/text/CString.h"
@@ -32,18 +33,21 @@ namespace WebCore {
class FormDataList {
public:
class Item {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
Item() { }
Item(const WTF::CString& data) : m_data(data) { }
- Item(PassRefPtr<Blob> blob, const String& filename) : m_blob(blob), m_filename(filename) { }
+ Item(PassRefPtrWillBeRawPtr<Blob> blob, const String& filename) : m_blob(blob), m_filename(filename) { }
const WTF::CString& data() const { return m_data; }
Blob* blob() const { return m_blob.get(); }
const String& filename() const { return m_filename; }
+ void trace(Visitor*);
+
private:
WTF::CString m_data;
- RefPtr<Blob> m_blob;
+ RefPtrWillBeMember<Blob> m_blob;
String m_filename;
};
@@ -64,29 +68,33 @@ public:
appendString(key);
appendString(String::number(value));
}
- void appendBlob(const String& key, PassRefPtr<Blob> blob, const String& filename = String())
+ void appendBlob(const String& key, PassRefPtrWillBeRawPtr<Blob> blob, const String& filename = String())
{
appendString(key);
appendBlob(blob, filename);
}
- const Vector<Item>& items() const { return m_items; }
+ const WillBeHeapVector<Item>& items() const { return m_items; }
const WTF::TextEncoding& encoding() const { return m_encoding; }
- PassRefPtr<FormData> createFormData(const WTF::TextEncoding&, FormData::EncodingType = FormData::FormURLEncoded);
- PassRefPtr<FormData> createMultiPartFormData(const WTF::TextEncoding&);
+ PassRefPtr<FormData> createFormData(FormData::EncodingType = FormData::FormURLEncoded);
+ PassRefPtr<FormData> createMultiPartFormData();
+
+ void trace(Visitor*);
private:
void appendKeyValuePairItemsTo(FormData*, const WTF::TextEncoding&, bool isMultiPartForm, FormData::EncodingType = FormData::FormURLEncoded);
void appendString(const CString&);
void appendString(const String&);
- void appendBlob(PassRefPtr<Blob>, const String& filename);
+ void appendBlob(PassRefPtrWillBeRawPtr<Blob>, const String& filename);
WTF::TextEncoding m_encoding;
- Vector<Item> m_items;
+ WillBeHeapVector<Item> m_items;
};
} // namespace WebCore
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::FormDataList::Item);
+
#endif // FormDataList_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp
index 5fc4b8bee57..38c620a350b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp
@@ -31,13 +31,14 @@
namespace WebCore {
-PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(Node* node, CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLAllCollection> HTMLAllCollection::create(ContainerNode& node, CollectionType type)
{
- return adoptRef(new HTMLAllCollection(node, type));
+ ASSERT_UNUSED(type, type == DocAll);
+ return adoptRefWillBeNoop(new HTMLAllCollection(node));
}
-HTMLAllCollection::HTMLAllCollection(Node* node, CollectionType type)
- : HTMLCollection(node, type, DoesNotOverrideItemAfter)
+HTMLAllCollection::HTMLAllCollection(ContainerNode& node)
+ : HTMLCollection(node, DocAll, DoesNotOverrideItemAfter)
{
ScriptWrappable::init(this);
}
@@ -46,27 +47,28 @@ HTMLAllCollection::~HTMLAllCollection()
{
}
-Node* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
+Element* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
{
- updateNameCache();
+ updateIdNameCache();
- if (Vector<Element*>* cache = idCache(name)) {
- if (index < cache->size())
- return cache->at(index);
- index -= cache->size();
+ const NamedItemCache& cache = namedItemCache();
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* elements = cache.getElementsById(name)) {
+ if (index < elements->size())
+ return elements->at(index);
+ index -= elements->size();
}
- if (Vector<Element*>* cache = nameCache(name)) {
- if (index < cache->size())
- return cache->at(index);
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* elements = cache.getElementsByName(name)) {
+ if (index < elements->size())
+ return elements->at(index);
}
return 0;
}
-void HTMLAllCollection::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLAllCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtrWillBeRawPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtrWillBeRawPtr<Element>& returnValue1)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
this->namedItems(name, namedItems);
if (!namedItems.size())
@@ -84,9 +86,4 @@ void HTMLAllCollection::anonymousNamedGetter(const AtomicString& name, bool& ret
returnValue0 = NamedNodesCollection::create(namedItems);
}
-PassRefPtr<NodeList> HTMLAllCollection::tags(const String& name)
-{
- return ownerNode()->getElementsByTagName(name);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h
index d5f1106ac5d..458e3bc96ac 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h
@@ -32,17 +32,18 @@ namespace WebCore {
class HTMLAllCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLAllCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLAllCollection> create(ContainerNode&, CollectionType);
virtual ~HTMLAllCollection();
- Node* namedItemWithIndex(const AtomicString& name, unsigned index) const;
- void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Node>&);
- PassRefPtr<NodeList> tags(const String&);
+ Element* namedItemWithIndex(const AtomicString& name, unsigned index) const;
+ void namedGetter(const AtomicString& name, bool&, RefPtrWillBeRawPtr<NodeList>&, bool&, RefPtrWillBeRawPtr<Element>&);
private:
- HTMLAllCollection(Node*, CollectionType);
+ explicit HTMLAllCollection(ContainerNode&);
};
+DEFINE_TYPE_CASTS(HTMLAllCollection, LiveNodeListBase, collection, collection->type() == DocAll, collection.type() == DocAll);
+
} // namespace WebCore
#endif // HTMLAllCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl
index 3508f8bc731..d56b8b6dbf5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,17 +24,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// FIXME: This interface should inherit HTMLCollection.
[
Custom=LegacyCallAsFunction,
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
+ WillBeGarbageCollected,
] interface HTMLAllCollection {
readonly attribute unsigned long length;
- [ImplementedAs=item] getter Node (unsigned long index);
- [Custom] Node item([Default=Undefined] optional unsigned long index);
- [ImplementedAs=anonymousNamedGetter, NotEnumerable] getter (NodeList or Node)(DOMString name);
- [Custom] Node namedItem(DOMString name);
- // FIXME: This should return an HTMLAllCollection.
- [MeasureAs=DocumentAllTags] NodeList tags(DOMString name);
+ [ImplementedAs=item] getter Element (unsigned long index);
+ [Custom] Element item([Default=Undefined] optional unsigned long index);
+ // FIXME: This should return an (HTMLCollection or Element) union.
+ [ImplementedAs=namedGetter] getter (NodeList or Element) namedItem(DOMString name);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
index 8a0e9f372d8..7c955b5f483 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
@@ -28,8 +28,10 @@
#include "core/editing/FrameSelection.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -40,10 +42,7 @@
#include "core/loader/PingLoader.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderImage.h"
-#include "core/svg/graphics/SVGImage.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/network/DNS.h"
#include "platform/network/ResourceRequest.h"
@@ -70,11 +69,11 @@ void preconnectToURL(const KURL& url, blink::WebPreconnectMotivation motivation)
}
-class HTMLAnchorElement::PrefetchEventHandler {
+class HTMLAnchorElement::PrefetchEventHandler FINAL : public NoBaseWillBeGarbageCollected<HTMLAnchorElement::PrefetchEventHandler> {
public:
- static PassOwnPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElement)
+ static PassOwnPtrWillBeRawPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElement)
{
- return adoptPtr(new HTMLAnchorElement::PrefetchEventHandler(anchorElement));
+ return adoptPtrWillBeNoop(new HTMLAnchorElement::PrefetchEventHandler(anchorElement));
}
void reset();
@@ -83,6 +82,8 @@ public:
void didChangeHREF() { m_hadHREFChanged = true; }
bool hasIssuedPreconnect() const { return m_hasIssuedPreconnect; }
+ void trace(Visitor* visitor) { visitor->trace(m_anchorElement); }
+
private:
explicit PrefetchEventHandler(HTMLAnchorElement*);
@@ -96,7 +97,7 @@ private:
bool shouldPrefetch(const KURL&);
void prefetch(blink::WebPreconnectMotivation);
- HTMLAnchorElement* m_anchorElement;
+ RawPtrWillBeMember<HTMLAnchorElement> m_anchorElement;
double m_mouseOverTimestamp;
double m_mouseDownTimestamp;
double m_tapDownTimestamp;
@@ -109,27 +110,19 @@ using namespace HTMLNames;
HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , m_hasRootEditableElementForSelectionOnMouseDown(false)
- , m_wasShiftKeyDownOnMouseDown(false)
, m_linkRelations(0)
, m_cachedVisitedLinkHash(0)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document& document)
+PassRefPtrWillBeRawPtr<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));
+ return adoptRefWillBeNoop(new HTMLAnchorElement(aTag, document));
}
HTMLAnchorElement::~HTMLAnchorElement()
{
- clearRootEditableElementForSelectionOnMouseDown();
}
bool HTMLAnchorElement::supportsFocus() const
@@ -152,16 +145,13 @@ bool HTMLAnchorElement::isMouseFocusable() const
bool HTMLAnchorElement::isKeyboardFocusable() const
{
+ ASSERT(document().isActive());
+
if (isFocusable() && Element::supportsFocus())
return HTMLElement::isKeyboardFocusable();
- if (isLink()) {
- Page* page = document().page();
- if (!page)
- return false;
- if (!page->chrome().client().tabsToLinks())
- return false;
- }
+ if (isLink() && !document().frameHost()->chrome().client().tabsToLinks())
+ return false;
return HTMLElement::isKeyboardFocusable();
}
@@ -173,16 +163,16 @@ static void appendServerMapMousePosition(StringBuilder& url, Event* event)
ASSERT(event->target());
Node* target = event->target()->toNode();
ASSERT(target);
- if (!target->hasTagName(imgTag))
+ if (!isHTMLImageElement(*target))
return;
- HTMLImageElement* imageElement = toHTMLImageElement(event->target()->toNode());
- if (!imageElement || !imageElement->isServerMap())
+ HTMLImageElement& imageElement = toHTMLImageElement(*target);
+ if (!imageElement.isServerMap())
return;
- if (!imageElement->renderer() || !imageElement->renderer()->isRenderImage())
+ if (!imageElement.renderer() || !imageElement.renderer()->isRenderImage())
return;
- RenderImage* renderer = toRenderImage(imageElement->renderer());
+ RenderImage* renderer = toRenderImage(imageElement.renderer());
// FIXME: This should probably pass true for useTransforms.
FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(toMouseEvent(event)->pageX(), toMouseEvent(event)->pageY()));
@@ -197,7 +187,7 @@ static void appendServerMapMousePosition(StringBuilder& url, Event* event)
void HTMLAnchorElement::defaultEventHandler(Event* event)
{
if (isLink()) {
- if (focused() && isEnterKeyKeydownEvent(event) && treatLinkAsLiveForEventType(NonMouseEvent)) {
+ if (focused() && isEnterKeyKeydownEvent(event) && isLiveLink()) {
event->setDefaultHandled();
dispatchSimulatedClick(event);
return;
@@ -205,25 +195,11 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
prefetchEventHandler()->handleEvent(event);
- if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) {
+ if (isLinkClick(event) && isLiveLink()) {
handleClick(event);
prefetchEventHandler()->reset();
return;
}
-
- if (rendererIsEditable()) {
- // 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() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() != RightButton && document().frame()) {
- setRootEditableElementForSelectionOnMouseDown(document().frame()->selection().rootEditableElement());
- m_wasShiftKeyDownOnMouseDown = toMouseEvent(event)->shiftKey();
- } else if (event->type() == EventTypeNames::mouseover) {
- // These are cleared on mouseover and not mouseout because their values are needed for drag events,
- // but drag events happen after mouse out events.
- clearRootEditableElementForSelectionOnMouseDown();
- m_wasShiftKeyDownOnMouseDown = false;
- }
- }
}
HTMLElement::defaultEventHandler(event);
@@ -231,32 +207,8 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
void HTMLAnchorElement::setActive(bool down)
{
- if (rendererIsEditable()) {
- 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;
- }
-
- }
+ if (rendererIsEditable())
+ return;
ContainerNode::setActive(down);
}
@@ -303,9 +255,13 @@ bool HTMLAnchorElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLAnchorElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
bool HTMLAnchorElement::canStartSelection() const
{
- // FIXME: We probably want this same behavior in SVGAElement too
if (!isLink())
return HTMLElement::canStartSelection();
return rendererIsEditable();
@@ -349,7 +305,7 @@ String HTMLAnchorElement::input() const
void HTMLAnchorElement::setInput(const String& value)
{
- setHref(value);
+ setHref(AtomicString(value));
}
bool HTMLAnchorElement::hasRel(uint32_t relation) const
@@ -357,7 +313,7 @@ bool HTMLAnchorElement::hasRel(uint32_t relation) const
return m_linkRelations & relation;
}
-void HTMLAnchorElement::setRel(const String& value)
+void HTMLAnchorElement::setRel(const AtomicString& value)
{
m_linkRelations = 0;
SpaceSplitString newLinkRelations(value, true);
@@ -377,37 +333,34 @@ short HTMLAnchorElement::tabIndex() const
return Element::tabIndex();
}
-String HTMLAnchorElement::target() const
+AtomicString HTMLAnchorElement::target() const
{
return getAttribute(targetAttr);
}
-
-String HTMLAnchorElement::text()
-{
- return innerText();
-}
-
bool HTMLAnchorElement::isLiveLink() const
{
- return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown ? MouseEventWithShiftKey : MouseEventWithoutShiftKey);
+ return isLink() && !rendererIsEditable();
}
void HTMLAnchorElement::sendPings(const KURL& destinationURL)
{
- if (!hasAttribute(pingAttr) || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
+ const AtomicString& pingValue = getAttribute(pingAttr);
+ if (pingValue.isNull() || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
return;
- SpaceSplitString pingURLs(getAttribute(pingAttr), false);
+ UseCounter::count(document(), UseCounter::HTMLAnchorElementPingAttribute);
+
+ SpaceSplitString pingURLs(pingValue, false);
for (unsigned i = 0; i < pingURLs.size(); i++)
- PingLoader::sendPing(document().frame(), document().completeURL(pingURLs[i]), destinationURL);
+ PingLoader::sendLinkAuditPing(document().frame(), document().completeURL(pingURLs[i]), destinationURL);
}
void HTMLAnchorElement::handleClick(Event* event)
{
event->setDefaultHandled();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -427,10 +380,13 @@ void HTMLAnchorElement::handleClick(Event* event)
if (!hasRel(RelationNoReferrer)) {
String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), completedURL, document().outgoingReferrer());
if (!referrer.isEmpty())
- request.setHTTPReferrer(referrer);
+ request.setHTTPReferrer(Referrer(referrer, document().referrerPolicy()));
}
- frame->loader().client()->loadURLExternally(request, NavigationPolicyDownload, fastGetAttribute(downloadAttr));
+ bool isSameOrigin = completedURL.protocolIsData() || document().securityOrigin()->canRequest(completedURL);
+ const AtomicString& suggestedName = (isSameOrigin ? fastGetAttribute(downloadAttr) : nullAtom);
+
+ frame->loader().client()->loadURLExternally(request, NavigationPolicyDownload, suggestedName);
} else {
FrameLoadRequest frameRequest(&document(), request, target());
frameRequest.setTriggeringEvent(event);
@@ -440,43 +396,6 @@ void HTMLAnchorElement::handleClick(Event* event)
}
}
-HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event)
-{
- if (!event->isMouseEvent())
- return NonMouseEvent;
- return toMouseEvent(event)->shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey;
-}
-
-bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
-{
- if (!rendererIsEditable())
- 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 && rootEditableElementForSelectionOnMouseDown() != rootEditableElement());
-
- case EditableLinkOnlyLiveWithShiftKey:
- return eventType == MouseEventWithShiftKey;
- }
-
- ASSERT_NOT_REACHED();
- return false;
-}
-
bool isEnterKeyKeydownEvent(Event* event)
{
return event->type() == EventTypeNames::keydown && event->isKeyboardEvent() && toKeyboardEvent(event)->keyIdentifier() == "Enter";
@@ -492,40 +411,6 @@ bool HTMLAnchorElement::willRespondToMouseClickEvents()
return isLink() || HTMLElement::willRespondToMouseClickEvents();
}
-typedef HashMap<const HTMLAnchorElement*, RefPtr<Element> > RootEditableElementMap;
-
-static RootEditableElementMap& rootEditableElementMap()
-{
- DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
- return map;
-}
-
-Element* HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown() const
-{
- if (!m_hasRootEditableElementForSelectionOnMouseDown)
- return 0;
- return rootEditableElementMap().get(this);
-}
-
-void HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown()
-{
- if (!m_hasRootEditableElementForSelectionOnMouseDown)
- return;
- rootEditableElementMap().remove(this);
- m_hasRootEditableElementForSelectionOnMouseDown = false;
-}
-
-void HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown(Element* element)
-{
- if (!element) {
- clearRootEditableElementForSelectionOnMouseDown();
- return;
- }
-
- rootEditableElementMap().set(this, element);
- m_hasRootEditableElementForSelectionOnMouseDown = true;
-}
-
HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler()
{
if (!m_prefetchEventHandler)
@@ -667,7 +552,7 @@ bool HTMLAnchorElement::PrefetchEventHandler::shouldPrefetch(const KURL& url)
if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.url(), url))
return false;
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return false;
@@ -698,4 +583,10 @@ bool HTMLAnchorElement::isInteractiveContent() const
return isLink();
}
+void HTMLAnchorElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_prefetchEventHandler);
+ HTMLElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h
index bfb0d634729..769c6d2a0ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h
@@ -24,8 +24,9 @@
#ifndef HTMLAnchorElement_h
#define HTMLAnchorElement_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/DOMURLUtils.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLElement.h"
#include "platform/LinkHash.h"
@@ -56,8 +57,7 @@ enum {
class HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
public:
- static PassRefPtr<HTMLAnchorElement> create(Document&);
- static PassRefPtr<HTMLAnchorElement> create(const QualifiedName&, Document&);
+ static PassRefPtrWillBeRawPtr<HTMLAnchorElement> create(Document&);
virtual ~HTMLAnchorElement();
@@ -66,66 +66,52 @@ public:
const AtomicString& name() const;
- virtual KURL url() const OVERRIDE;
- virtual void setURL(const KURL&) OVERRIDE;
+ virtual KURL url() const OVERRIDE FINAL;
+ virtual void setURL(const KURL&) OVERRIDE FINAL;
- virtual String input() const OVERRIDE;
- virtual void setInput(const String&) OVERRIDE;
-
- String text();
+ virtual String input() const OVERRIDE FINAL;
+ virtual void setInput(const String&) OVERRIDE FINAL;
bool isLiveLink() const;
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE FINAL;
bool hasRel(uint32_t relation) const;
- void setRel(const String&);
+ void setRel(const AtomicString&);
LinkHash visitedLinkHash() const;
void invalidateCachedVisitedLinkHash() { m_cachedVisitedLinkHash = 0; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
HTMLAnchorElement(const QualifiedName&, Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE;
private:
- virtual bool supportsFocus() const;
- virtual bool isMouseFocusable() const;
+ virtual bool isMouseFocusable() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
virtual void setActive(bool = true) OVERRIDE FINAL;
- virtual void accessKeyAction(bool sendMouseEvents);
- virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool canStartSelection() const;
- virtual String target() const;
- virtual short tabIndex() const;
- virtual bool draggable() const;
- virtual bool isInteractiveContent() const OVERRIDE;
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE FINAL;
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE FINAL;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual bool canStartSelection() const OVERRIDE FINAL;
+ virtual short tabIndex() const OVERRIDE FINAL;
+ virtual bool draggable() const OVERRIDE FINAL;
+ virtual bool isInteractiveContent() const OVERRIDE FINAL;
void sendPings(const KURL& destinationURL);
-
+ AtomicString target() const;
void handleClick(Event*);
- enum EventType {
- MouseEventWithoutShiftKey,
- MouseEventWithShiftKey,
- NonMouseEvent,
- };
- static EventType eventType(Event*);
- bool treatLinkAsLiveForEventType(EventType) const;
-
- Element* rootEditableElementForSelectionOnMouseDown() const;
- void setRootEditableElementForSelectionOnMouseDown(Element*);
- void clearRootEditableElementForSelectionOnMouseDown();
-
class PrefetchEventHandler;
PrefetchEventHandler* prefetchEventHandler();
- bool m_hasRootEditableElementForSelectionOnMouseDown : 1;
- bool m_wasShiftKeyDownOnMouseDown : 1;
- uint32_t m_linkRelations : 30;
- OwnPtr<PrefetchEventHandler> m_prefetchEventHandler;
+ uint32_t m_linkRelations;
+ OwnPtrWillBeMember<PrefetchEventHandler> m_prefetchEventHandler;
mutable LinkHash m_cachedVisitedLinkHash;
};
@@ -141,23 +127,6 @@ inline LinkHash HTMLAnchorElement::visitedLinkHash() const
bool isEnterKeyKeydownEvent(Event*);
bool isLinkClick(Event*);
-inline bool isHTMLAnchorElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::aTag);
-}
-
-inline bool isHTMLAnchorElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::aTag);
-}
-
-inline bool isHTMLAnchorElement(const Element& element)
-{
- return element.hasTagName(HTMLNames::aTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLAnchorElement, hasTagName(HTMLNames::aTag));
-
} // namespace WebCore
#endif // HTMLAnchorElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl
index 525c307807f..63775c24b9b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl
@@ -31,8 +31,9 @@ interface HTMLAnchorElement : HTMLElement {
[Reflect] attribute DOMString target;
[Reflect] attribute DOMString type;
- readonly attribute DOMString text;
+ [ImplementedAs=textContent] attribute DOMString text;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
-// force rebuild: crbug.com/307023
HTMLAnchorElement implements URLUtils;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp
index 242e2ea2110..6dd43e9d911 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp
@@ -24,14 +24,14 @@
#include "config.h"
#include "core/html/HTMLAppletElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLParamElement.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/rendering/RenderApplet.h"
#include "platform/Widget.h"
#include "platform/weborigin/KURL.h"
@@ -49,9 +49,9 @@ HTMLAppletElement::HTMLAppletElement(Document& document, bool createdByParser)
m_serviceType = "application/x-java-applet";
}
-PassRefPtr<HTMLAppletElement> HTMLAppletElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLAppletElement> HTMLAppletElement::create(Document& document, bool createdByParser)
{
- RefPtr<HTMLAppletElement> element = adoptRef(new HTMLAppletElement(document, createdByParser));
+ RefPtrWillBeRawPtr<HTMLAppletElement> element = adoptRefWillBeNoop(new HTMLAppletElement(document, createdByParser));
element->ensureUserAgentShadowRoot();
return element.release();
}
@@ -77,6 +77,11 @@ bool HTMLAppletElement::isURLAttribute(const Attribute& attribute) const
|| HTMLPlugInElement::isURLAttribute(attribute);
}
+bool HTMLAppletElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == codebaseAttr || HTMLPlugInElement::hasLegalLinkAttribute(name);
+}
+
bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
{
if (!fastHasAttribute(codeAttr) && !hasAuthorShadowRoot())
@@ -114,14 +119,9 @@ void HTMLAppletElement::updateWidgetInternal()
RenderEmbeddedObject* renderer = renderEmbeddedObject();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
ASSERT(frame);
- LayoutUnit contentWidth = renderer->style()->width().isFixed() ? LayoutUnit(renderer->style()->width().value()) :
- renderer->width() - renderer->borderAndPaddingWidth();
- LayoutUnit contentHeight = renderer->style()->height().isFixed() ? LayoutUnit(renderer->style()->height().value()) :
- renderer->height() - renderer->borderAndPaddingHeight();
-
Vector<String> paramNames;
Vector<String> paramValues;
@@ -172,11 +172,7 @@ void HTMLAppletElement::updateWidgetInternal()
paramValues.append(mayScript.string());
}
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->hasTagName(paramTag))
- continue;
-
- HTMLParamElement* param = toHTMLParamElement(child);
+ for (HTMLParamElement* param = Traversal<HTMLParamElement>::firstChild(*this); param; param = Traversal<HTMLParamElement>::nextSibling(*param)) {
if (param->name().isEmpty())
continue;
@@ -186,7 +182,7 @@ void HTMLAppletElement::updateWidgetInternal()
RefPtr<Widget> widget;
if (frame->loader().allowPlugins(AboutToInstantiatePlugin))
- widget = frame->loader().client()->createJavaAppletWidget(roundedIntSize(LayoutSize(contentWidth, contentHeight)), this, baseURL, paramNames, paramValues);
+ widget = frame->loader().client()->createJavaAppletWidget(this, baseURL, paramNames, paramValues);
if (!widget) {
if (!renderer->showsUnavailablePluginIndicator())
@@ -194,7 +190,7 @@ void HTMLAppletElement::updateWidgetInternal()
return;
}
document().setContainsPlugins();
- renderer->setWidget(widget);
+ setWidget(widget);
}
bool HTMLAppletElement::canEmbedJava() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h
index 41c5193a81e..fbba123f567 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h
@@ -31,7 +31,7 @@ class KURL;
class HTMLAppletElement FINAL : public HTMLPlugInElement {
public:
- static PassRefPtr<HTMLAppletElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLAppletElement> create(Document&, bool createdByParser);
protected:
virtual RenderWidget* renderWidgetForJSBindings() const OVERRIDE;
@@ -41,6 +41,7 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
index 73cd5fb7ac0..1606791ed62 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
@@ -22,17 +22,16 @@
#include "config.h"
#include "core/html/HTMLAreaElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLMapElement.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderView.h"
+#include "platform/LengthFunctions.h"
#include "platform/graphics/Path.h"
#include "platform/transforms/AffineTransform.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -45,10 +44,7 @@ inline HTMLAreaElement::HTMLAreaElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLAreaElement> HTMLAreaElement::create(Document& document)
-{
- return adoptRef(new HTMLAreaElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLAreaElement)
void HTMLAreaElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
@@ -102,7 +98,7 @@ Path HTMLAreaElement::computePath(RenderObject* obj) const
// Default should default to the size of the containing object.
LayoutSize size = m_lastSize;
if (m_shape == Default)
- size = obj->absoluteOutlineBounds().size();
+ size = obj->absoluteClippedOverflowRect().size();
Path p = getRegion(size);
float zoomFactor = obj->style()->effectiveZoom();
@@ -141,35 +137,34 @@ Path HTMLAreaElement::getRegion(const LayoutSize& size) const
}
Path path;
- RenderView* renderView = document().renderView();
switch (shape) {
case Poly:
if (m_coords.size() >= 6) {
int numPoints = m_coords.size() / 2;
- path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width, renderView), minimumValueForLength(m_coords[1], height, renderView)));
+ path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width).toFloat(), minimumValueForLength(m_coords[1], height).toFloat()));
for (int i = 1; i < numPoints; ++i)
- path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width, renderView), minimumValueForLength(m_coords[i * 2 + 1], height, renderView)));
+ path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width).toFloat(), minimumValueForLength(m_coords[i * 2 + 1], height).toFloat()));
path.closeSubpath();
}
break;
case Circle:
if (m_coords.size() >= 3) {
Length radius = m_coords[2];
- int r = min(minimumValueForLength(radius, width, renderView), minimumValueForLength(radius, height, renderView));
- path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width, renderView) - r, minimumValueForLength(m_coords[1], height, renderView) - r, 2 * r, 2 * r));
+ float r = std::min(minimumValueForLength(radius, width).toFloat(), minimumValueForLength(radius, height).toFloat());
+ path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width).toFloat() - r, minimumValueForLength(m_coords[1], height).toFloat() - r, 2 * r, 2 * r));
}
break;
case Rect:
if (m_coords.size() >= 4) {
- int x0 = minimumValueForLength(m_coords[0], width, renderView);
- int y0 = minimumValueForLength(m_coords[1], height, renderView);
- int x1 = minimumValueForLength(m_coords[2], width, renderView);
- int y1 = minimumValueForLength(m_coords[3], height, renderView);
+ float x0 = minimumValueForLength(m_coords[0], width).toFloat();
+ float y0 = minimumValueForLength(m_coords[1], height).toFloat();
+ float x1 = minimumValueForLength(m_coords[2], width).toFloat();
+ float y1 = minimumValueForLength(m_coords[3], height).toFloat();
path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0));
}
break;
case Default:
- path.addRect(FloatRect(0, 0, width, height));
+ path.addRect(FloatRect(0, 0, width.toFloat(), height.toFloat()));
break;
case Unknown:
break;
@@ -181,13 +176,13 @@ Path HTMLAreaElement::getRegion(const LayoutSize& size) const
HTMLImageElement* HTMLAreaElement::imageElement() const
{
Element* mapElement = parentElement();
- while (mapElement && !mapElement->hasTagName(mapTag))
+ while (mapElement && !isHTMLMapElement(*mapElement))
mapElement = mapElement->parentElement();
if (!mapElement)
return 0;
- return toHTMLMapElement(mapElement)->imageElement();
+ return toHTMLMapElement(*mapElement).imageElement();
}
bool HTMLAreaElement::isKeyboardFocusable() const
@@ -239,16 +234,4 @@ void HTMLAreaElement::updateFocusAppearance(bool restorePreviousSelection)
imageElement->updateFocusAppearance(restorePreviousSelection);
}
-bool HTMLAreaElement::supportsFocus() const
-{
- // If the AREA element was a link, it should support focus.
- // FIXME: This means that an AREA that is not a link cannot be made focusable through contenteditable or tabindex. Is it correct?
- return isLink();
-}
-
-String HTMLAreaElement::target() const
-{
- return getAttribute(targetAttr);
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h
index 35f34387d52..b68450ef951 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h
@@ -34,7 +34,7 @@ class Path;
class HTMLAreaElement FINAL : public HTMLAnchorElement {
public:
- static PassRefPtr<HTMLAreaElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLAreaElement);
bool isDefault() const { return m_shape == Default; }
@@ -50,12 +50,10 @@ private:
explicit HTMLAreaElement(Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool supportsFocus() const;
- virtual String target() const;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool isMouseFocusable() const;
+ virtual bool isMouseFocusable() const OVERRIDE;
virtual bool rendererIsFocusable() const OVERRIDE;
- virtual void updateFocusAppearance(bool /*restorePreviousSelection*/);
+ virtual void updateFocusAppearance(bool /*restorePreviousSelection*/) OVERRIDE;
virtual void setFocus(bool) OVERRIDE;
enum Shape { Default, Poly, Rect, Circle, Unknown };
@@ -68,18 +66,6 @@ private:
Shape m_shape;
};
-inline bool isHTMLAreaElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::areaTag);
-}
-
-inline bool isHTMLAreaElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::areaTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLAreaElement, hasTagName(HTMLNames::areaTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl
index 1ad7233a1f9..471e5835a6f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl
@@ -27,5 +27,4 @@ interface HTMLAreaElement : HTMLElement {
[Reflect] attribute DOMString target;
};
-// force rebuild: crbug.com/307023
HTMLAreaElement implements URLUtils;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in b/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
index 4ae7745ae45..9494fad2a03 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
@@ -126,6 +126,7 @@ id
incremental
indeterminate
inputmode
+integrity
is
ismap
itemid
@@ -176,7 +177,6 @@ onautocomplete
onautocompleteerror
onbeforecopy
onbeforecut
-onbeforeload
onbeforepaste
onbeforeunload
onblur
@@ -211,6 +211,7 @@ oninvalid
onkeydown
onkeypress
onkeyup
+onlanguagechange
onload
onloadeddata
onloadedmetadata
@@ -252,6 +253,7 @@ onstorage
onsuspend
onsubmit
ontimeupdate
+ontoggle
ontouchstart
ontouchmove
ontouchend
@@ -282,7 +284,6 @@ pluginspage
pluginurl
ping
poster
-precision
preload
primary
profile
@@ -292,7 +293,6 @@ pseudo
readonly
rel
required
-reset-style-inheritance
results
rev
reversed
@@ -307,7 +307,6 @@ scoped
scrollamount
scrolldelay
scrolling
-seamless
select
selected
shape
@@ -316,8 +315,6 @@ sizes
sortable
sortdirection
span
-x-webkit-speech
-x-webkit-grammar
spellcheck
src
srcset
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp
index bdc0d9f3a04..07db2563fc3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp
@@ -26,29 +26,32 @@
#include "config.h"
#include "core/html/HTMLAudioElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLAudioElement::HTMLAudioElement(Document& document, bool createdByParser)
- : HTMLMediaElement(audioTag, document, createdByParser)
+HTMLAudioElement::HTMLAudioElement(Document& document)
+ : HTMLMediaElement(audioTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLAudioElement> HTMLAudioElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLAudioElement> HTMLAudioElement::create(Document& document)
{
- RefPtr<HTMLAudioElement> audioElement(adoptRef(new HTMLAudioElement(document, createdByParser)));
- audioElement->suspendIfNeeded();
- return audioElement.release();
+ RefPtrWillBeRawPtr<HTMLAudioElement> audio = adoptRefWillBeNoop(new HTMLAudioElement(document));
+ audio->ensureUserAgentShadowRoot();
+ audio->suspendIfNeeded();
+ return audio.release();
}
-PassRefPtr<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document& document, const AtomicString& src)
+PassRefPtrWillBeRawPtr<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document& document, const AtomicString& src)
{
- RefPtr<HTMLAudioElement> audio = adoptRef(new HTMLAudioElement(document, false));
- audio->setPreload("auto");
+ RefPtrWillBeRawPtr<HTMLAudioElement> audio = adoptRefWillBeNoop(new HTMLAudioElement(document));
+ audio->ensureUserAgentShadowRoot();
+ audio->setPreload(AtomicString("auto", AtomicString::ConstructFromLiteral));
if (!src.isNull())
audio->setSrc(src);
audio->suspendIfNeeded();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h
index c69a3057630..9969491d803 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h
@@ -35,13 +35,11 @@ class Document;
class HTMLAudioElement FINAL : public HTMLMediaElement {
public:
- static PassRefPtr<HTMLAudioElement> create(Document&, bool);
- static PassRefPtr<HTMLAudioElement> createForJSConstructor(Document&, const AtomicString& src);
+ static PassRefPtrWillBeRawPtr<HTMLAudioElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLAudioElement> createForJSConstructor(Document&, const AtomicString& src);
private:
- HTMLAudioElement(Document&, bool);
-
- virtual bool isVideo() const OVERRIDE { return false; }
+ HTMLAudioElement(Document&);
};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl
index ffb4769c23f..f1e3629d65e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl
@@ -25,6 +25,7 @@
[
RuntimeEnabled=Media,
- NamedConstructor=Audio([Default=NullString] optional DOMString src)
+ NamedConstructor=Audio(optional DOMString src = null),
+ ConstructorCallWith=Document
] interface HTMLAudioElement : HTMLMediaElement {
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h
index b5050a6ddee..52db54e9369 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h
@@ -27,13 +27,10 @@ namespace WebCore {
class HTMLBDIElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBDIElement> create(Document& document)
- {
- return adoptRef(new HTMLBDIElement(document));
- }
+ DECLARE_NODE_FACTORY(HTMLBDIElement);
private:
- explicit HTMLBDIElement(Document& document)
+ inline explicit HTMLBDIElement(Document& document)
: HTMLElement(HTMLNames::bdiTag, document)
{
// FIXME: Rename setSelfOrAncestorHasDirAutoAttribute to reflect the fact bdi also uses this flag.
@@ -41,6 +38,8 @@ private:
}
};
+DEFINE_NODE_FACTORY(HTMLBDIElement)
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp
index 19b3aa9dab9..b04ba6edef5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp
@@ -23,25 +23,22 @@
#include "config.h"
#include "core/html/HTMLBRElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/rendering/RenderBR.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLBRElement::HTMLBRElement(Document& document)
+inline HTMLBRElement::HTMLBRElement(Document& document)
: HTMLElement(brTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLBRElement> HTMLBRElement::create(Document& document)
-{
- return adoptRef(new HTMLBRElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLBRElement)
bool HTMLBRElement::isPresentationAttribute(const QualifiedName& name) const
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h
index 0188c71bd41..01af5657750 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h
@@ -30,9 +30,9 @@ namespace WebCore {
class HTMLBRElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBRElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLBRElement);
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
private:
explicit HTMLBRElement(Document&);
@@ -40,7 +40,7 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp
index 6ec6654c17f..de1075c7907 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp
@@ -23,11 +23,11 @@
#include "config.h"
#include "core/html/HTMLBaseElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/parser/TextResourceDecoder.h"
namespace WebCore {
@@ -39,10 +39,7 @@ inline HTMLBaseElement::HTMLBaseElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLBaseElement> HTMLBaseElement::create(Document& document)
-{
- return adoptRef(new HTMLBaseElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLBaseElement)
void HTMLBaseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
@@ -72,11 +69,6 @@ bool HTMLBaseElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
-String HTMLBaseElement::target() const
-{
- return fastGetAttribute(targetAttr);
-}
-
KURL HTMLBaseElement::href() const
{
// This does not use the getURLAttribute function because that will resolve relative to the document's base URL;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h
index 39c8bfeadff..cefdc19f3f0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLBaseElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBaseElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLBaseElement);
KURL href() const;
void setHref(const AtomicString&);
@@ -37,7 +37,6 @@ public:
private:
explicit HTMLBaseElement(Document&);
- virtual String target() const;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
index 44a1572fec5..624dec6126e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
@@ -24,33 +24,30 @@
#include "config.h"
#include "core/html/HTMLBodyElement.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSImageValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Attribute.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
+#include "core/rendering/RenderBox.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLBodyElement::HTMLBodyElement(Document& document)
+inline HTMLBodyElement::HTMLBodyElement(Document& document)
: HTMLElement(bodyTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(Document& document)
-{
- return adoptRef(new HTMLBodyElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLBodyElement)
HTMLBodyElement::~HTMLBodyElement()
{
@@ -68,8 +65,9 @@ void HTMLBodyElement::collectStyleForPresentationAttribute(const QualifiedName&
if (name == backgroundAttr) {
String url = stripLeadingAndTrailingHTMLSpaces(value);
if (!url.isEmpty()) {
- RefPtr<CSSImageValue> imageValue = CSSImageValue::create(document().completeURL(url).string());
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
imageValue->setInitiator(localName());
+ imageValue->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
}
} else if (name == marginwidthAttr || name == leftmarginAttr) {
@@ -101,7 +99,7 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
document().textLinkColors().resetActiveLinkColor();
} else {
RGBA32 color;
- if (CSSParser::parseColor(color, value, !document().inQuirksMode())) {
+ if (BisonCSSParser::parseColor(color, value, !document().inQuirksMode())) {
if (name == linkAttr)
document().textLinkColors().setLinkColor(color);
else if (name == vlinkAttr)
@@ -111,45 +109,45 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
}
}
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
} else if (name == onloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onbeforeunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpagehideAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpageshowAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpopstateAttr)
- document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onblurAttr)
- document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onerrorAttr)
- document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value));
-#if ENABLE(ORIENTATION_EVENTS)
- else if (name == onorientationchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value));
-#endif
+ document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (RuntimeEnabledFeatures::orientationEventEnabled() && name == onorientationchangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onhashchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onmessageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onresizeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onscrollAttr)
- document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onselectionchangeAttr)
- document().setAttributeEventListener(EventTypeNames::selectionchange, createAttributeEventListener(document().frame(), name, value));
+ document().setAttributeEventListener(EventTypeNames::selectionchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onstorageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == ononlineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onofflineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (name == onlanguagechangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::languagechange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else
HTMLElement::parseAttribute(name, value);
}
@@ -157,22 +155,24 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
Node::InsertionNotificationRequest HTMLBodyElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument()) {
- // FIXME: It's surprising this is web compatible since it means a marginwidth
- // and marginheight attribute can magically appear on the <body> of all documents
- // embedded through <iframe> or <frame>.
- Element* ownerElement = document().ownerElement();
- if (ownerElement && ownerElement->isFrameElementBase()) {
- HTMLFrameElementBase* ownerFrameElement = toHTMLFrameElementBase(ownerElement);
- int marginWidth = ownerFrameElement->marginWidth();
- if (marginWidth != -1)
- setIntegralAttribute(marginwidthAttr, marginWidth);
- int marginHeight = ownerFrameElement->marginHeight();
- if (marginHeight != -1)
- setIntegralAttribute(marginheightAttr, marginHeight);
- }
- }
- return InsertionDone;
+ return InsertionShouldCallDidNotifySubtreeInsertions;
+}
+
+void HTMLBodyElement::didNotifySubtreeInsertionsToDocument()
+{
+ // FIXME: It's surprising this is web compatible since it means a
+ // marginwidth and marginheight attribute can magically appear on the <body>
+ // of all documents embedded through <iframe> or <frame>.
+ Element* ownerElement = document().ownerElement();
+ if (!isHTMLFrameElementBase(ownerElement))
+ return;
+ HTMLFrameElementBase& ownerFrameElement = toHTMLFrameElementBase(*ownerElement);
+ int marginWidth = ownerFrameElement.marginWidth();
+ int marginHeight = ownerFrameElement.marginHeight();
+ if (marginWidth != -1)
+ setIntegralAttribute(marginwidthAttr, marginWidth);
+ if (marginHeight != -1)
+ setIntegralAttribute(marginheightAttr, marginHeight);
}
bool HTMLBodyElement::isURLAttribute(const Attribute& attribute) const
@@ -180,6 +180,16 @@ bool HTMLBodyElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLBodyElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == backgroundAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLBodyElement::subResourceAttributeName() const
+{
+ return backgroundAttr;
+}
+
bool HTMLBodyElement::supportsFocus() const
{
// This override is needed because the inherited method bails if the parent is editable.
@@ -189,7 +199,7 @@ bool HTMLBodyElement::supportsFocus() const
static int adjustForZoom(int value, Document* document)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
float zoomFactor = frame->pageZoomFactor();
if (zoomFactor == 1)
return value;
@@ -199,17 +209,28 @@ static int adjustForZoom(int value, Document* document)
return static_cast<int>(value / zoomFactor);
}
-// FIXME: There are cases where body.scrollLeft is allowed to return
-// non-zero values in both quirks and strict mode. It happens when
-// <body> has an overflow that is not the Frame overflow.
-// http://dev.w3.org/csswg/cssom-view/#dom-element-scrollleft
-// http://code.google.com/p/chromium/issues/detail?id=312435
+// Blink, Gecko and Presto's quirks mode implementations of overflow set to the
+// body element differ from IE's: the formers can create a scrollable area for the
+// body element that is not the same as the root elements's one. On IE's quirks mode
+// though, as body is the root element, body's and the root element's scrollable areas,
+// if any, are the same.
+// In order words, a <body> will only have an overflow clip (that differs from
+// documentElement's) if both html and body nodes have its overflow set to either hidden,
+// auto or scroll.
+// That said, Blink's {set}scroll{Top,Left} behaviors match Gecko's: even if there is a non-overflown
+// scrollable area, scrolling should not get propagated to the viewport in neither strict
+// or quirks modes.
int HTMLBodyElement::scrollLeft()
{
Document& document = this->document();
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return 0;
+ if (render->hasOverflowClip())
+ return adjustForAbsoluteZoom(render->scrollLeft(), render);
if (!document.inQuirksMode())
return 0;
}
@@ -224,11 +245,19 @@ void HTMLBodyElement::setScrollLeft(int scrollLeft)
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return;
+ if (render->hasOverflowClip()) {
+ // FIXME: Investigate how are other browsers casting to int (rounding, ceiling, ...).
+ render->setScrollLeft(static_cast<int>(scrollLeft * render->style()->effectiveZoom()));
+ return;
+ }
if (!document.inQuirksMode())
return;
}
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return;
FrameView* view = frame->view();
@@ -243,6 +272,11 @@ int HTMLBodyElement::scrollTop()
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return 0;
+ if (render->hasOverflowClip())
+ return adjustForAbsoluteZoom(render->scrollTop(), render);
if (!document.inQuirksMode())
return 0;
}
@@ -257,11 +291,19 @@ void HTMLBodyElement::setScrollTop(int scrollTop)
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return;
+ if (render->hasOverflowClip()) {
+ // FIXME: Investigate how are other browsers casting to int (rounding, ceiling, ...).
+ render->setScrollTop(static_cast<int>(scrollTop * render->style()->effectiveZoom()));
+ return;
+ }
if (!document.inQuirksMode())
return;
}
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return;
FrameView* view = frame->view();
@@ -288,11 +330,4 @@ int HTMLBodyElement::scrollWidth()
return view ? adjustForZoom(view->contentsWidth(), &document) : 0;
}
-void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h
index d7a5c45da0a..7dd1f21c09b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h
@@ -24,6 +24,7 @@
#ifndef HTMLBodyElement_h
#define HTMLBodyElement_h
+#include "core/dom/Document.h"
#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -32,18 +33,16 @@ class Document;
class HTMLBodyElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBodyElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLBodyElement);
virtual ~HTMLBodyElement();
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(resize);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll);
-
-#if ENABLE(ORIENTATION_EVENTS)
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
-#endif
private:
explicit HTMLBodyElement(Document&);
@@ -53,25 +52,24 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
- virtual bool supportsFocus() const;
+ virtual bool supportsFocus() const OVERRIDE;
- virtual int scrollLeft();
- virtual void setScrollLeft(int scrollLeft);
+ virtual int scrollLeft() OVERRIDE;
+ virtual void setScrollLeft(int) OVERRIDE;
- virtual int scrollTop();
- virtual void setScrollTop(int scrollTop);
+ virtual int scrollTop() OVERRIDE;
+ virtual void setScrollTop(int) OVERRIDE;
- virtual int scrollHeight();
- virtual int scrollWidth();
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual int scrollHeight() OVERRIDE;
+ virtual int scrollWidth() OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLBodyElement, hasTagName(HTMLNames::bodyTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
index 139b34a52a1..6f454c6aeef 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
@@ -26,13 +26,14 @@ interface HTMLBodyElement : HTMLElement {
[Reflect, TreatNullAs=NullString] attribute DOMString text;
[Reflect, TreatNullAs=NullString] attribute DOMString vLink;
- [Conditional=ORIENTATION_EVENTS] attribute EventHandler onorientationchange;
+ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
// Overrides of GlobalEventHandler attributes
attribute EventHandler onblur;
attribute EventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onload;
+ attribute EventHandler onresize;
attribute EventHandler onscroll;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
index 4b3c235fdab..55f7defa1a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
@@ -26,10 +26,9 @@
#include "config.h"
#include "core/html/HTMLButtonElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLFormElement.h"
#include "core/rendering/RenderButton.h"
@@ -47,9 +46,9 @@ inline HTMLButtonElement::HTMLButtonElement(Document& document, HTMLFormElement*
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLButtonElement> HTMLButtonElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLButtonElement> HTMLButtonElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLButtonElement(document, form));
+ return adoptRefWillBeNoop(new HTMLButtonElement(document, form));
}
void HTMLButtonElement::setType(const AtomicString& type)
@@ -209,4 +208,9 @@ bool HTMLButtonElement::isInteractiveContent() const
return true;
}
+bool HTMLButtonElement::supportsAutofocus() const
+{
+ return true;
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h
index 5032c386975..110e411f480 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLButtonElement FINAL : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLButtonElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLButtonElement> create(Document&, HTMLFormElement*);
void setType(const AtomicString&);
@@ -43,34 +43,35 @@ private:
enum Type { SUBMIT, RESET, BUTTON };
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
// HTMLFormControlElement always creates one, but buttons don't need it.
virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return false; }
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual bool appendFormData(FormDataList&, bool);
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool supportLabels() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool canBeSuccessfulSubmitButton() const OVERRIDE;
- virtual bool isActivatedSubmit() const;
- virtual void setActivatedSubmit(bool flag);
+ virtual bool isActivatedSubmit() const OVERRIDE;
+ virtual void setActivatedSubmit(bool flag) OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool canStartSelection() const { return false; }
+ virtual bool canStartSelection() const OVERRIDE { return false; }
- virtual bool isOptionalFormControl() const { return true; }
- virtual bool recalcWillValidate() const;
+ virtual bool isOptionalFormControl() const OVERRIDE { return true; }
+ virtual bool recalcWillValidate() const OVERRIDE;
Type m_type;
bool m_isActivatedSubmit;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl
index aa402325ce4..d92dcd166a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl
@@ -22,7 +22,7 @@ interface HTMLButtonElement : HTMLElement {
[Reflect] attribute boolean autofocus;
[Reflect] attribute boolean disabled;
[ImplementedAs=formOwner] readonly attribute HTMLFormElement form;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString formAction;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString formAction;
attribute DOMString formEnctype;
attribute DOMString formMethod;
[Reflect] attribute boolean formNoValidate;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index ba778484dbc..4d6c77edb14 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -28,29 +28,32 @@
#include "config.h"
#include "core/html/HTMLCanvasElement.h"
-#include <math.h>
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptController.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/ImageData.h"
#include "core/html/canvas/Canvas2DContextAttributes.h"
#include "core/html/canvas/CanvasRenderingContext2D.h"
#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/html/canvas/WebGLContextEvent.h"
#include "core/html/canvas/WebGLRenderingContext.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderHTMLCanvas.h"
#include "platform/MIMETypeRegistry.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/Canvas2DImageBufferSurface.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/UnacceleratedImageBufferSurface.h"
#include "platform/graphics/gpu/WebGLImageBufferSurface.h"
+#include "platform/transforms/AffineTransform.h"
#include "public/platform/Platform.h"
+#include <math.h>
+#include <v8.h>
namespace WebCore {
@@ -68,10 +71,12 @@ static const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pix
//In Skia, we will also limit width/height to 32767.
static const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels.
-HTMLCanvasElement::HTMLCanvasElement(Document& document)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver);
+
+inline HTMLCanvasElement::HTMLCanvasElement(Document& document)
: HTMLElement(canvasTag, document)
+ , DocumentVisibilityObserver(document)
, m_size(DefaultWidth, DefaultHeight)
- , m_rendererIsCanvas(false)
, m_ignoreReset(false)
, m_accelerationDisabled(false)
, m_externallyAllocatedMemory(0)
@@ -82,19 +87,19 @@ HTMLCanvasElement::HTMLCanvasElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
-{
- return adoptRef(new HTMLCanvasElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLCanvasElement)
HTMLCanvasElement::~HTMLCanvasElement()
{
- setExternallyAllocatedMemory(0);
- HashSet<CanvasObserver*>::iterator end = m_observers.end();
- for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory);
+#if !ENABLE(OILPAN)
+ HashSet<RawPtr<CanvasObserver> >::iterator end = m_observers.end();
+ for (HashSet<RawPtr<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasDestroyed(this);
-
- m_context.clear(); // Ensure this goes away before the ImageBuffer.
+ // Ensure these go away before the ImageBuffer.
+ m_contextStateSaver.clear();
+ m_context.clear();
+#endif
}
void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -106,13 +111,9 @@ void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt
RenderObject* HTMLCanvasElement::createRenderer(RenderStyle* style)
{
- Frame* frame = document().frame();
- if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript)) {
- m_rendererIsCanvas = true;
+ LocalFrame* frame = document().frame();
+ if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
return new RenderHTMLCanvas(this);
- }
-
- m_rendererIsCanvas = false;
return HTMLElement::createRenderer(style);
}
@@ -166,38 +167,33 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
if (!m_context) {
blink::Platform::current()->histogramEnumeration("Canvas.ContextType", Context2d, ContextTypeCount);
m_context = CanvasRenderingContext2D::create(this, static_cast<Canvas2DContextAttributes*>(attrs), document().inQuirksMode());
- if (m_context)
- scheduleLayerUpdate();
+ setNeedsCompositingUpdate();
}
return m_context.get();
}
- Settings* settings = document().settings();
- if (settings && settings->webGLEnabled()) {
- // Accept the legacy "webkit-3d" name as well as the provisional "experimental-webgl" name.
- // Now that WebGL is ratified, we will also accept "webgl" as the context name in Chrome.
- ContextType contextType;
- bool is3dContext = true;
- if (type == "webkit-3d")
- contextType = ContextWebkit3d;
- else if (type == "experimental-webgl")
- contextType = ContextExperimentalWebgl;
- else if (type == "webgl")
- contextType = ContextWebgl;
- else
- is3dContext = false;
-
- if (is3dContext) {
- if (m_context && !m_context->is3d())
- return 0;
- if (!m_context) {
- blink::Platform::current()->histogramEnumeration("Canvas.ContextType", contextType, ContextTypeCount);
- m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
- if (m_context)
- scheduleLayerUpdate();
- }
- return m_context.get();
+ // Accept the the provisional "experimental-webgl" or official "webgl" context ID.
+ ContextType contextType;
+ bool is3dContext = true;
+ if (type == "experimental-webgl")
+ contextType = ContextExperimentalWebgl;
+ else if (type == "webgl")
+ contextType = ContextWebgl;
+ else
+ is3dContext = false;
+
+ if (is3dContext) {
+ if (m_context && !m_context->is3d()) {
+ dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Canvas has an existing, non-WebGL context"));
+ return 0;
}
+ if (!m_context) {
+ blink::Platform::current()->histogramEnumeration("Canvas.ContextType", contextType, ContextTypeCount);
+ m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
+ setNeedsCompositingUpdate();
+ updateExternallyAllocatedMemory();
+ }
+ return m_context.get();
}
return 0;
}
@@ -214,7 +210,7 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
return;
m_dirtyRect.unite(r);
- ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
+ ro->invalidatePaintRectangle(enclosingIntRect(m_dirtyRect));
}
notifyObserversCanvasChanged(rect);
@@ -222,8 +218,8 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
void HTMLCanvasElement::notifyObserversCanvasChanged(const FloatRect& rect)
{
- HashSet<CanvasObserver*>::iterator end = m_observers.end();
- for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator end = m_observers.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasChanged(this, rect);
}
@@ -269,19 +265,19 @@ void HTMLCanvasElement::reset()
toWebGLRenderingContext(m_context.get())->reshape(width(), height());
if (RenderObject* renderer = this->renderer()) {
- if (m_rendererIsCanvas) {
+ if (renderer->isCanvas()) {
if (oldSize != size()) {
toRenderHTMLCanvas(renderer)->canvasSizeChanged();
if (renderBox() && renderBox()->hasAcceleratedCompositing())
renderBox()->contentChanged(CanvasChanged);
}
if (hadImageBuffer)
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
}
}
- HashSet<CanvasObserver*>::iterator end = m_observers.end();
- for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator end = m_observers.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasResized(this);
}
@@ -299,7 +295,7 @@ bool HTMLCanvasElement::paintsIntoCanvasBuffer() const
}
-void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, bool useLowQualityScale)
+void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r)
{
// Clear the dirty rect
m_dirtyRect = FloatRect();
@@ -318,10 +314,14 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, boo
if (imageBuffer) {
CompositeOperator compositeOperator = !m_context || m_context->hasAlpha() ? CompositeSourceOver : CompositeCopy;
if (m_presentedImage)
- context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r), compositeOperator, DoNotRespectImageOrientation, useLowQualityScale);
+ context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r), compositeOperator, DoNotRespectImageOrientation);
else
- context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), compositeOperator, blink::WebBlendModeNormal, useLowQualityScale);
+ context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), 0, compositeOperator);
}
+ } else {
+ // When alpha is false, we should draw to opaque black.
+ if (m_context && !m_context->hasAlpha())
+ context->fillRect(FloatRect(r), Color(0, 0, 0));
}
if (is3D())
@@ -338,22 +338,28 @@ void HTMLCanvasElement::makePresentationCopy()
if (!m_presentedImage) {
// The buffer contains the last presented data, so save a copy of it.
m_presentedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
+ updateExternallyAllocatedMemory();
}
}
void HTMLCanvasElement::clearPresentationCopy()
{
m_presentedImage.clear();
+ updateExternallyAllocatedMemory();
}
void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
{
m_size = size;
m_didFailToCreateImageBuffer = false;
- m_contextStateSaver.clear();
- m_imageBuffer.clear();
- setExternallyAllocatedMemory(0);
+ discardImageBuffer();
clearCopiedImage();
+ if (m_context && m_context->is2d()) {
+ CanvasRenderingContext2D* context2d = toCanvasRenderingContext2D(m_context.get());
+ if (context2d->isContextLost()) {
+ context2d->restoreContext();
+ }
+ }
}
String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
@@ -367,34 +373,47 @@ String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
return lowercaseMimeType;
}
-String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionState& exceptionState)
+const AtomicString HTMLCanvasElement::imageSourceURL() const
{
- if (!m_originClean) {
- exceptionState.throwSecurityError("Tainted canvases may not be exported.");
- return String();
- }
+ return AtomicString(toDataURLInternal("image/png", 0, true));
+}
+String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double* quality, bool isSaving) const
+{
if (m_size.isEmpty() || !buffer())
return String("data:,");
String encodingMimeType = toEncodingMimeType(mimeType);
// Try to get ImageData first, as that may avoid lossy conversions.
- RefPtr<ImageData> imageData = getImageData();
+ RefPtrWillBeRawPtr<ImageData> imageData = getImageData();
if (imageData)
return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->data()), encodingMimeType, quality);
- if (m_context)
+ if (m_context && m_context->is3d()) {
+ toWebGLRenderingContext(m_context.get())->setSavingImage(isSaving);
m_context->paintRenderingResultsToCanvas();
+ toWebGLRenderingContext(m_context.get())->setSavingImage(false);
+ }
return buffer()->toDataURL(encodingMimeType, quality);
}
-PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
+String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionState& exceptionState) const
+{
+ if (!m_originClean) {
+ exceptionState.throwSecurityError("Tainted canvases may not be exported.");
+ return String();
+ }
+
+ return toDataURLInternal(mimeType, quality);
+}
+
+PassRefPtrWillBeRawPtr<ImageData> HTMLCanvasElement::getImageData() const
{
if (!m_context || !m_context->is3d())
- return 0;
+ return nullptr;
return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImageData();
}
@@ -446,7 +465,15 @@ PassOwnPtr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(const
void HTMLCanvasElement::createImageBuffer()
{
+ createImageBufferInternal();
+ if (m_didFailToCreateImageBuffer && m_context && m_context->is2d())
+ toCanvasRenderingContext2D(m_context.get())->loseContext();
+}
+
+void HTMLCanvasElement::createImageBufferInternal()
+{
ASSERT(!m_imageBuffer);
+ ASSERT(!m_contextStateSaver);
m_didFailToCreateImageBuffer = true;
m_didClearImageBuffer = true;
@@ -465,20 +492,23 @@ void HTMLCanvasElement::createImageBuffer()
OwnPtr<ImageBufferSurface> surface = createImageBufferSurface(deviceSize, &msaaSampleCount);
if (!surface->isValid())
return;
+
m_imageBuffer = ImageBuffer::create(surface.release());
+ m_imageBuffer->setClient(this);
m_didFailToCreateImageBuffer = false;
- setExternallyAllocatedMemory(4 * width() * height());
+ updateExternallyAllocatedMemory();
if (is3D()) {
// Early out for WebGL canvases
- m_contextStateSaver.clear();
return;
}
+ m_imageBuffer->setClient(this);
m_imageBuffer->context()->setShouldClampToSourceRect(false);
- m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality);
+ m_imageBuffer->context()->disableAntialiasingOptimizationForHairlineImages();
+ m_imageBuffer->context()->setImageInterpolationQuality(CanvasDefaultInterpolationQuality);
// Enabling MSAA overrides a request to disable antialiasing. This is true regardless of whether the
// rendering mode is accelerated or not. For consistency, we don't want to apply AA in accelerated
// canvases but not in unaccelerated canvases.
@@ -488,15 +518,51 @@ void HTMLCanvasElement::createImageBuffer()
// See CanvasRenderingContext2D::State::State() for more information.
m_imageBuffer->context()->setMiterLimit(10);
m_imageBuffer->context()->setStrokeThickness(1);
+#if ASSERT_ENABLED
+ m_imageBuffer->context()->disableDestructionChecks(); // 2D canvas is allowed to leave context in an unfinalized state.
+#endif
m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context()));
- // Recalculate compositing requirements if acceleration state changed.
if (m_context)
- scheduleLayerUpdate();
+ setNeedsCompositingUpdate();
+}
+
+void HTMLCanvasElement::notifySurfaceInvalid()
+{
+ if (m_context && m_context->is2d()) {
+ CanvasRenderingContext2D* context2d = toCanvasRenderingContext2D(m_context.get());
+ context2d->loseContext();
+ }
+}
+
+void HTMLCanvasElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_observers);
+ visitor->trace(m_context);
+ DocumentVisibilityObserver::trace(visitor);
+ HTMLElement::trace(visitor);
}
-void HTMLCanvasElement::setExternallyAllocatedMemory(intptr_t externallyAllocatedMemory)
+void HTMLCanvasElement::updateExternallyAllocatedMemory() const
{
+ int bufferCount = 0;
+ if (m_imageBuffer)
+ bufferCount++;
+ if (is3D())
+ bufferCount += 2;
+ if (m_copiedImage)
+ bufferCount++;
+ if (m_presentedImage)
+ bufferCount++;
+
+ Checked<intptr_t, RecordOverflow> checkedExternallyAllocatedMemory = 4 * bufferCount;
+ checkedExternallyAllocatedMemory *= width();
+ checkedExternallyAllocatedMemory *= height();
+ intptr_t externallyAllocatedMemory;
+ if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == CheckedState::DidOverflow)
+ externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
+
+ // Subtracting two intptr_t that are known to be positive will never underflow.
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyAllocatedMemory - m_externallyAllocatedMemory);
m_externallyAllocatedMemory = externallyAllocatedMemory;
}
@@ -508,10 +574,8 @@ GraphicsContext* HTMLCanvasElement::drawingContext() const
GraphicsContext* HTMLCanvasElement::existingDrawingContext() const
{
- if (m_didFailToCreateImageBuffer) {
- ASSERT(!hasImageBuffer());
+ if (!hasImageBuffer())
return 0;
- }
return drawingContext();
}
@@ -527,7 +591,7 @@ void HTMLCanvasElement::ensureUnacceleratedImageBuffer()
{
if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCreateImageBuffer)
return;
- m_imageBuffer.clear();
+ discardImageBuffer();
OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque;
m_imageBuffer = ImageBuffer::create(size(), opacityMode);
m_didFailToCreateImageBuffer = !m_imageBuffer;
@@ -539,6 +603,7 @@ Image* HTMLCanvasElement::copiedImage() const
if (m_context)
m_context->paintRenderingResultsToCanvas();
m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
+ updateExternallyAllocatedMemory();
}
return m_copiedImage.get();
}
@@ -558,10 +623,23 @@ void HTMLCanvasElement::clearImageBuffer()
}
}
+void HTMLCanvasElement::discardImageBuffer()
+{
+ m_contextStateSaver.clear(); // uses context owned by m_imageBuffer
+ m_imageBuffer.clear();
+ updateExternallyAllocatedMemory();
+}
+
+bool HTMLCanvasElement::hasValidImageBuffer() const
+{
+ return m_imageBuffer && m_imageBuffer->isSurfaceValid();
+}
+
void HTMLCanvasElement::clearCopiedImage()
{
m_copiedImage.clear();
m_didClearImageBuffer = false;
+ updateExternallyAllocatedMemory();
}
AffineTransform HTMLCanvasElement::baseTransform() const
@@ -570,4 +648,62 @@ AffineTransform HTMLCanvasElement::baseTransform() const
return m_imageBuffer->baseTransform();
}
+void HTMLCanvasElement::didChangeVisibilityState(PageVisibilityState visibility)
+{
+ if (hasImageBuffer()) {
+ bool hidden = visibility != PageVisibilityStateVisible;
+ if (hidden) {
+ clearCopiedImage();
+ if (is3D()) {
+ discardImageBuffer();
+ }
+ }
+ if (hasImageBuffer()) {
+ m_imageBuffer->setIsHidden(hidden);
+ }
+ }
+}
+
+void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument)
+{
+ setObservedDocument(document());
+ HTMLElement::didMoveToNewDocument(oldDocument);
+}
+
+PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+ if (!width() || !height()) {
+ *status = ZeroSizeCanvasSourceImageStatus;
+ return nullptr;
+ }
+
+ if (!buffer()) {
+ *status = InvalidSourceImageStatus;
+ return nullptr;
+ }
+
+ if (mode == CopySourceImageIfVolatile) {
+ *status = NormalSourceImageStatus;
+ return copiedImage();
+ }
+
+ if (m_context && m_context->is3d()) {
+ m_context->paintRenderingResultsToCanvas();
+ *status = ExternalSourceImageStatus;
+ } else {
+ *status = NormalSourceImageStatus;
+ }
+ return m_imageBuffer->copyImage(DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const
+{
+ return !originClean();
+}
+
+FloatSize HTMLCanvasElement::sourceSize() const
+{
+ return FloatSize(width(), height());
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
index 8db8a6d70a0..175bd4e11d9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -28,15 +28,22 @@
#ifndef HTMLCanvasElement_h
#define HTMLCanvasElement_h
+#include "core/dom/Document.h"
#include "core/html/HTMLElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntSize.h"
+#include "platform/graphics/Canvas2DLayerBridge.h"
+#include "platform/graphics/GraphicsTypes.h"
+#include "platform/graphics/ImageBufferClient.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
-#define DefaultInterpolationQuality InterpolationMedium
+#define CanvasDefaultInterpolationQuality InterpolationLow
namespace WebCore {
+class AffineTransform;
class CanvasContextAttributes;
class CanvasRenderingContext;
class GraphicsContext;
@@ -48,18 +55,22 @@ class ImageBuffer;
class ImageBufferSurface;
class IntSize;
-class CanvasObserver {
+class CanvasObserver : public WillBeGarbageCollectedMixin {
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver);
public:
- virtual ~CanvasObserver() { }
-
virtual void canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect) = 0;
virtual void canvasResized(HTMLCanvasElement*) = 0;
+#if !ENABLE(OILPAN)
virtual void canvasDestroyed(HTMLCanvasElement*) = 0;
+#endif
+
+ virtual void trace(Visitor*) { }
};
-class HTMLCanvasElement FINAL : public HTMLElement {
+class HTMLCanvasElement FINAL : public HTMLElement, public DocumentVisibilityObserver, public CanvasImageSource, public ImageBufferClient {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLCanvasElement);
public:
- static PassRefPtr<HTMLCanvasElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLCanvasElement);
virtual ~HTMLCanvasElement();
void addObserver(CanvasObserver*);
@@ -90,14 +101,14 @@ public:
CanvasRenderingContext* getContext(const String&, CanvasContextAttributes* attributes = 0);
static String toEncodingMimeType(const String& mimeType);
- String toDataURL(const String& mimeType, const double* quality, ExceptionState&);
- String toDataURL(const String& mimeType, ExceptionState& exceptionState) { return toDataURL(mimeType, 0, exceptionState); }
+ String toDataURL(const String& mimeType, const double* quality, ExceptionState&) const;
+ String toDataURL(const String& mimeType, ExceptionState& exceptionState) const { return toDataURL(mimeType, 0, exceptionState); }
// Used for rendering
void didDraw(const FloatRect&);
void notifyObserversCanvasChanged(const FloatRect&);
- void paint(GraphicsContext*, const LayoutRect&, bool useLowQualityScale = false);
+ void paint(GraphicsContext*, const LayoutRect&);
GraphicsContext* drawingContext() const;
GraphicsContext* existingDrawingContext() const;
@@ -108,56 +119,77 @@ public:
ImageBuffer* buffer() const;
Image* copiedImage() const;
void clearCopiedImage();
- PassRefPtr<ImageData> getImageData();
+ PassRefPtrWillBeRawPtr<ImageData> getImageData() const;
void makePresentationCopy();
void clearPresentationCopy();
SecurityOrigin* securityOrigin() const;
- void setOriginTainted() { m_originClean = false; }
bool originClean() const { return m_originClean; }
+ void setOriginTainted() { m_originClean = false; }
AffineTransform baseTransform() const;
bool is3D() const;
- bool hasImageBuffer() const { return m_imageBuffer.get(); }
+ bool hasImageBuffer() const { return m_imageBuffer; }
+ bool hasValidImageBuffer() const;
+ void discardImageBuffer();
bool shouldAccelerate(const IntSize&) const;
- InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+ virtual const AtomicString imageSourceURL() const OVERRIDE;
+
+ virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+
+ // DocumentVisibilityObserver implementation
+ virtual void didChangeVisibilityState(PageVisibilityState) OVERRIDE;
+
+ // CanvasImageSource implementation
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+
+ // ImageBufferClient implementation
+ virtual void notifySurfaceInvalid() OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+protected:
+ virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
private:
explicit HTMLCanvasElement(Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
void reset();
PassOwnPtr<ImageBufferSurface> createImageBufferSurface(const IntSize& deviceSize, int* msaaSampleCount);
void createImageBuffer();
+ void createImageBufferInternal();
void clearImageBuffer();
void setSurfaceSize(const IntSize&);
bool paintsIntoCanvasBuffer() const;
- void setExternallyAllocatedMemory(intptr_t);
+ void updateExternallyAllocatedMemory() const;
- HashSet<CanvasObserver*> m_observers;
+ String toDataURLInternal(const String& mimeType, const double* quality, bool isSaving = false) const;
- IntSize m_size;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> > m_observers;
- OwnPtr<CanvasRenderingContext> m_context;
+ IntSize m_size;
- bool m_rendererIsCanvas;
+ OwnPtrWillBeMember<CanvasRenderingContext> m_context;
bool m_ignoreReset;
bool m_accelerationDisabled;
FloatRect m_dirtyRect;
- intptr_t m_externallyAllocatedMemory;
+ mutable intptr_t m_externallyAllocatedMemory;
bool m_originClean;
@@ -172,8 +204,6 @@ private:
mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue).
};
-DEFINE_NODE_TYPE_CASTS(HTMLCanvasElement, hasTagName(HTMLNames::canvasTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
index 0bee59fe085..e900490949d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
@@ -32,6 +32,5 @@ interface HTMLCanvasElement : HTMLElement {
[Custom, RaisesException] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString type);
// The custom binding is needed to handle context creation attributes.
- [Custom, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] any getContext([Default=Undefined] optional DOMString contextId);
+ [Custom, LogActivity] any getContext([Default=Undefined] optional DOMString contextId);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp
index a0edbbc2f20..7f7d597f521 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,23 +24,27 @@
#include "config.h"
#include "core/html/HTMLCollection.h"
-#include "HTMLNames.h"
-#include "core/dom/ClassNodeList.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ClassCollection.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NodeList.h"
#include "core/dom/NodeRareData.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/html/DocumentNameCollection.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLObjectElement.h"
#include "core/html/HTMLOptionElement.h"
+#include "core/html/WindowNameCollection.h"
+#include "wtf/HashSet.h"
namespace WebCore {
using namespace HTMLNames;
-static bool shouldOnlyIncludeDirectChildren(CollectionType type)
+static bool shouldTypeOnlyIncludeDirectChildren(CollectionType type)
{
switch (type) {
+ case ClassCollectionType:
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case DocAll:
case DocAnchors:
case DocApplets:
@@ -62,12 +67,9 @@ static bool shouldOnlyIncludeDirectChildren(CollectionType type)
case TSectionRows:
case TableTBodies:
return true;
- case ChildNodeListType:
- case ClassNodeListType:
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
break;
}
@@ -90,6 +92,9 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
case DocumentNamedItems:
case FormControls:
return NodeListIsRootedAtDocument;
+ case ClassCollectionType:
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case NodeChildren:
case TableTBodies:
case TSectionRows:
@@ -100,12 +105,9 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
case DataListOptions:
case MapAreas:
return NodeListIsRootedAtNode;
- case ChildNodeListType:
- case ClassNodeListType:
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
break;
}
@@ -116,6 +118,8 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(CollectionType type)
{
switch (type) {
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case DocImages:
case DocEmbeds:
case DocForms:
@@ -144,12 +148,11 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
return InvalidateOnIdNameAttrChange;
case FormControls:
return InvalidateForFormControls;
- case ChildNodeListType:
- case ClassNodeListType:
+ case ClassCollectionType:
+ return InvalidateOnClassAttrChange;
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
break;
}
@@ -157,536 +160,367 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
return DoNotInvalidateOnAttributeChanges;
}
-HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType)
- : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type),
- WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideType)
+HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType)
+ : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type)
+ , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
+ , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type))
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLCollection::create(ContainerNode& base, CollectionType type)
{
- return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter));
+ return adoptRefWillBeNoop(new HTMLCollection(base, type, DoesNotOverrideItemAfter));
}
HTMLCollection::~HTMLCollection()
{
- // HTMLNameCollection removes cache by itself.
- if (type() != WindowNamedItems && type() != DocumentNamedItems)
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type());
+#if !ENABLE(OILPAN)
+ if (hasValidIdNameCache())
+ unregisterIdNameCacheFromDocument(document());
+ // Named HTMLCollection types remove cache by themselves.
+ if (isUnnamedHTMLCollectionType(type()))
+ ownerNode().nodeLists()->removeCache(this, type());
+#endif
+}
+
+void HTMLCollection::invalidateCache(Document* oldDocument) const
+{
+ m_collectionIndexCache.invalidate();
+ invalidateIdNameCacheMaps(oldDocument);
}
template <class NodeListType>
-inline bool isMatchingElement(const NodeListType*, Element*);
+inline bool isMatchingElement(const NodeListType&, const Element&);
-template <> inline bool isMatchingElement(const HTMLCollection* htmlCollection, Element* element)
+template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element)
{
- CollectionType type = htmlCollection->type();
- if (!element->isHTMLElement() && !(type == DocAll || type == NodeChildren || type == WindowNamedItems))
+ CollectionType type = htmlCollection.type();
+
+ // These collections apply to any kind of Elements, not just HTMLElements.
+ switch (type) {
+ case DocAll:
+ case NodeChildren:
+ return true;
+ case ClassCollectionType:
+ return toClassCollection(htmlCollection).elementMatches(element);
+ case TagCollectionType:
+ return toTagCollection(htmlCollection).elementMatches(element);
+ case HTMLTagCollectionType:
+ return toHTMLTagCollection(htmlCollection).elementMatches(element);
+ case DocumentNamedItems:
+ return toDocumentNameCollection(htmlCollection).elementMatches(element);
+ case WindowNamedItems:
+ return toWindowNameCollection(htmlCollection).elementMatches(element);
+ default:
+ break;
+ }
+
+ // The following only applies to HTMLElements.
+ if (!element.isHTMLElement())
return false;
switch (type) {
case DocImages:
- return element->hasLocalName(imgTag);
+ return element.hasLocalName(imgTag);
case DocScripts:
- return element->hasLocalName(scriptTag);
+ return element.hasLocalName(scriptTag);
case DocForms:
- return element->hasLocalName(formTag);
+ return element.hasLocalName(formTag);
case TableTBodies:
- return element->hasLocalName(tbodyTag);
+ return element.hasLocalName(tbodyTag);
case TRCells:
- return element->hasLocalName(tdTag) || element->hasLocalName(thTag);
+ return element.hasLocalName(tdTag) || element.hasLocalName(thTag);
case TSectionRows:
- return element->hasLocalName(trTag);
+ return element.hasLocalName(trTag);
case SelectOptions:
- return element->hasLocalName(optionTag);
+ return element.hasLocalName(optionTag);
case SelectedOptions:
- return element->hasLocalName(optionTag) && toHTMLOptionElement(element)->selected();
+ return element.hasLocalName(optionTag) && toHTMLOptionElement(element).selected();
case DataListOptions:
- if (element->hasLocalName(optionTag)) {
- HTMLOptionElement* option = toHTMLOptionElement(element);
- if (!option->isDisabledFormControl() && !option->value().isEmpty())
+ if (element.hasLocalName(optionTag)) {
+ const HTMLOptionElement& option = toHTMLOptionElement(element);
+ if (!option.isDisabledFormControl() && !option.value().isEmpty())
return true;
}
return false;
case MapAreas:
- return element->hasLocalName(areaTag);
+ return element.hasLocalName(areaTag);
case DocApplets:
- return element->hasLocalName(appletTag) || (element->hasLocalName(objectTag) && toHTMLObjectElement(element)->containsJavaApplet());
+ return element.hasLocalName(appletTag) || (element.hasLocalName(objectTag) && toHTMLObjectElement(element).containsJavaApplet());
case DocEmbeds:
- return element->hasLocalName(embedTag);
+ return element.hasLocalName(embedTag);
case DocLinks:
- return (element->hasLocalName(aTag) || element->hasLocalName(areaTag)) && element->fastHasAttribute(hrefAttr);
+ return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) && element.fastHasAttribute(hrefAttr);
case DocAnchors:
- return element->hasLocalName(aTag) && element->fastHasAttribute(nameAttr);
+ return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr);
+ case ClassCollectionType:
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case DocAll:
case NodeChildren:
- return true;
case FormControls:
case DocumentNamedItems:
case TableRows:
case WindowNamedItems:
- case ChildNodeListType:
- case ClassNodeListType:
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
ASSERT_NOT_REACHED();
}
return false;
}
-template <> inline bool isMatchingElement(const LiveNodeList* nodeList, Element* element)
-{
- return nodeList->nodeMatches(element);
-}
-
-template <> inline bool isMatchingElement(const HTMLTagNodeList* nodeList, Element* element)
-{
- return nodeList->nodeMatchesInlined(element);
-}
-
-template <> inline bool isMatchingElement(const ClassNodeList* nodeList, Element* element)
+template <> inline bool isMatchingElement(const ClassCollection& collection, const Element& element)
{
- return nodeList->nodeMatchesInlined(element);
+ return collection.elementMatches(element);
}
-static Node* previousNode(Node& base, Node& previous, bool onlyIncludeDirectChildren)
+template <> inline bool isMatchingElement(const HTMLTagCollection& collection, const Element& element)
{
- return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversal::previous(previous, &base);
+ return collection.elementMatches(element);
}
-static inline Node* lastDescendent(Node& node)
+Element* HTMLCollection::virtualItemAfter(Element*) const
{
- Node* descendent = node.lastChild();
- for (Node* current = descendent; current; current = current->lastChild())
- descendent = current;
- return descendent;
-}
-
-static Node* lastNode(Node& rootNode, bool onlyIncludeDirectChildren)
-{
- return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendent(rootNode);
-}
-
-ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) const
-{
- bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren();
- CollectionType collectionType = type();
- Node& rootNode = this->rootNode();
- for (; current; current = previousNode(rootNode, *current, onlyIncludeDirectChildren)) {
- if (isNodeList(collectionType)) {
- if (current->isElementNode() && isMatchingElement(static_cast<const LiveNodeList*>(this), toElement(current)))
- return toElement(current);
- } else {
- if (current->isElementNode() && isMatchingElement(static_cast<const HTMLCollection*>(this), toElement(current)))
- return toElement(current);
- }
- }
+ ASSERT_NOT_REACHED();
return 0;
}
-ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(Node* previous) const
+static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element)
{
- Node* current;
- if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower.
- current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChildren());
- else
- current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren());
-
- if (type() == ChildNodeListType)
- return current;
- return iterateForPreviousNode(current);
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#dom-htmlallcollection-nameditem:
+ // The document.all collection returns only certain types of elements by name,
+ // although it returns any type of element by id.
+ return element.hasLocalName(aTag)
+ || element.hasLocalName(appletTag)
+ || element.hasLocalName(areaTag)
+ || element.hasLocalName(embedTag)
+ || element.hasLocalName(formTag)
+ || element.hasLocalName(frameTag)
+ || element.hasLocalName(framesetTag)
+ || element.hasLocalName(iframeTag)
+ || element.hasLocalName(imgTag)
+ || element.hasLocalName(inputTag)
+ || element.hasLocalName(objectTag)
+ || element.hasLocalName(selectTag);
+}
+
+inline Element* firstMatchingChildElement(const HTMLCollection& nodeList)
+{
+ Element* element = ElementTraversal::firstChild(nodeList.rootNode());
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::nextSibling(*element);
+ return element;
}
-template <class NodeListType>
-inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode& root)
+inline Element* lastMatchingChildElement(const HTMLCollection& nodeList)
{
- Element* element = ElementTraversal::firstWithin(root);
- while (element && !isMatchingElement(nodeList, element))
- element = ElementTraversal::next(*element, &root);
+ Element* element = ElementTraversal::lastChild(nodeList.rootNode());
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::previousSibling(*element);
return element;
}
-template <class NodeListType>
-inline Element* nextMatchingElement(const NodeListType* nodeList, Element& current, ContainerNode* root)
+inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element& current)
{
Element* next = &current;
do {
- next = ElementTraversal::next(*next, root);
- } while (next && !isMatchingElement(nodeList, next));
+ next = ElementTraversal::nextSibling(*next);
+ } while (next && !isMatchingElement(nodeList, *next));
return next;
}
-template <class NodeListType>
-inline Element* traverseMatchingElementsForwardToOffset(const NodeListType* nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root)
-{
- ASSERT(currentOffset < offset);
- Element* next = &currentElement;
- while ((next = nextMatchingElement(nodeList, *next, root))) {
- if (++currentOffset == offset)
- return next;
- }
- return 0;
-}
-
-// FIXME: This should be in ChildNodeList
-inline Node* LiveNodeListBase::traverseChildNodeListForwardToOffset(unsigned offset, Node* currentNode, unsigned& currentOffset) const
+inline Element* previousMatchingChildElement(const HTMLCollection& nodeList, Element& current)
{
- ASSERT(type() == ChildNodeListType);
- ASSERT(currentOffset < offset);
- while ((currentNode = currentNode->nextSibling())) {
- if (++currentOffset == offset)
- return currentNode;
+ Element* previous = &current;
+ do {
+ previous = ElementTraversal::previousSibling(*previous);
+ } while (previous && !isMatchingElement(nodeList, *previous));
+ return previous;
+}
+
+Element* HTMLCollection::traverseToFirstElement() const
+{
+ switch (type()) {
+ case HTMLTagCollectionType:
+ return firstMatchingElement(toHTMLTagCollection(*this));
+ case ClassCollectionType:
+ return firstMatchingElement(toClassCollection(*this));
+ default:
+ if (overridesItemAfter())
+ return virtualItemAfter(0);
+ if (shouldOnlyIncludeDirectChildren())
+ return firstMatchingChildElement(*this);
+ return firstMatchingElement(*this);
}
- return 0;
-}
-
-// FIXME: This should be in LiveNodeList
-inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode& root) const
-{
- ASSERT(isNodeList(type()));
- ASSERT(type() != ChildNodeListType);
- if (type() == HTMLTagNodeListType)
- return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), root);
- if (type() == ClassNodeListType)
- return firstMatchingElement(static_cast<const ClassNodeList*>(this), root);
- return firstMatchingElement(static_cast<const LiveNodeList*>(this), root);
-}
-
-// FIXME: This should be in LiveNodeList
-inline Element* LiveNodeListBase::traverseLiveNodeListForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) const
-{
- ASSERT(isNodeList(type()));
- ASSERT(type() != ChildNodeListType);
- if (type() == HTMLTagNodeListType)
- return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTagNodeList*>(this), offset, currentElement, currentOffset, root);
- if (type() == ClassNodeListType)
- return traverseMatchingElementsForwardToOffset(static_cast<const ClassNodeList*>(this), offset, currentElement, currentOffset, root);
- return traverseMatchingElementsForwardToOffset(static_cast<const LiveNodeList*>(this), offset, currentElement, currentOffset, root);
-}
-
-bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsigned offset) const
-{
- ASSERT(isLengthCacheValid());
- unsigned distanceFromLastItem = cachedLength() - offset;
- if (!isItemCacheValid())
- return distanceFromLastItem < offset;
-
- return cachedItemOffset() < offset && distanceFromLastItem < offset - cachedItemOffset();
-}
-
-bool ALWAYS_INLINE LiveNodeListBase::isFirstItemCloserThanCachedItem(unsigned offset) const
-{
- ASSERT(isItemCacheValid());
- if (cachedItemOffset() < offset)
- return false;
-
- unsigned distanceFromCachedItem = cachedItemOffset() - offset;
- return offset < distanceFromCachedItem;
}
-ALWAYS_INLINE void LiveNodeListBase::setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const
+Element* HTMLCollection::traverseToLastElement() const
{
- setItemCache(item, offset);
- if (overridesItemAfter()) {
- ASSERT_WITH_SECURITY_IMPLICATION(item->isElementNode());
- static_cast<const HTMLCollection*>(this)->m_cachedElementsArrayOffset = elementsArrayOffset;
- } else
- ASSERT(!elementsArrayOffset);
-}
-
-unsigned LiveNodeListBase::length() const
-{
- if (isLengthCacheValid())
- return cachedLength();
-
- item(UINT_MAX);
- ASSERT(isLengthCacheValid());
-
- return cachedLength();
+ ASSERT(canTraverseBackward());
+ if (shouldOnlyIncludeDirectChildren())
+ return lastMatchingChildElement(*this);
+ return lastMatchingElement(*this);
}
-// FIXME: It is silly that these functions are in HTMLCollection.cpp.
-Node* LiveNodeListBase::item(unsigned offset) const
+Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const
{
- if (isItemCacheValid() && cachedItemOffset() == offset)
- return cachedItem();
-
- if (isLengthCacheValid() && cachedLength() <= offset)
- return 0;
-
- ContainerNode* root = rootContainerNode();
- if (!root) {
- // FIMXE: In someTextNode.childNodes case the root is Text. We shouldn't even make a LiveNodeList for that.
- setLengthCache(0);
- return 0;
- }
-
- if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) {
- Node* lastItem = itemBefore(0);
- ASSERT(lastItem);
- setItemCache(lastItem, cachedLength() - 1, 0);
- } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) {
- unsigned offsetInArray = 0;
- Node* firstItem;
- if (type() == ChildNodeListType)
- firstItem = root->firstChild();
- else if (isNodeList(type()))
- firstItem = traverseLiveNodeListFirstElement(*root);
- else
- firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstElement(offsetInArray, *root);
-
- if (!firstItem) {
- setLengthCache(0);
+ ASSERT(currentOffset < offset);
+ switch (type()) {
+ case HTMLTagCollectionType:
+ return traverseMatchingElementsForwardToOffset(toHTMLTagCollection(*this), offset, currentElement, currentOffset);
+ case ClassCollectionType:
+ return traverseMatchingElementsForwardToOffset(toClassCollection(*this), offset, currentElement, currentOffset);
+ default:
+ if (overridesItemAfter()) {
+ Element* next = &currentElement;
+ while ((next = virtualItemAfter(next))) {
+ if (++currentOffset == offset)
+ return next;
+ }
return 0;
}
- setItemCache(firstItem, 0, offsetInArray);
- ASSERT(!cachedItemOffset());
+ if (shouldOnlyIncludeDirectChildren()) {
+ Element* next = &currentElement;
+ while ((next = nextMatchingChildElement(*this, *next))) {
+ if (++currentOffset == offset)
+ return next;
+ }
+ return 0;
+ }
+ return traverseMatchingElementsForwardToOffset(*this, offset, currentElement, currentOffset);
}
-
- if (cachedItemOffset() == offset)
- return cachedItem();
-
- return itemBeforeOrAfterCachedItem(offset, root);
}
-inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const
+Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const
{
- unsigned currentOffset = cachedItemOffset();
- Node* currentItem = cachedItem();
- ASSERT(currentItem);
- ASSERT(currentOffset != offset);
-
- if (offset < cachedItemOffset()) {
- ASSERT(!overridesItemAfter());
- while ((currentItem = itemBefore(currentItem))) {
- ASSERT(currentOffset);
- currentOffset--;
- if (currentOffset == offset) {
- setItemCache(currentItem, currentOffset, 0);
- return currentItem;
- }
+ ASSERT(currentOffset > offset);
+ ASSERT(canTraverseBackward());
+ if (shouldOnlyIncludeDirectChildren()) {
+ Element* previous = &currentElement;
+ while ((previous = previousMatchingChildElement(*this, *previous))) {
+ if (--currentOffset == offset)
+ return previous;
}
- ASSERT_NOT_REACHED();
- return 0;
- }
-
- unsigned offsetInArray = 0;
- if (type() == ChildNodeListType)
- currentItem = traverseChildNodeListForwardToOffset(offset, currentItem, currentOffset);
- else if (isNodeList(type()))
- currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(*currentItem), currentOffset, root);
- else
- currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, toElement(*currentItem), currentOffset, offsetInArray, root);
-
- if (!currentItem) {
- // Did not find the item. On plus side, we now know the length.
- setLengthCache(currentOffset + 1);
return 0;
}
- setItemCache(currentItem, currentOffset, offsetInArray);
- return currentItem;
-}
-
-Element* HTMLCollection::virtualItemAfter(unsigned&, Element*) const
-{
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement* element)
-{
- // The document.all collection returns only certain types of elements by name,
- // although it returns any type of element by id.
- return element->hasLocalName(appletTag)
- || element->hasLocalName(embedTag)
- || element->hasLocalName(formTag)
- || element->hasLocalName(imgTag)
- || element->hasLocalName(inputTag)
- || element->hasLocalName(objectTag)
- || element->hasLocalName(selectTag);
+ return traverseMatchingElementsBackwardToOffset(*this, offset, currentElement, currentOffset);
}
-bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const AtomicString& name) const
+Element* HTMLCollection::namedItem(const AtomicString& name) const
{
- if (!element->isHTMLElement())
- return false;
-
- HTMLElement* e = toHTMLElement(element);
- if (!checkName)
- return e->getIdAttribute() == name;
-
- if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e))
- return false;
+ // 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.
+ updateIdNameCache();
- return e->getNameAttribute() == name && e->getIdAttribute() != name;
-}
+ const NamedItemCache& cache = namedItemCache();
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* idResults = cache.getElementsById(name);
+ if (idResults && !idResults->isEmpty())
+ return idResults->first();
-inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, ContainerNode& root)
-{
- Element* element = ElementTraversal::firstWithin(root);
- while (element && !isMatchingElement(nodeList, element))
- element = ElementTraversal::nextSkippingChildren(*element, &root);
- return element;
-}
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* nameResults = cache.getElementsByName(name);
+ if (nameResults && !nameResults->isEmpty())
+ return nameResults->first();
-inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element& current, ContainerNode* root)
-{
- Element* next = &current;
- do {
- next = ElementTraversal::nextSkippingChildren(*next, root);
- } while (next && !isMatchingElement(nodeList, next));
- return next;
-}
-
-inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, ContainerNode& root) const
-{
- if (overridesItemAfter())
- return virtualItemAfter(offsetInArray, 0);
- ASSERT(!offsetInArray);
- if (shouldOnlyIncludeDirectChildren())
- return firstMatchingChildElement(static_cast<const HTMLCollection*>(this), root);
- return firstMatchingElement(static_cast<const HTMLCollection*>(this), root);
+ return 0;
}
-inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Element& previous, ContainerNode* root) const
+bool HTMLCollection::namedPropertyQuery(const AtomicString& name, ExceptionState&)
{
- if (overridesItemAfter())
- return virtualItemAfter(offsetInArray, &previous);
- ASSERT(!offsetInArray);
- if (shouldOnlyIncludeDirectChildren())
- return nextMatchingChildElement(this, previous, root);
- return nextMatchingElement(this, previous, root);
+ return namedItem(name);
}
-inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNode* root) const
+void HTMLCollection::supportedPropertyNames(Vector<String>& names)
{
- ASSERT(currentOffset < offset);
- if (overridesItemAfter()) {
- offsetInArray = m_cachedElementsArrayOffset;
- Element* next = &currentElement;
- while ((next = virtualItemAfter(offsetInArray, next))) {
- if (++currentOffset == offset)
- return next;
+ // As per the specification (http://dom.spec.whatwg.org/#htmlcollection):
+ // The supported property names are the values from the list returned by these steps:
+ // 1. Let result be an empty list.
+ // 2. For each element represented by the collection, in tree order, run these substeps:
+ // 1. If element has an ID which is neither the empty string nor is in result, append element's ID to result.
+ // 2. If element is in the HTML namespace and has a name attribute whose value is neither the empty string
+ // nor is in result, append element's name attribute value to result.
+ // 3. Return result.
+ HashSet<AtomicString> existingNames;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
+ const AtomicString& idAttribute = element->getIdAttribute();
+ if (!idAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(idAttribute);
+ if (addResult.isNewEntry)
+ names.append(idAttribute);
}
- return 0;
- }
- if (shouldOnlyIncludeDirectChildren()) {
- Element* next = &currentElement;
- while ((next = nextMatchingChildElement(this, *next, root))) {
- if (++currentOffset == offset)
- return next;
+ if (!element->isHTMLElement())
+ continue;
+ const AtomicString& nameAttribute = element->getNameAttribute();
+ if (!nameAttribute.isEmpty() && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(nameAttribute);
+ if (addResult.isNewEntry)
+ names.append(nameAttribute);
}
- return 0;
}
- return traverseMatchingElementsForwardToOffset(this, offset, currentElement, currentOffset, root);
}
-Node* HTMLCollection::namedItem(const AtomicString& name) const
+void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionState&)
{
- // 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.
-
- ContainerNode* root = rootContainerNode();
- if (!root)
- return 0;
-
- unsigned arrayOffset = 0;
- unsigned i = 0;
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) {
- if (checkForNameMatch(element, /* checkName */ false, name)) {
- setItemCache(element, i, arrayOffset);
- return element;
- }
- i++;
- }
-
- i = 0;
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) {
- if (checkForNameMatch(element, /* checkName */ true, name)) {
- setItemCache(element, i, arrayOffset);
- return element;
- }
- i++;
- }
-
- return 0;
+ supportedPropertyNames(names);
}
-void HTMLCollection::updateNameCache() const
+void HTMLCollection::updateIdNameCache() const
{
- if (hasNameCache())
- return;
-
- ContainerNode* root = rootContainerNode();
- if (!root)
+ if (hasValidIdNameCache())
return;
- unsigned arrayOffset = 0;
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) {
+ OwnPtrWillBeRawPtr<NamedItemCache> cache = NamedItemCache::create();
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
const AtomicString& idAttrVal = element->getIdAttribute();
if (!idAttrVal.isEmpty())
- appendIdCache(idAttrVal, element);
+ cache->addElementWithId(idAttrVal, element);
if (!element->isHTMLElement())
continue;
const AtomicString& nameAttrVal = element->getNameAttribute();
- if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(element))))
- appendNameCache(nameAttrVal, element);
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
+ cache->addElementWithName(nameAttrVal, element);
}
-
- setHasNameCache();
+ // Set the named item cache last as traversing the tree may cause cache invalidation.
+ setNamedItemCache(cache.release());
}
-bool HTMLCollection::hasNamedItem(const AtomicString& name) const
+void HTMLCollection::namedItems(const AtomicString& name, WillBeHeapVector<RefPtrWillBeMember<Element> >& result) const
{
+ ASSERT(result.isEmpty());
if (name.isEmpty())
- return false;
+ return;
- updateNameCache();
+ updateIdNameCache();
- if (Vector<Element*>* cache = idCache(name)) {
- if (!cache->isEmpty())
- return true;
+ const NamedItemCache& cache = namedItemCache();
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* idResults = cache.getElementsById(name)) {
+ for (unsigned i = 0; i < idResults->size(); ++i)
+ result.append(idResults->at(i));
}
-
- if (Vector<Element*>* cache = nameCache(name)) {
- if (!cache->isEmpty())
- return true;
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* nameResults = cache.getElementsByName(name)) {
+ for (unsigned i = 0; i < nameResults->size(); ++i)
+ result.append(nameResults->at(i));
}
-
- return false;
}
-void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const
+HTMLCollection::NamedItemCache::NamedItemCache()
{
- ASSERT(result.isEmpty());
- if (name.isEmpty())
- return;
-
- updateNameCache();
-
- Vector<Element*>* idResults = idCache(name);
- Vector<Element*>* nameResults = nameCache(name);
-
- 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));
}
-void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
+void HTMLCollection::trace(Visitor* visitor)
{
- OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->value;
- if (!vector)
- vector = adoptPtr(new Vector<Element*>);
- vector->append(element);
+ visitor->trace(m_namedItemCache);
+ visitor->trace(m_collectionIndexCache);
+ LiveNodeListBase::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h
index 967b247db4d..97416341978 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,7 +24,8 @@
#ifndef HTMLCollection_h
#define HTMLCollection_h
-#include "core/dom/LiveNodeList.h"
+#include "core/dom/LiveNodeListBase.h"
+#include "core/html/CollectionIndexCache.h"
#include "core/html/CollectionType.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
@@ -31,65 +33,133 @@
namespace WebCore {
-class HTMLCollection : public LiveNodeListBase {
+class HTMLCollection : public RefCountedWillBeGarbageCollectedFinalized<HTMLCollection>, public ScriptWrappable, public LiveNodeListBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLCollection);
public:
- static PassRefPtr<HTMLCollection> create(Node* base, CollectionType);
+ enum ItemAfterOverrideType {
+ OverridesItemAfter,
+ DoesNotOverrideItemAfter,
+ };
+
+ static PassRefPtrWillBeRawPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
virtual ~HTMLCollection();
+ virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
+ void invalidateCacheForAttribute(const QualifiedName*) const;
// DOM API
- virtual Node* namedItem(const AtomicString& name) const;
+ unsigned length() const { return m_collectionIndexCache.nodeCount(*this); }
+ Element* item(unsigned offset) const { return m_collectionIndexCache.nodeAt(*this, offset); }
+ virtual Element* namedItem(const AtomicString& name) const;
+ bool namedPropertyQuery(const AtomicString&, ExceptionState&);
+ void namedPropertyEnumerator(Vector<String>& names, ExceptionState&);
// Non-DOM API
- virtual bool hasNamedItem(const AtomicString& name) const;
- void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const;
- bool isEmpty() const
- {
- if (isLengthCacheValid())
- return !cachedLength();
- if (isItemCacheValid())
- return !cachedItem();
- return !item(0);
- }
- bool hasExactlyOneItem() const
- {
- if (isLengthCacheValid())
- return cachedLength() == 1;
- if (isItemCacheValid())
- return cachedItem() && !cachedItemOffset() && !item(1);
- return item(0) && !item(1);
- }
+ void namedItems(const AtomicString& name, WillBeHeapVector<RefPtrWillBeMember<Element> >&) const;
+ bool isEmpty() const { return m_collectionIndexCache.isEmpty(*this); }
+ bool hasExactlyOneItem() const { return m_collectionIndexCache.hasExactlyOneNode(*this); }
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const;
+ // CollectionIndexCache API.
+ bool canTraverseBackward() const { return !overridesItemAfter(); }
+ Element* traverseToFirstElement() const;
+ Element* traverseToLastElement() const;
+ Element* traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const;
+ Element* traverseBackwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const;
- Element* traverseFirstElement(unsigned& offsetInArray, ContainerNode& root) const;
- Element* traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNode* root) const;
+ virtual void trace(Visitor*);
protected:
- HTMLCollection(Node* base, CollectionType, ItemAfterOverrideType);
-
- virtual void updateNameCache() const;
+ HTMLCollection(ContainerNode& base, CollectionType, ItemAfterOverrideType);
+
+ class NamedItemCache FINAL : public NoBaseWillBeGarbageCollected<NamedItemCache> {
+ public:
+ static PassOwnPtrWillBeRawPtr<NamedItemCache> create()
+ {
+ return adoptPtrWillBeNoop(new NamedItemCache);
+ }
+
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* getElementsById(const AtomicString& id) const { return m_idCache.get(id.impl()); }
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* getElementsByName(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
+ void addElementWithId(const AtomicString& id, Element* element) { addElementToMap(m_idCache, id, element); }
+ void addElementWithName(const AtomicString& name, Element* element) { addElementToMap(m_nameCache, name, element); }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_idCache);
+ visitor->trace(m_nameCache);
+ }
+
+ private:
+ NamedItemCache();
+ typedef WillBeHeapHashMap<StringImpl*, OwnPtrWillBeMember<WillBeHeapVector<RawPtrWillBeMember<Element> > > > StringToElementsMap;
+ static void addElementToMap(StringToElementsMap& map, const AtomicString& key, Element* element)
+ {
+ OwnPtrWillBeMember<WillBeHeapVector<RawPtrWillBeMember<Element> > >& vector = map.add(key.impl(), nullptr).storedValue->value;
+ if (!vector)
+ vector = adoptPtrWillBeNoop(new WillBeHeapVector<RawPtrWillBeMember<Element> >);
+ vector->append(element);
+ }
+
+ StringToElementsMap m_idCache;
+ StringToElementsMap m_nameCache;
+ };
+
+ bool overridesItemAfter() const { return m_overridesItemAfter; }
+ virtual Element* virtualItemAfter(Element*) const;
+ bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; }
+ virtual void supportedPropertyNames(Vector<String>& names);
+
+ virtual void updateIdNameCache() const;
+ bool hasValidIdNameCache() const { return m_namedItemCache; }
+
+ void setNamedItemCache(PassOwnPtrWillBeRawPtr<NamedItemCache> cache) const
+ {
+ ASSERT(!m_namedItemCache);
+ document().registerNodeListWithIdNameCache(this);
+ m_namedItemCache = cache;
+ }
- typedef HashMap<StringImpl*, OwnPtr<Vector<Element*> > > NodeCacheMap;
- Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); }
- Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
- void appendIdCache(const AtomicString& name, Element* element) const { append(m_idCache, name, element); }
- void appendNameCache(const AtomicString& name, Element* element) const { append(m_nameCache, name, element); }
+ NamedItemCache& namedItemCache() const
+ {
+ ASSERT(m_namedItemCache);
+ return *m_namedItemCache;
+ }
private:
- bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
- Element* traverseNextElement(unsigned& offsetInArray, Element& previous, ContainerNode* root) const;
+ void invalidateIdNameCacheMaps(Document* oldDocument = 0) const
+ {
+ if (!hasValidIdNameCache())
+ return;
- virtual bool isLiveNodeList() const OVERRIDE { ASSERT_NOT_REACHED(); return true; }
+ // Make sure we decrement the NodeListWithIdNameCache count from
+ // the old document instead of the new one in the case the collection
+ // is moved to a new document.
+ unregisterIdNameCacheFromDocument(oldDocument ? *oldDocument : document());
- static void append(NodeCacheMap&, const AtomicString&, Element*);
+ m_namedItemCache.clear();
+ }
- mutable NodeCacheMap m_idCache;
- mutable NodeCacheMap m_nameCache;
- mutable unsigned m_cachedElementsArrayOffset;
+ void unregisterIdNameCacheFromDocument(Document& document) const
+ {
+ ASSERT(hasValidIdNameCache());
+ document.unregisterNodeListWithIdNameCache(this);
+ }
- friend class LiveNodeListBase;
+ const unsigned m_overridesItemAfter : 1;
+ const unsigned m_shouldOnlyIncludeDirectChildren : 1;
+ mutable OwnPtrWillBeMember<NamedItemCache> m_namedItemCache;
+ mutable CollectionIndexCache<HTMLCollection, Element> m_collectionIndexCache;
};
+DEFINE_TYPE_CASTS(HTMLCollection, LiveNodeListBase, collection, isHTMLCollectionType(collection->type()), isHTMLCollectionType(collection.type()));
+
+inline void HTMLCollection::invalidateCacheForAttribute(const QualifiedName* attrName) const
+{
+ if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+ invalidateCache();
+ else if (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr)
+ invalidateIdNameCacheMaps();
+}
+
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl
index 0198742a6cb..cab83cd6177 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2014 Samsung Electronics. 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
@@ -21,11 +22,11 @@
[
Custom=Wrap,
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
+ WillBeGarbageCollected,
] interface HTMLCollection {
readonly attribute unsigned long length;
- getter Node item([Default=Undefined] optional unsigned long index);
- Node namedItem([Default=Undefined] optional DOMString name);
- [NotEnumerable, ImplementedAs=namedItem] getter Node ([Default=Undefined] optional DOMString name);
+ getter Element item([Default=Undefined] optional unsigned long index);
+ getter Element namedItem(DOMString name);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp
index 81691295e85..e47e91002d5 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp
@@ -25,26 +25,22 @@
*/
#include "config.h"
-#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/HTMLContentElement.h"
-#include "HTMLNames.h"
-#include "core/css/CSSParser.h"
+#include "core/HTMLNames.h"
#include "core/css/SelectorChecker.h"
#include "core/css/SiblingTraversalStrategies.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/dom/QualifiedName.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<HTMLContentElement> HTMLContentElement::create(Document& document)
-{
- return adoptRef(new HTMLContentElement(document));
-}
-
-HTMLContentElement::HTMLContentElement(Document& document)
+inline HTMLContentElement::HTMLContentElement(Document& document)
: InsertionPoint(contentTag, document)
, m_shouldParseSelect(false)
, m_isValidSelector(true)
@@ -52,6 +48,8 @@ HTMLContentElement::HTMLContentElement(Document& document)
ScriptWrappable::init(this);
}
+DEFINE_NODE_FACTORY(HTMLContentElement)
+
HTMLContentElement::~HTMLContentElement()
{
}
@@ -60,7 +58,7 @@ void HTMLContentElement::parseSelect()
{
ASSERT(m_shouldParseSelect);
- CSSParser parser(document());
+ BisonCSSParser parser(CSSParserContext(document(), 0));
parser.parseSelector(m_select, m_selectorList);
m_shouldParseSelect = false;
m_isValidSelector = validateSelect();
@@ -77,8 +75,14 @@ void HTMLContentElement::parseAttribute(const QualifiedName& name, const AtomicS
root->owner()->willAffectSelector();
m_shouldParseSelect = true;
m_select = value;
- } else
+ } else {
InsertionPoint::parseAttribute(name, value);
+ }
+}
+
+static inline bool includesDisallowedPseudoClass(const CSSSelector& selector)
+{
+ return selector.match() == CSSSelector::PseudoClass && selector.pseudoType() != CSSSelector::PseudoNot;
}
bool HTMLContentElement::validateSelect() const
@@ -91,15 +95,22 @@ bool HTMLContentElement::validateSelect() const
if (!m_selectorList.isValid())
return false;
- for (const CSSSelector* selector = m_selectorList.first(); selector; selector = m_selectorList.next(selector)) {
+ bool allowAnyPseudoClasses = RuntimeEnabledFeatures::pseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled() || (containingShadowRoot() && containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot);
+
+ for (const CSSSelector* selector = m_selectorList.first(); selector; selector = m_selectorList.next(*selector)) {
if (!selector->isCompound())
return false;
+ if (allowAnyPseudoClasses)
+ continue;
+ for (const CSSSelector* subSelector = selector; subSelector; subSelector = subSelector->tagHistory()) {
+ if (includesDisallowedPseudoClass(*subSelector))
+ return false;
+ }
}
-
return true;
}
-static inline bool checkOneSelector(const CSSSelector* selector, const Vector<Node*, 32>& siblings, int nth)
+static inline bool checkOneSelector(const CSSSelector& selector, const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth)
{
Element* element = toElement(siblings[nth]);
SelectorChecker selectorChecker(element->document(), SelectorChecker::CollectingCSSRules);
@@ -108,10 +119,10 @@ static inline bool checkOneSelector(const CSSSelector* selector, const Vector<No
return selectorChecker.match(context, strategy) == SelectorChecker::SelectorMatches;
}
-bool HTMLContentElement::matchSelector(const Vector<Node*, 32>& siblings, int nth) const
+bool HTMLContentElement::matchSelector(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const
{
- for (const CSSSelector* selector = selectorList().first(); selector; selector = CSSSelectorList::next(selector)) {
- if (checkOneSelector(selector, siblings, nth))
+ for (const CSSSelector* selector = selectorList().first(); selector; selector = CSSSelectorList::next(*selector)) {
+ if (checkOneSelector(*selector, siblings, nth))
return true;
}
return false;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h
index 9d14a277dc7..775813415d1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h
@@ -1,2 +1,94 @@
-// FIXME: Move HTMLContentElement.h here.
-#include "core/html/shadow/HTMLContentElement.h"
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 HTMLContentElement_h
+#define HTMLContentElement_h
+
+#include "core/css/CSSSelectorList.h"
+#include "core/dom/shadow/InsertionPoint.h"
+
+namespace WebCore {
+
+class HTMLContentElement FINAL : public InsertionPoint {
+public:
+ DECLARE_NODE_FACTORY(HTMLContentElement);
+ virtual ~HTMLContentElement();
+
+ virtual bool canAffectSelector() const OVERRIDE { return true; }
+
+ bool canSelectNode(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const;
+
+ const CSSSelectorList& selectorList() const;
+ bool isSelectValid() const;
+
+private:
+ explicit HTMLContentElement(Document&);
+
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
+
+ bool validateSelect() const;
+ void parseSelect();
+
+ bool matchSelector(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const;
+
+ bool m_shouldParseSelect;
+ bool m_isValidSelector;
+ AtomicString m_select;
+ CSSSelectorList m_selectorList;
+};
+
+inline const CSSSelectorList& HTMLContentElement::selectorList() const
+{
+ if (m_shouldParseSelect)
+ const_cast<HTMLContentElement*>(this)->parseSelect();
+ return m_selectorList;
+}
+
+inline bool HTMLContentElement::isSelectValid() const
+{
+ if (m_shouldParseSelect)
+ const_cast<HTMLContentElement*>(this)->parseSelect();
+ return m_isValidSelector;
+}
+
+inline bool HTMLContentElement::canSelectNode(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const
+{
+ if (m_select.isNull() || m_select.isEmpty())
+ return true;
+ if (!isSelectValid())
+ return false;
+ if (!siblings[nth]->isElementNode())
+ return false;
+ return matchSelector(siblings, nth);
+}
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl
index ab593425152..15d63d6681a 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl
@@ -27,6 +27,5 @@
[
] interface HTMLContentElement : HTMLElement {
[Reflect, TreatNullAs=NullString] attribute DOMString select;
- attribute boolean resetStyleInheritance;
NodeList getDistributedNodes();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp
index 7196698f622..59f54a6e039 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLDListElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,9 +35,6 @@ inline HTMLDListElement::HTMLDListElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDListElement> HTMLDListElement::create(Document& document)
-{
- return adoptRef(new HTMLDListElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLDListElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h
index 24aeb814c09..8942e5e29ff 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLDListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDListElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDListElement);
private:
explicit HTMLDListElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp
index d8666e88e91..99f268c9395 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/HTMLDataListElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/IdTargetObserverRegistry.h"
#include "core/frame/UseCounter.h"
@@ -44,13 +44,13 @@ inline HTMLDataListElement::HTMLDataListElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDataListElement> HTMLDataListElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLDataListElement> HTMLDataListElement::create(Document& document)
{
UseCounter::count(document, UseCounter::DataListElement);
- return adoptRef(new HTMLDataListElement(document));
+ return adoptRefWillBeNoop(new HTMLDataListElement(document));
}
-PassRefPtr<HTMLCollection> HTMLDataListElement::options()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLDataListElement::options()
{
return ensureCachedHTMLCollection(DataListOptions);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h
index e19686bfa5c..7d79c7720f3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h
@@ -39,9 +39,9 @@ namespace WebCore {
class HTMLDataListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDataListElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLDataListElement> create(Document&);
- PassRefPtr<HTMLCollection> options();
+ PassRefPtrWillBeRawPtr<HTMLCollection> options();
void optionElementChildrenChanged();
@@ -51,8 +51,6 @@ private:
virtual void finishParsingChildren() OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLDataListElement, hasTagName(HTMLNames::datalistTag));
-
} // namespace WebCore
#endif // HTMLDataListElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl
index 93c8663c2bb..4dd3654e759 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl
@@ -28,8 +28,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- RuntimeEnabled=DataListElement
-] interface HTMLDataListElement : HTMLElement {
+interface HTMLDataListElement : HTMLElement {
readonly attribute HTMLCollection options;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp
index 28c6bbeae6c..b2973cf2e51 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp
@@ -21,12 +21,17 @@
#include "config.h"
#include "core/html/HTMLDetailsElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/EventSender.h"
+#include "core/html/HTMLContentElement.h"
+#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLSummaryElement.h"
-#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/ShadowElementNames.h"
#include "core/rendering/RenderBlockFlow.h"
#include "platform/text/PlatformLocale.h"
@@ -34,9 +39,15 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(Document& document)
+static DetailsEventSender& detailsToggleEventSender()
{
- RefPtr<HTMLDetailsElement> details = adoptRef(new HTMLDetailsElement(document));
+ DEFINE_STATIC_LOCAL(DetailsEventSender, sharedToggleEventSender, (EventTypeNames::toggle));
+ return sharedToggleEventSender;
+}
+
+PassRefPtrWillBeRawPtr<HTMLDetailsElement> HTMLDetailsElement::create(Document& document)
+{
+ RefPtrWillBeRawPtr<HTMLDetailsElement> details = adoptRefWillBeNoop(new HTMLDetailsElement(document));
details->ensureUserAgentShadowRoot();
return details.release();
}
@@ -48,6 +59,18 @@ HTMLDetailsElement::HTMLDetailsElement(Document& document)
ScriptWrappable::init(this);
}
+HTMLDetailsElement::~HTMLDetailsElement()
+{
+ detailsToggleEventSender().cancelEvent(this);
+}
+
+void HTMLDetailsElement::dispatchPendingEvent(DetailsEventSender* eventSender)
+{
+ ASSERT_UNUSED(eventSender, eventSender == &detailsToggleEventSender());
+ dispatchEvent(Event::create(EventTypeNames::toggle));
+}
+
+
RenderObject* HTMLDetailsElement::createRenderer(RenderStyle*)
{
return new RenderBlockFlow(this);
@@ -57,26 +80,29 @@ void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
DEFINE_STATIC_LOCAL(const AtomicString, summarySelector, ("summary:first-of-type", AtomicString::ConstructFromLiteral));
- RefPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(document());
+ RefPtrWillBeRawPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(document());
defaultSummary->appendChild(Text::create(document(), locale().queryString(blink::WebLocalizedString::DetailsLabel)));
- RefPtr<HTMLContentElement> content = HTMLContentElement::create(document());
- content->setAttribute(selectAttr, summarySelector);
- content->appendChild(defaultSummary);
-
- root.appendChild(content);
- root.appendChild(HTMLContentElement::create(document()));
+ RefPtrWillBeRawPtr<HTMLContentElement> summary = HTMLContentElement::create(document());
+ summary->setIdAttribute(ShadowElementNames::detailsSummary());
+ summary->setAttribute(selectAttr, summarySelector);
+ summary->appendChild(defaultSummary);
+ root.appendChild(summary.release());
+
+ RefPtrWillBeRawPtr<HTMLDivElement> content = HTMLDivElement::create(document());
+ content->setIdAttribute(ShadowElementNames::detailsContent());
+ content->appendChild(HTMLContentElement::create(document()));
+ content->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+ root.appendChild(content.release());
}
Element* HTMLDetailsElement::findMainSummary() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(summaryTag))
- return toElement(child);
- }
+ if (HTMLSummaryElement* summary = Traversal<HTMLSummaryElement>::firstChild(*this))
+ return summary;
HTMLContentElement* content = toHTMLContentElement(userAgentShadowRoot()->firstChild());
- ASSERT(content->firstChild() && content->firstChild()->hasTagName(summaryTag));
+ ASSERT(content->firstChild() && isHTMLSummaryElement(*content->firstChild()));
return toElement(content->firstChild());
}
@@ -85,20 +111,28 @@ void HTMLDetailsElement::parseAttribute(const QualifiedName& name, const AtomicS
if (name == openAttr) {
bool oldValue = m_isOpen;
m_isOpen = !value.isNull();
- if (oldValue != m_isOpen)
- lazyReattachIfAttached();
- } else
- HTMLElement::parseAttribute(name, value);
-}
-
-bool HTMLDetailsElement::childShouldCreateRenderer(const Node& child) const
-{
- // FIXME: These checks do not look correct, we should just use insertion points instead.
- if (m_isOpen)
- return HTMLElement::childShouldCreateRenderer(child);
- if (!child.hasTagName(summaryTag))
- return false;
- return child == findMainSummary() && HTMLElement::childShouldCreateRenderer(child);
+ if (m_isOpen == oldValue)
+ return;
+
+ // Dispatch toggle event asynchronously.
+ detailsToggleEventSender().cancelEvent(this);
+ detailsToggleEventSender().dispatchEventSoon(this);
+
+ Element* content = ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsContent());
+ ASSERT(content);
+ if (m_isOpen)
+ content->removeInlineStyleProperty(CSSPropertyDisplay);
+ else
+ content->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+ Element* summary = ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsSummary());
+ ASSERT(summary);
+ // FIXME: DetailsMarkerControl's RenderDetailsMarker has no concept of being updated
+ // without recreating it causing a repaint. Instead we should change it so we can tell
+ // it to toggle the open/closed triangle state and avoid reattaching the entire summary.
+ summary->lazyReattachIfAttached();
+ return;
+ }
+ HTMLElement::parseAttribute(name, value);
}
void HTMLDetailsElement::toggleOpen()
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h
index d5a6b4a6169..2e9d762d980 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h
@@ -25,18 +25,23 @@
namespace WebCore {
+template<typename T> class EventSender;
+typedef EventSender<HTMLDetailsElement> DetailsEventSender;
+
class HTMLDetailsElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDetailsElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLDetailsElement> create(Document&);
void toggleOpen();
+ virtual ~HTMLDetailsElement();
+
+ void dispatchPendingEvent(DetailsEventSender*);
Element* findMainSummary() const;
private:
explicit HTMLDetailsElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
virtual bool isInteractiveContent() const OVERRIDE;
@@ -44,18 +49,6 @@ private:
bool m_isOpen;
};
-inline bool isHTMLDetailsElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::detailsTag);
-}
-
-inline bool isHTMLDetailsElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::detailsTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLDetailsElement, hasTagName(HTMLNames::detailsTag));
-
} // namespace WebCore
#endif // HTMLDetailsElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
index 59d5bc04a5e..5eb8125e534 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
@@ -45,7 +45,7 @@ static void setFocusForModalDialog(HTMLDialogElement* dialog)
Element* focusableDescendant = 0;
Node* next = 0;
for (Node* node = dialog->firstChild(); node; node = next) {
- if (node->hasTagName(dialogTag))
+ if (isHTMLDialogElement(*node))
next = NodeTraversal::nextSkippingChildren(*node, dialog);
else
next = NodeTraversal::next(*node, dialog);
@@ -57,7 +57,6 @@ static void setFocusForModalDialog(HTMLDialogElement* dialog)
HTMLFormControlElement* control = toHTMLFormControlElement(node);
if (control->isAutofocusable()) {
control->focus();
- control->setAutofocused();
return;
}
}
@@ -75,7 +74,7 @@ static void setFocusForModalDialog(HTMLDialogElement* dialog)
return;
}
- dialog->document().setFocusedElement(0);
+ dialog->document().setFocusedElement(nullptr);
}
static void inertSubtreesChanged(Document& document)
@@ -84,25 +83,22 @@ static void inertSubtreesChanged(Document& document)
// tree can change inertness which means they must be added or removed from
// the tree. The most foolproof way is to clear the entire tree and rebuild
// it, though a more clever way is probably possible.
- Document* topDocument = document.topDocument();
- topDocument->clearAXObjectCache();
- if (AXObjectCache* cache = topDocument->axObjectCache())
- cache->childrenChanged(cache->getOrCreate(topDocument));
+ Document& topDocument = document.topDocument();
+ topDocument.clearAXObjectCache();
+ if (AXObjectCache* cache = topDocument.axObjectCache())
+ cache->childrenChanged(cache->getOrCreate(&topDocument));
}
-HTMLDialogElement::HTMLDialogElement(Document& document)
+inline HTMLDialogElement::HTMLDialogElement(Document& document)
: HTMLElement(dialogTag, document)
- , m_centeringMode(Uninitialized)
+ , m_centeringMode(NotCentered)
, m_centeredPosition(0)
, m_returnValue("")
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDialogElement> HTMLDialogElement::create(Document& document)
-{
- return adoptRef(new HTMLDialogElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLDialogElement)
void HTMLDialogElement::close(const String& returnValue, ExceptionState& exceptionState)
{
@@ -132,10 +128,10 @@ void HTMLDialogElement::closeDialog(const String& returnValue)
void HTMLDialogElement::forceLayoutForCentering()
{
- m_centeringMode = Uninitialized;
+ m_centeringMode = NeedsCentering;
document().updateLayoutIgnorePendingStylesheets();
- if (m_centeringMode == Uninitialized)
- m_centeringMode = NotCentered;
+ if (m_centeringMode == NeedsCentering)
+ setNotCentered();
}
void HTMLDialogElement::show()
@@ -143,7 +139,6 @@ void HTMLDialogElement::show()
if (fastHasAttribute(openAttr))
return;
setBooleanAttribute(openAttr, true);
- forceLayoutForCentering();
}
void HTMLDialogElement::showModal(ExceptionState& exceptionState)
@@ -168,16 +163,22 @@ void HTMLDialogElement::showModal(ExceptionState& exceptionState)
setFocusForModalDialog(this);
}
+void HTMLDialogElement::removedFrom(ContainerNode* insertionPoint)
+{
+ HTMLElement::removedFrom(insertionPoint);
+ setNotCentered();
+ // FIXME: We should call inertSubtreesChanged() here.
+}
+
void HTMLDialogElement::setCentered(LayoutUnit centeredPosition)
{
- ASSERT(m_centeringMode == Uninitialized);
+ ASSERT(m_centeringMode == NeedsCentering);
m_centeredPosition = centeredPosition;
m_centeringMode = Centered;
}
void HTMLDialogElement::setNotCentered()
{
- ASSERT(m_centeringMode == Uninitialized);
m_centeringMode = NotCentered;
}
@@ -201,11 +202,4 @@ void HTMLDialogElement::defaultEventHandler(Event* event)
HTMLElement::defaultEventHandler(event);
}
-bool HTMLDialogElement::shouldBeReparentedUnderRenderView(const RenderStyle* style) const
-{
- if (style && style->position() == AbsolutePosition)
- return true;
- return Element::shouldBeReparentedUnderRenderView(style);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h
index 248044e98f8..2f003c9dc95 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h
@@ -26,7 +26,6 @@
#ifndef HTMLDialogElement_h
#define HTMLDialogElement_h
-#include "RuntimeEnabledFeatures.h"
#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -37,14 +36,18 @@ class QualifiedName;
class HTMLDialogElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDialogElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDialogElement);
void close(const String& returnValue, ExceptionState&);
void closeDialog(const String& returnValue = String());
void show();
void showModal(ExceptionState&);
+ virtual void removedFrom(ContainerNode*) OVERRIDE;
- enum CenteringMode { Uninitialized, Centered, NotCentered };
+ // NotCentered means do not center the dialog. Centered means the dialog has
+ // been centered and centeredPosition() is set. NeedsCentering means attempt
+ // to center on the next layout, then set to Centered or NotCentered.
+ enum CenteringMode { NotCentered, Centered, NeedsCentering };
CenteringMode centeringMode() const { return m_centeringMode; }
LayoutUnit centeredPosition() const
{
@@ -62,7 +65,6 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual bool shouldBeReparentedUnderRenderView(const RenderStyle*) const OVERRIDE;
void forceLayoutForCentering();
@@ -71,13 +73,6 @@ private:
String m_returnValue;
};
-inline HTMLDialogElement* toHTMLDialogElement(Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->hasTagName(HTMLNames::dialogTag));
- ASSERT_WITH_SECURITY_IMPLICATION(RuntimeEnabledFeatures::dialogElementEnabled());
- return static_cast<HTMLDialogElement*>(node);
-}
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl
index 6c2d0c8c0fe..c26e3941dce 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl
@@ -28,7 +28,7 @@
] interface HTMLDialogElement : HTMLElement {
[Reflect] attribute boolean open;
attribute DOMString returnValue;
- [RaisesException] void close([Default=NullString] optional DOMString returnValue);
+ [RaisesException] void close(optional DOMString returnValue = null);
void show();
[RaisesException] void showModal();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp
index 2010c5a5178..8d739dc3d7e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLDirectoryElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,9 +35,6 @@ inline HTMLDirectoryElement::HTMLDirectoryElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDirectoryElement> HTMLDirectoryElement::create(Document& document)
-{
- return adoptRef(new HTMLDirectoryElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLDirectoryElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h
index 7c0dcaa7951..fc2a0792ef9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLDirectoryElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDirectoryElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDirectoryElement);
private:
explicit HTMLDirectoryElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp
index af3d8938783..29d4ce2f7e5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLDivElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -37,17 +37,7 @@ HTMLDivElement::HTMLDivElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDivElement> HTMLDivElement::create(Document& document)
-{
- return adoptRef(new HTMLDivElement(document));
-}
-
-bool HTMLDivElement::isPresentationAttribute(const QualifiedName& name) const
-{
- if (name == alignAttr)
- return true;
- return HTMLElement::isPresentationAttribute(name);
-}
+DEFINE_NODE_FACTORY(HTMLDivElement)
void HTMLDivElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h
index 12e230088b2..37279ed111d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h
@@ -29,18 +29,15 @@ namespace WebCore {
class HTMLDivElement : public HTMLElement {
public:
- static PassRefPtr<HTMLDivElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDivElement);
protected:
explicit HTMLDivElement(Document&);
private:
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLDivElement, hasTagName(HTMLNames::divTag));
-
} // namespace WebCore
#endif // HTMLDivElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp
index 761a6e3093a..298f8b6e91d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp
@@ -53,11 +53,11 @@
#include "config.h"
#include "core/html/HTMLDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/HTMLNames.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
@@ -73,69 +73,20 @@ HTMLDocument::HTMLDocument(const DocumentInit& initializer, DocumentClassFlags e
{
ScriptWrappable::init(this);
clearXMLVersion();
+ if (isSrcdocDocument() || initializer.importsController()) {
+ ASSERT(inNoQuirksMode());
+ lockCompatibilityMode();
+ }
}
HTMLDocument::~HTMLDocument()
{
}
-const AtomicString& HTMLDocument::dir()
-{
- HTMLElement* b = body();
- if (!b)
- return nullAtom;
- return b->getAttribute(dirAttr);
-}
-
-void HTMLDocument::setDir(const AtomicString& 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 (Element* element = treeScope().adjustedFocusedElement())
- return element;
- return body();
-}
-
-bool HTMLDocument::hasFocus()
-{
- Page* page = this->page();
- if (!page)
- return false;
- if (!page->focusController().isActive() || !page->focusController().isFocused())
- return false;
- if (Frame* focusedFrame = page->focusController().focusedFrame()) {
- if (focusedFrame->tree().isDescendantOf(frame()))
- return true;
- }
- return false;
-}
-
HTMLBodyElement* HTMLDocument::htmlBodyElement() const
{
HTMLElement* body = this->body();
- return (body && body->hasTagName(bodyTag)) ? toHTMLBodyElement(body) : 0;
+ return isHTMLBodyElement(body) ? toHTMLBodyElement(body) : 0;
}
const AtomicString& HTMLDocument::bodyAttributeValue(const QualifiedName& name) const
@@ -207,7 +158,7 @@ void HTMLDocument::setVlinkColor(const AtomicString& value)
setBodyAttribute(vlinkAttr, value);
}
-PassRefPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
+PassRefPtrWillBeRawPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
{
return create(DocumentInit(url()).withRegistrationContext(registrationContext()));
}
@@ -221,7 +172,7 @@ void HTMLDocument::addItemToMap(HashCountedSet<AtomicString>& map, const AtomicS
if (name.isEmpty())
return;
map.add(name);
- if (Frame* f = frame())
+ if (LocalFrame* f = frame())
f->script().namedItemAdded(this, name);
}
@@ -230,7 +181,7 @@ void HTMLDocument::removeItemFromMap(HashCountedSet<AtomicString>& map, const At
if (name.isEmpty())
return;
map.remove(name);
- if (Frame* f = frame())
+ if (LocalFrame* f = frame())
f->script().namedItemRemoved(this, name);
}
@@ -321,29 +272,22 @@ bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName& attributeName)
return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(attributeName.localName().impl());
}
-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.
-}
-
-void HTMLDocument::write(DOMWindow* activeWindow, const Vector<String>& text)
+void HTMLDocument::write(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
{
- ASSERT(activeWindow);
+ ASSERT(callingWindow);
StringBuilder builder;
for (size_t i = 0; i < text.size(); ++i)
builder.append(text[i]);
- write(builder.toString(), activeWindow->document());
+ write(builder.toString(), callingWindow->document(), exceptionState);
}
-void HTMLDocument::writeln(DOMWindow* activeWindow, const Vector<String>& text)
+void HTMLDocument::writeln(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
{
- ASSERT(activeWindow);
+ ASSERT(callingWindow);
StringBuilder builder;
for (size_t i = 0; i < text.size(); ++i)
builder.append(text[i]);
- writeln(builder.toString(), activeWindow->document());
+ writeln(builder.toString(), callingWindow->document(), exceptionState);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h
index aa52f77ac85..f89c1b7639f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h
@@ -35,21 +35,12 @@ class HTMLElement;
class HTMLDocument : public Document, public ResourceClient {
public:
- static PassRefPtr<HTMLDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<HTMLDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new HTMLDocument(initializer));
+ return adoptRefWillBeNoop(new HTMLDocument(initializer));
}
virtual ~HTMLDocument();
- const AtomicString& dir();
- void setDir(const AtomicString&);
-
- String designMode() const;
- void setDesignMode(const String&);
-
- Element* activeElement();
- bool hasFocus();
-
const AtomicString& bgColor() const;
void setBgColor(const AtomicString&);
const AtomicString& fgColor() const;
@@ -61,7 +52,7 @@ public:
const AtomicString& vlinkColor() const;
void setVlinkColor(const AtomicString&);
- void clear();
+ void clear() { }
void captureEvents() { }
void releaseEvents() { }
@@ -76,12 +67,12 @@ public:
using Document::write;
using Document::writeln;
- void write(DOMWindow*, const Vector<String>& text);
- void writeln(DOMWindow*, const Vector<String>& text);
+ void write(LocalDOMWindow*, const Vector<String>& text, ExceptionState&);
+ void writeln(LocalDOMWindow*, const Vector<String>& text, ExceptionState&);
static bool isCaseSensitiveAttribute(const QualifiedName&);
- virtual PassRefPtr<Document> cloneDocumentWithoutChildren() OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Document> cloneDocumentWithoutChildren() OVERRIDE FINAL;
protected:
HTMLDocument(const DocumentInit&, DocumentClassFlags extendedDocumentClasses = DefaultDocumentClass);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl
index 84328c8565f..04ba97f3187 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl
@@ -18,36 +18,30 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLDocument : Document {
+[
+ // FIXME: Oilpan: remove this once Node specifies WillBeGarbageCollected.
+ WillBeGarbageCollected
+] interface HTMLDocument : Document {
[Custom, CustomElementCallbacks] void open();
- void close();
+ [RaisesException] void close();
// We support multiple DOMString arguments to match FF / IE, e.g.:
// document.write("a", "b", "c") --> document.write("abc")
// document.write() --> document.write("")
- [CallWith=ActiveWindow, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, CustomElementCallbacks] void write(DOMString... text);
- [CallWith=ActiveWindow, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, CustomElementCallbacks] void writeln(DOMString... text);
-
- readonly attribute HTMLCollection embeds;
- [ImplementedAs=embeds] readonly attribute HTMLCollection plugins;
- readonly attribute HTMLCollection scripts;
+ [CallWith=ActiveWindow,LogActivity, CustomElementCallbacks, RaisesException] void write(DOMString... text);
+ [CallWith=ActiveWindow, LogActivity, CustomElementCallbacks, RaisesException] void writeln(DOMString... text);
// Extensions
[Replaceable, ImplementedAs=allForBinding] readonly attribute HTMLAllCollection all;
- [DeprecateAs=DocumentClear] void clear();
+ [MeasureAs=DocumentClear] void clear();
- [DeprecateAs=CaptureEvents] void captureEvents();
- [DeprecateAs=ReleaseEvents] void releaseEvents();
+ [MeasureAs=DocumentCaptureEvents] void captureEvents();
+ [MeasureAs=DocumentReleaseEvents] void releaseEvents();
- [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString dir;
- [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString designMode;
readonly attribute DOMString compatMode;
- readonly attribute Element activeElement;
- boolean hasFocus();
-
// Deprecated attributes
[TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString bgColor;
[TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString fgColor;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp
index 8fcff5b5bfb..6a64bc4b5b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp
@@ -25,35 +25,34 @@
#include "config.h"
#include "core/html/HTMLElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNames.h"
+#include "core/css/CSSMarkup.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Text.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/markup.h"
#include "core/events/EventListener.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLTemplateElement.h"
#include "core/html/HTMLTextFormControlElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
-#include "core/rendering/RenderWordBreak.h"
+#include "core/rendering/RenderObject.h"
#include "platform/text/BidiResolver.h"
+#include "platform/text/BidiTextRun.h"
#include "platform/text/TextRunIterator.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/CString.h"
@@ -66,18 +65,18 @@ using namespace WTF;
using std::min;
using std::max;
-PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLElement);
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();
+ if (document().isHTMLDocument()) {
+ if (!tagQName().hasPrefix())
+ return tagQName().localNameUpper();
+ return Element::nodeName().upper();
+ }
return Element::nodeName();
}
@@ -101,7 +100,6 @@ bool HTMLElement::ieForbidsInsertHTML() const
|| hasLocalName(imageTag)
|| hasLocalName(imgTag)
|| hasLocalName(inputTag)
- || hasLocalName(isindexTag)
|| hasLocalName(linkTag)
|| hasLocalName(metaTag)
|| hasLocalName(paramTag)
@@ -204,95 +202,102 @@ void HTMLElement::collectStyleForPresentationAttribute(const QualifiedName& name
Element::collectStyleForPresentationAttribute(name, value, style);
}
-const AtomicString& HTMLElement::eventNameForAttributeName(const QualifiedName& attrName) const
+const AtomicString& HTMLElement::eventNameForAttributeName(const QualifiedName& attrName)
{
if (!attrName.namespaceURI().isNull())
return nullAtom;
+ if (!attrName.localName().startsWith("on", false))
+ return nullAtom;
+
typedef HashMap<AtomicString, AtomicString> StringToStringMap;
DEFINE_STATIC_LOCAL(StringToStringMap, attributeNameToEventNameMap, ());
if (!attributeNameToEventNameMap.size()) {
- attributeNameToEventNameMap.set(onanimationstartAttr.localName(), EventTypeNames::animationstart);
- attributeNameToEventNameMap.set(onanimationiterationAttr.localName(), EventTypeNames::animationiteration);
+ attributeNameToEventNameMap.set(onabortAttr.localName(), EventTypeNames::abort);
attributeNameToEventNameMap.set(onanimationendAttr.localName(), EventTypeNames::animationend);
+ attributeNameToEventNameMap.set(onanimationiterationAttr.localName(), EventTypeNames::animationiteration);
+ attributeNameToEventNameMap.set(onanimationstartAttr.localName(), EventTypeNames::animationstart);
+ attributeNameToEventNameMap.set(onautocompleteAttr.localName(), EventTypeNames::autocomplete);
+ attributeNameToEventNameMap.set(onautocompleteerrorAttr.localName(), EventTypeNames::autocompleteerror);
+ attributeNameToEventNameMap.set(onbeforecopyAttr.localName(), EventTypeNames::beforecopy);
+ attributeNameToEventNameMap.set(onbeforecutAttr.localName(), EventTypeNames::beforecut);
+ attributeNameToEventNameMap.set(onbeforepasteAttr.localName(), EventTypeNames::beforepaste);
+ attributeNameToEventNameMap.set(onblurAttr.localName(), EventTypeNames::blur);
attributeNameToEventNameMap.set(oncancelAttr.localName(), EventTypeNames::cancel);
+ attributeNameToEventNameMap.set(oncanplayAttr.localName(), EventTypeNames::canplay);
+ attributeNameToEventNameMap.set(oncanplaythroughAttr.localName(), EventTypeNames::canplaythrough);
+ attributeNameToEventNameMap.set(onchangeAttr.localName(), EventTypeNames::change);
attributeNameToEventNameMap.set(onclickAttr.localName(), EventTypeNames::click);
attributeNameToEventNameMap.set(oncloseAttr.localName(), EventTypeNames::close);
attributeNameToEventNameMap.set(oncontextmenuAttr.localName(), EventTypeNames::contextmenu);
- attributeNameToEventNameMap.set(ondblclickAttr.localName(), EventTypeNames::dblclick);
- attributeNameToEventNameMap.set(onmousedownAttr.localName(), EventTypeNames::mousedown);
- attributeNameToEventNameMap.set(onmouseenterAttr.localName(), EventTypeNames::mouseenter);
- attributeNameToEventNameMap.set(onmouseleaveAttr.localName(), EventTypeNames::mouseleave);
- attributeNameToEventNameMap.set(onmousemoveAttr.localName(), EventTypeNames::mousemove);
- attributeNameToEventNameMap.set(onmouseoutAttr.localName(), EventTypeNames::mouseout);
- attributeNameToEventNameMap.set(onmouseoverAttr.localName(), EventTypeNames::mouseover);
- attributeNameToEventNameMap.set(onmouseupAttr.localName(), EventTypeNames::mouseup);
- attributeNameToEventNameMap.set(onmousewheelAttr.localName(), EventTypeNames::mousewheel);
- attributeNameToEventNameMap.set(onwheelAttr.localName(), EventTypeNames::wheel);
- attributeNameToEventNameMap.set(onfocusAttr.localName(), EventTypeNames::focus);
- attributeNameToEventNameMap.set(onfocusinAttr.localName(), EventTypeNames::focusin);
- attributeNameToEventNameMap.set(onfocusoutAttr.localName(), EventTypeNames::focusout);
- attributeNameToEventNameMap.set(onblurAttr.localName(), EventTypeNames::blur);
- attributeNameToEventNameMap.set(onkeydownAttr.localName(), EventTypeNames::keydown);
- attributeNameToEventNameMap.set(onkeypressAttr.localName(), EventTypeNames::keypress);
- attributeNameToEventNameMap.set(onkeyupAttr.localName(), EventTypeNames::keyup);
- attributeNameToEventNameMap.set(onscrollAttr.localName(), EventTypeNames::scroll);
- attributeNameToEventNameMap.set(onbeforecutAttr.localName(), EventTypeNames::beforecut);
- attributeNameToEventNameMap.set(oncutAttr.localName(), EventTypeNames::cut);
- attributeNameToEventNameMap.set(onbeforecopyAttr.localName(), EventTypeNames::beforecopy);
attributeNameToEventNameMap.set(oncopyAttr.localName(), EventTypeNames::copy);
- attributeNameToEventNameMap.set(onbeforepasteAttr.localName(), EventTypeNames::beforepaste);
- attributeNameToEventNameMap.set(onpasteAttr.localName(), EventTypeNames::paste);
+ attributeNameToEventNameMap.set(oncuechangeAttr.localName(), EventTypeNames::cuechange);
+ attributeNameToEventNameMap.set(oncutAttr.localName(), EventTypeNames::cut);
+ attributeNameToEventNameMap.set(ondblclickAttr.localName(), EventTypeNames::dblclick);
+ attributeNameToEventNameMap.set(ondragAttr.localName(), EventTypeNames::drag);
+ attributeNameToEventNameMap.set(ondragendAttr.localName(), EventTypeNames::dragend);
attributeNameToEventNameMap.set(ondragenterAttr.localName(), EventTypeNames::dragenter);
- attributeNameToEventNameMap.set(ondragoverAttr.localName(), EventTypeNames::dragover);
attributeNameToEventNameMap.set(ondragleaveAttr.localName(), EventTypeNames::dragleave);
- attributeNameToEventNameMap.set(ondropAttr.localName(), EventTypeNames::drop);
+ attributeNameToEventNameMap.set(ondragoverAttr.localName(), EventTypeNames::dragover);
attributeNameToEventNameMap.set(ondragstartAttr.localName(), EventTypeNames::dragstart);
- attributeNameToEventNameMap.set(ondragAttr.localName(), EventTypeNames::drag);
- attributeNameToEventNameMap.set(ondragendAttr.localName(), EventTypeNames::dragend);
- attributeNameToEventNameMap.set(onselectstartAttr.localName(), EventTypeNames::selectstart);
- attributeNameToEventNameMap.set(onsubmitAttr.localName(), EventTypeNames::submit);
- attributeNameToEventNameMap.set(onerrorAttr.localName(), EventTypeNames::error);
- attributeNameToEventNameMap.set(onwebkitanimationstartAttr.localName(), EventTypeNames::webkitAnimationStart);
- attributeNameToEventNameMap.set(onwebkitanimationiterationAttr.localName(), EventTypeNames::webkitAnimationIteration);
- attributeNameToEventNameMap.set(onwebkitanimationendAttr.localName(), EventTypeNames::webkitAnimationEnd);
- attributeNameToEventNameMap.set(onwebkittransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
- attributeNameToEventNameMap.set(ontransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
- attributeNameToEventNameMap.set(oninputAttr.localName(), EventTypeNames::input);
- attributeNameToEventNameMap.set(oninvalidAttr.localName(), EventTypeNames::invalid);
- attributeNameToEventNameMap.set(ontouchstartAttr.localName(), EventTypeNames::touchstart);
- attributeNameToEventNameMap.set(ontouchmoveAttr.localName(), EventTypeNames::touchmove);
- attributeNameToEventNameMap.set(ontouchendAttr.localName(), EventTypeNames::touchend);
- attributeNameToEventNameMap.set(ontouchcancelAttr.localName(), EventTypeNames::touchcancel);
- attributeNameToEventNameMap.set(onwebkitfullscreenchangeAttr.localName(), EventTypeNames::webkitfullscreenchange);
- attributeNameToEventNameMap.set(onwebkitfullscreenerrorAttr.localName(), EventTypeNames::webkitfullscreenerror);
- attributeNameToEventNameMap.set(onabortAttr.localName(), EventTypeNames::abort);
- attributeNameToEventNameMap.set(oncanplayAttr.localName(), EventTypeNames::canplay);
- attributeNameToEventNameMap.set(oncanplaythroughAttr.localName(), EventTypeNames::canplaythrough);
- attributeNameToEventNameMap.set(onchangeAttr.localName(), EventTypeNames::change);
- attributeNameToEventNameMap.set(oncuechangeAttr.localName(), EventTypeNames::cuechange);
+ attributeNameToEventNameMap.set(ondropAttr.localName(), EventTypeNames::drop);
attributeNameToEventNameMap.set(ondurationchangeAttr.localName(), EventTypeNames::durationchange);
attributeNameToEventNameMap.set(onemptiedAttr.localName(), EventTypeNames::emptied);
attributeNameToEventNameMap.set(onendedAttr.localName(), EventTypeNames::ended);
+ attributeNameToEventNameMap.set(onerrorAttr.localName(), EventTypeNames::error);
+ attributeNameToEventNameMap.set(onfocusAttr.localName(), EventTypeNames::focus);
+ attributeNameToEventNameMap.set(onfocusinAttr.localName(), EventTypeNames::focusin);
+ attributeNameToEventNameMap.set(onfocusoutAttr.localName(), EventTypeNames::focusout);
+ attributeNameToEventNameMap.set(oninputAttr.localName(), EventTypeNames::input);
+ attributeNameToEventNameMap.set(oninvalidAttr.localName(), EventTypeNames::invalid);
+ attributeNameToEventNameMap.set(onkeydownAttr.localName(), EventTypeNames::keydown);
+ attributeNameToEventNameMap.set(onkeypressAttr.localName(), EventTypeNames::keypress);
+ attributeNameToEventNameMap.set(onkeyupAttr.localName(), EventTypeNames::keyup);
+ attributeNameToEventNameMap.set(onloadAttr.localName(), EventTypeNames::load);
attributeNameToEventNameMap.set(onloadeddataAttr.localName(), EventTypeNames::loadeddata);
attributeNameToEventNameMap.set(onloadedmetadataAttr.localName(), EventTypeNames::loadedmetadata);
attributeNameToEventNameMap.set(onloadstartAttr.localName(), EventTypeNames::loadstart);
+ attributeNameToEventNameMap.set(onmousedownAttr.localName(), EventTypeNames::mousedown);
+ attributeNameToEventNameMap.set(onmouseenterAttr.localName(), EventTypeNames::mouseenter);
+ attributeNameToEventNameMap.set(onmouseleaveAttr.localName(), EventTypeNames::mouseleave);
+ attributeNameToEventNameMap.set(onmousemoveAttr.localName(), EventTypeNames::mousemove);
+ attributeNameToEventNameMap.set(onmouseoutAttr.localName(), EventTypeNames::mouseout);
+ attributeNameToEventNameMap.set(onmouseoverAttr.localName(), EventTypeNames::mouseover);
+ attributeNameToEventNameMap.set(onmouseupAttr.localName(), EventTypeNames::mouseup);
+ attributeNameToEventNameMap.set(onmousewheelAttr.localName(), EventTypeNames::mousewheel);
+ attributeNameToEventNameMap.set(onpasteAttr.localName(), EventTypeNames::paste);
attributeNameToEventNameMap.set(onpauseAttr.localName(), EventTypeNames::pause);
attributeNameToEventNameMap.set(onplayAttr.localName(), EventTypeNames::play);
attributeNameToEventNameMap.set(onplayingAttr.localName(), EventTypeNames::playing);
attributeNameToEventNameMap.set(onprogressAttr.localName(), EventTypeNames::progress);
attributeNameToEventNameMap.set(onratechangeAttr.localName(), EventTypeNames::ratechange);
attributeNameToEventNameMap.set(onresetAttr.localName(), EventTypeNames::reset);
+ attributeNameToEventNameMap.set(onresizeAttr.localName(), EventTypeNames::resize);
+ attributeNameToEventNameMap.set(onscrollAttr.localName(), EventTypeNames::scroll);
attributeNameToEventNameMap.set(onseekedAttr.localName(), EventTypeNames::seeked);
attributeNameToEventNameMap.set(onseekingAttr.localName(), EventTypeNames::seeking);
attributeNameToEventNameMap.set(onselectAttr.localName(), EventTypeNames::select);
+ attributeNameToEventNameMap.set(onselectstartAttr.localName(), EventTypeNames::selectstart);
attributeNameToEventNameMap.set(onshowAttr.localName(), EventTypeNames::show);
attributeNameToEventNameMap.set(onstalledAttr.localName(), EventTypeNames::stalled);
+ attributeNameToEventNameMap.set(onsubmitAttr.localName(), EventTypeNames::submit);
attributeNameToEventNameMap.set(onsuspendAttr.localName(), EventTypeNames::suspend);
attributeNameToEventNameMap.set(ontimeupdateAttr.localName(), EventTypeNames::timeupdate);
+ attributeNameToEventNameMap.set(ontoggleAttr.localName(), EventTypeNames::toggle);
+ attributeNameToEventNameMap.set(ontouchcancelAttr.localName(), EventTypeNames::touchcancel);
+ attributeNameToEventNameMap.set(ontouchendAttr.localName(), EventTypeNames::touchend);
+ attributeNameToEventNameMap.set(ontouchmoveAttr.localName(), EventTypeNames::touchmove);
+ attributeNameToEventNameMap.set(ontouchstartAttr.localName(), EventTypeNames::touchstart);
+ attributeNameToEventNameMap.set(ontransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
attributeNameToEventNameMap.set(onvolumechangeAttr.localName(), EventTypeNames::volumechange);
attributeNameToEventNameMap.set(onwaitingAttr.localName(), EventTypeNames::waiting);
- attributeNameToEventNameMap.set(onloadAttr.localName(), EventTypeNames::load);
+ attributeNameToEventNameMap.set(onwebkitanimationendAttr.localName(), EventTypeNames::webkitAnimationEnd);
+ attributeNameToEventNameMap.set(onwebkitanimationiterationAttr.localName(), EventTypeNames::webkitAnimationIteration);
+ attributeNameToEventNameMap.set(onwebkitanimationstartAttr.localName(), EventTypeNames::webkitAnimationStart);
+ attributeNameToEventNameMap.set(onwebkitfullscreenchangeAttr.localName(), EventTypeNames::webkitfullscreenchange);
+ attributeNameToEventNameMap.set(onwebkitfullscreenerrorAttr.localName(), EventTypeNames::webkitfullscreenerror);
+ attributeNameToEventNameMap.set(onwebkittransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
+ attributeNameToEventNameMap.set(onwheelAttr.localName(), EventTypeNames::wheel);
}
return attributeNameToEventNameMap.get(attrName.localName());
@@ -300,37 +305,24 @@ const AtomicString& HTMLElement::eventNameForAttributeName(const QualifiedName&
void HTMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (isIdAttributeName(name) || name == classAttr || name == styleAttr)
+ if (name == tabindexAttr)
return Element::parseAttribute(name, value);
- if (name == dirAttr)
+ if (name == dirAttr) {
dirAttributeChanged(value);
- else if (name == tabindexAttr) {
- int tabindex = 0;
- if (value.isEmpty()) {
- clearTabIndexExplicitlyIfNeeded();
- if (treeScope().adjustedFocusedElement() == this) {
- // We might want to call blur(), but it's dangerous to dispatch
- // events here.
- document().setNeedsFocusedElementCheck();
- }
- } else if (parseHTMLInteger(value, 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 {
const AtomicString& eventName = eventNameForAttributeName(name);
if (!eventName.isNull())
- setAttributeEventListener(eventName, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(eventName, createAttributeEventListener(this, name, value, eventParameterName()));
}
}
-PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionState& exceptionState)
{
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
- unsigned int i, length = text.length();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document());
+ unsigned i, length = text.length();
UChar c = 0;
- for (unsigned int start = 0; start < length; ) {
+ for (unsigned start = 0; start < length; ) {
// Find next line break.
for (i = start; i < length; i++) {
@@ -341,12 +333,12 @@ PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, Exc
fragment->appendChild(Text::create(document(), text.substring(start, i - start)), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (c == '\r' || c == '\n') {
fragment->appendChild(HTMLBRElement::create(document()), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
// Make sure \r\n doesn't result in two line breaks.
if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
i++;
@@ -400,7 +392,7 @@ void HTMLElement::setInnerText(const String& text, ExceptionState& exceptionStat
}
// Add text nodes and <br> elements.
- RefPtr<DocumentFragment> fragment = textToFragment(text, exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = textToFragment(text, exceptionState);
if (!exceptionState.hadException())
replaceChildrenWithFragment(this, fragment.release(), exceptionState);
}
@@ -425,9 +417,9 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
return;
}
- RefPtr<Node> prev = previousSibling();
- RefPtr<Node> next = nextSibling();
- RefPtr<Node> newChild;
+ RefPtrWillBeRawPtr<Node> prev = previousSibling();
+ RefPtrWillBeRawPtr<Node> next = nextSibling();
+ RefPtrWillBeRawPtr<Node> newChild = nullptr;
// Convert text to fragment with <br> tags instead of linebreaks if needed.
if (text.contains('\r') || text.contains('\n'))
@@ -436,7 +428,7 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
newChild = Text::create(document(), text);
// textToFragment might cause mutation events.
- if (!this || !parentNode())
+ if (!parentNode())
exceptionState.throwDOMException(HierarchyRequestError, "The element has no parent.");
if (exceptionState.hadException())
@@ -444,7 +436,7 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
parent->replaceChild(newChild.release(), this, exceptionState);
- RefPtr<Node> node = next ? next->previousSibling() : 0;
+ RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : nullptr;
if (!exceptionState.hadException() && node && node->isTextNode())
mergeWithNextTextNode(node.release(), exceptionState);
@@ -452,24 +444,6 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
mergeWithNextTextNode(prev.release(), exceptionState);
}
-Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChild, ExceptionState& exceptionState)
-{
- if (!newChild) {
- // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative.
- exceptionState.throwTypeError("The node provided is null.");
- return 0;
- }
-
- Node* returnValue = insertAdjacent(where, newChild, exceptionState);
- return toElement(returnValue);
-}
-
-void HTMLElement::insertAdjacentText(const String& where, const String& text, ExceptionState& exceptionState)
-{
- RefPtr<Text> textNode = document().createTextNode(text);
- insertAdjacent(where, textNode.get(), exceptionState);
-}
-
void HTMLElement::applyAlignmentAttributeToStyle(const AtomicString& alignment, MutableStylePropertySet* style)
{
// Vertical alignment with respect to the current baseline of the text
@@ -510,33 +484,6 @@ bool HTMLElement::hasCustomFocusLogic() const
return false;
}
-bool HTMLElement::supportsSpatialNavigationFocus() const
-{
- // This function checks whether the element satisfies the extended criteria
- // for the element to be focusable, introduced by spatial navigation feature,
- // i.e. checks if click or keyboard event handler is specified.
- // This is the way to make it possible to navigate to (focus) elements
- // which web designer meant for being active (made them respond to click events).
-
- if (!document().settings() || !document().settings()->spatialNavigationEnabled())
- return false;
- return hasEventListeners(EventTypeNames::click)
- || hasEventListeners(EventTypeNames::keydown)
- || hasEventListeners(EventTypeNames::keypress)
- || hasEventListeners(EventTypeNames::keyup);
-}
-
-bool HTMLElement::supportsFocus() const
-{
- // FIXME: supportsFocus() can be called when layout is not up to date.
- // Logic that deals with the renderer should be moved to rendererIsFocusable().
- // But supportsFocus must return true when the element is editable, or else
- // it won't be focusable. Furthermore, supportsFocus cannot just return true
- // always or else tabIndex() will change for all HTML elements.
- return Element::supportsFocus() || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable())
- || supportsSpatialNavigationFocus();
-}
-
String HTMLElement::contentEditable() const
{
const AtomicString& value = fastGetAttribute(contenteditableAttr);
@@ -600,7 +547,7 @@ void HTMLElement::accessKeyAction(bool sendMouseEvents)
String HTMLElement::title() const
{
- return getAttribute(titleAttr);
+ return fastGetAttribute(titleAttr);
}
short HTMLElement::tabIndex() const
@@ -610,11 +557,6 @@ short HTMLElement::tabIndex() const
return -1;
}
-void HTMLElement::setTabIndex(int value)
-{
- setIntegralAttribute(tabindexAttr, value);
-}
-
TranslateAttributeMode HTMLElement::translateAttributeMode() const
{
const AtomicString& value = getAttribute(translateAttr);
@@ -631,13 +573,11 @@ TranslateAttributeMode HTMLElement::translateAttributeMode() const
bool HTMLElement::translate() const
{
- for (const Node* n = this; n; n = n->parentNode()) {
- if (n->isHTMLElement()) {
- TranslateAttributeMode mode = toHTMLElement(n)->translateAttributeMode();
- if (mode != TranslateAttributeInherit) {
- ASSERT(mode == TranslateAttributeYes || mode == TranslateAttributeNo);
- return mode == TranslateAttributeYes;
- }
+ for (const HTMLElement* element = this; element; element = Traversal<HTMLElement>::firstAncestor(*element)) {
+ TranslateAttributeMode mode = element->translateAttributeMode();
+ if (mode != TranslateAttributeInherit) {
+ ASSERT(mode == TranslateAttributeYes || mode == TranslateAttributeNo);
+ return mode == TranslateAttributeYes;
}
}
@@ -650,39 +590,43 @@ void HTMLElement::setTranslate(bool enable)
setAttribute(translateAttr, enable ? "yes" : "no");
}
-bool HTMLElement::rendererIsNeeded(const RenderStyle& style)
+// Returns the conforming 'dir' value associated with the state the attribute is in (in its canonical case), if any,
+// or the empty string if the attribute is in a state that has no associated keyword value or if the attribute is
+// not in a defined state (e.g. the attribute is missing and there is no missing value default).
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#limited-to-only-known-values
+static inline const AtomicString& toValidDirValue(const AtomicString& value)
{
- if (hasLocalName(noscriptTag)) {
- Frame* frame = document().frame();
- if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
- return false;
- } else if (hasLocalName(noembedTag)) {
- Frame* frame = document().frame();
- if (frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
- return false;
- }
- return Element::rendererIsNeeded(style);
+ DEFINE_STATIC_LOCAL(const AtomicString, ltrValue, ("ltr", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, rtlValue, ("rtl", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, autoValue, ("auto", AtomicString::ConstructFromLiteral));
+
+ if (equalIgnoringCase(value, ltrValue))
+ return ltrValue;
+ if (equalIgnoringCase(value, rtlValue))
+ return rtlValue;
+ if (equalIgnoringCase(value, autoValue))
+ return autoValue;
+ return nullAtom;
+}
+
+const AtomicString& HTMLElement::dir()
+{
+ return toValidDirValue(fastGetAttribute(dirAttr));
}
-RenderObject* HTMLElement::createRenderer(RenderStyle* style)
+void HTMLElement::setDir(const AtomicString& value)
{
- if (hasLocalName(wbrTag))
- return new RenderWordBreak(this);
- return RenderObject::createObject(this, style);
+ setAttribute(dirAttr, value);
}
HTMLFormElement* HTMLElement::findFormAncestor() const
{
- for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(formTag))
- return toHTMLFormElement(ancestor);
- }
- return 0;
+ return Traversal<HTMLFormElement>::firstAncestor(*this);
}
static inline bool elementAffectsDirectionality(const Node* node)
{
- return node->isHTMLElement() && (node->hasTagName(bdiTag) || toHTMLElement(node)->hasAttribute(dirAttr));
+ return node->isHTMLElement() && (isHTMLBDIElement(*node) || toHTMLElement(node)->hasAttribute(dirAttr));
}
static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastNode = 0)
@@ -692,9 +636,6 @@ static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastN
Node* node = firstNode->firstChild();
while (node) {
- if (node->selfOrAncestorHasDirAutoAttribute() == flag)
- return;
-
if (elementAffectsDirectionality(node)) {
if (node == lastNode)
return;
@@ -717,7 +658,7 @@ void HTMLElement::childrenChanged(bool changedByParser, Node* beforeChange, Node
bool HTMLElement::hasDirectionAuto() const
{
const AtomicString& direction = fastGetAttribute(dirAttr);
- return (hasTagName(bdiTag) && direction == nullAtom) || equalIgnoringCase(direction, "auto");
+ return (isHTMLBDIElement(*this) && direction == nullAtom) || equalIgnoringCase(direction, "auto");
}
TextDirection HTMLElement::directionalityIfhasDirAutoAttribute(bool& isAuto) const
@@ -731,18 +672,9 @@ TextDirection HTMLElement::directionalityIfhasDirAutoAttribute(bool& isAuto) con
return directionality();
}
-static TextDirection determineDirectionality(const String& value, bool& hasStrongDirectionality)
-{
- TextRun run(value);
- BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
- bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride()));
- bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0));
- return bidiResolver.determineParagraphDirectionality(&hasStrongDirectionality);
-}
-
TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) const
{
- if (hasTagName(inputTag)) {
+ if (isHTMLInputElement(*this)) {
HTMLInputElement* inputElement = toHTMLInputElement(const_cast<HTMLElement*>(this));
bool hasStrongDirectionality;
TextDirection textDirection = determineDirectionality(inputElement->value(), hasStrongDirectionality);
@@ -754,7 +686,7 @@ TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) c
Node* node = firstChild();
while (node) {
// Skip bdi, script, style and text form controls.
- if (equalIgnoringCase(node->nodeName(), "bdi") || node->hasTagName(scriptTag) || node->hasTagName(styleTag)
+ if (equalIgnoringCase(node->nodeName(), "bdi") || isHTMLScriptElement(*node) || isHTMLStyleElement(*node)
|| (node->isElementNode() && toElement(node)->isTextFormControl())) {
node = NodeTraversal::nextSkippingChildren(*node, this);
continue;
@@ -806,7 +738,7 @@ void HTMLElement::adjustDirectionalityIfNeededAfterChildAttributeChanged(Element
Element* elementToAdjust = this;
for (; elementToAdjust; elementToAdjust = elementToAdjust->parentElement()) {
if (elementAffectsDirectionality(elementToAdjust)) {
- elementToAdjust->setNeedsStyleRecalc();
+ elementToAdjust->setNeedsStyleRecalc(SubtreeStyleChange);
return;
}
}
@@ -817,14 +749,16 @@ void HTMLElement::calculateAndAdjustDirectionality()
{
Node* strongDirectionalityTextNode;
TextDirection textDirection = directionality(&strongDirectionalityTextNode);
- setHasDirAutoFlagRecursively(this, true, strongDirectionalityTextNode);
+ setHasDirAutoFlagRecursively(this, hasDirectionAuto(), strongDirectionalityTextNode);
+ for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
+ setHasDirAutoFlagRecursively(root, hasDirectionAuto());
if (renderer() && renderer()->style() && renderer()->style()->direction() != textDirection)
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Node* beforeChange, int childCountDelta)
{
- if (document().renderer() && childCountDelta < 0) {
+ if (document().renderView() && childCountDelta < 0) {
Node* node = beforeChange ? NodeTraversal::nextSkippingChildren(*beforeChange) : 0;
for (int counter = 0; node && counter < childCountDelta; counter++, node = NodeTraversal::nextSkippingChildren(*node)) {
if (elementAffectsDirectionality(node))
@@ -859,25 +793,25 @@ void HTMLElement::addHTMLLengthToStyle(MutableStylePropertySet* style, CSSProper
// strip attribute garbage..
StringImpl* v = value.impl();
if (v) {
- unsigned int l = 0;
+ unsigned length = 0;
- while (l < v->length() && (*v)[l] <= ' ')
- l++;
+ while (length < v->length() && (*v)[length] <= ' ')
+ length++;
- for (; l < v->length(); l++) {
- UChar cc = (*v)[l];
+ for (; length < v->length(); length++) {
+ UChar cc = (*v)[length];
if (cc > '9')
break;
if (cc < '0') {
if (cc == '%' || cc == '*')
- l++;
+ length++;
if (cc != '.')
break;
}
}
- if (l != v->length()) {
- addPropertyToPresentationAttributeStyle(style, propertyID, v->substring(0, l));
+ if (length != v->length()) {
+ addPropertyToPresentationAttributeStyle(style, propertyID, v->substring(0, length));
return;
}
}
@@ -955,8 +889,8 @@ void HTMLElement::addHTMLColorToStyle(MutableStylePropertySet* style, CSSPropert
return;
// If the string is a named CSS color or a 3/6-digit hex color, use that.
- Color parsedColor(colorString);
- if (!parsedColor.isValid())
+ Color parsedColor;
+ if (!parsedColor.setFromString(colorString))
parsedColor.setRGB(parseColorStringWithCrazyLegacyRules(colorString));
style->setProperty(propertyID, cssValuePool().createColorValue(parsedColor.rgb()));
@@ -978,6 +912,26 @@ void HTMLElement::defaultEventHandler(Event* event)
Element::defaultEventHandler(event);
}
+bool HTMLElement::matchesReadOnlyPseudoClass() const
+{
+ return !matchesReadWritePseudoClass();
+}
+
+bool HTMLElement::matchesReadWritePseudoClass() const
+{
+ if (fastHasAttribute(contenteditableAttr)) {
+ const AtomicString& value = fastGetAttribute(contenteditableAttr);
+
+ if (value.isEmpty() || equalIgnoringCase(value, "true") || equalIgnoringCase(value, "plaintext-only"))
+ return true;
+ if (equalIgnoringCase(value, "false"))
+ return false;
+ // All other values should be treated as "inherit".
+ }
+
+ return parentElement() && parentElement()->rendererIsEditable();
+}
+
void HTMLElement::handleKeypressEvent(KeyboardEvent* event)
{
if (!document().settings() || !document().settings()->spatialNavigationEnabled() || !supportsFocus())
@@ -994,6 +948,12 @@ void HTMLElement::handleKeypressEvent(KeyboardEvent* event)
}
}
+const AtomicString& HTMLElement::eventParameterName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, eventString, ("event", AtomicString::ConstructFromLiteral));
+ return eventString;
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLElement.h
index ef4736aa9bc..492555175a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLElement.h
@@ -40,21 +40,15 @@ enum TranslateAttributeMode {
class HTMLElement : public Element {
public:
- static PassRefPtr<HTMLElement> create(const QualifiedName& tagName, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLElement);
virtual String title() const OVERRIDE FINAL;
-
- virtual short tabIndex() const;
- void setTabIndex(int);
+ virtual short tabIndex() const OVERRIDE;
void setInnerText(const String&, ExceptionState&);
void setOuterText(const String&, ExceptionState&);
- Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionState&);
- void insertAdjacentText(const String& where, const String& text, ExceptionState&);
-
virtual bool hasCustomFocusLogic() const;
- virtual bool supportsFocus() const;
String contentEditable() const;
void setContentEditable(const String&, ExceptionState&);
@@ -68,15 +62,15 @@ public:
bool translate() const;
void setTranslate(bool);
+ const AtomicString& dir();
+ void setDir(const AtomicString&);
+
void click();
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
bool ieForbidsInsertHTML() const;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
-
virtual HTMLFormElement* formOwner() const { return 0; }
HTMLFormElement* findFormAncestor() const;
@@ -85,12 +79,20 @@ public:
TextDirection directionalityIfhasDirAutoAttribute(bool& isAuto) const;
virtual bool isHTMLUnknownElement() const { return false; }
+ virtual bool isPluginElement() const { return false; }
virtual bool isLabelable() const { return false; }
// http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#interactive-content
virtual bool isInteractiveContent() const;
virtual void defaultEventHandler(Event*) OVERRIDE;
+ static const AtomicString& eventNameForAttributeName(const QualifiedName& attrName);
+
+ virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
+ virtual bool matchesReadWritePseudoClass() const OVERRIDE;
+
+ static const AtomicString& eventParameterName();
+
protected:
HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
@@ -105,7 +107,7 @@ protected:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
unsigned parseBorderWidthAttribute(const AtomicString&) const;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
void calculateAndAdjustDirectionality();
private:
@@ -113,7 +115,7 @@ private:
void mapLanguageAttributeToLocale(const AtomicString&, MutableStylePropertySet*);
- PassRefPtr<DocumentFragment> textToFragment(const String&, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> textToFragment(const String&, ExceptionState&);
void dirAttributeChanged(const AtomicString&);
void adjustDirectionalityIfNeededAfterChildAttributeChanged(Element* child);
@@ -122,13 +124,14 @@ private:
TranslateAttributeMode translateAttributeMode() const;
- const AtomicString& eventNameForAttributeName(const QualifiedName& attrName) const;
-
void handleKeypressEvent(KeyboardEvent*);
- bool supportsSpatialNavigationFocus() const;
};
-DEFINE_NODE_TYPE_CASTS(HTMLElement, isHTMLElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLElement, isHTMLElement());
+
+template <> inline bool isElementOfType<const HTMLElement>(const Node& node) { return node.isHTMLElement(); }
+template <typename T> bool isElementOfType(const HTMLElement&);
+template <> inline bool isElementOfType<const HTMLElement>(const HTMLElement&) { return true; }
inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document, ConstructionType type = CreateHTMLElement)
: Element(tagName, &document, type)
@@ -137,6 +140,22 @@ inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document
ScriptWrappable::init(this);
}
+// This requires isHTML*Element(const Element&) and isHTML*Element(const HTMLElement&).
+// When the input element is an HTMLElement, we don't need to check the namespace URI, just the local name.
+#define DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
+ inline bool is##thisType(const thisType* element); \
+ inline bool is##thisType(const thisType& element); \
+ inline bool is##thisType(const HTMLElement* element) { return element && is##thisType(*element); } \
+ inline bool is##thisType(const Element* element) { return element && is##thisType(*element); } \
+ inline bool is##thisType(const Node& node) { return node.isElementNode() ? is##thisType(toElement(node)) : false; } \
+ inline bool is##thisType(const Node* node) { return node && node->isElementNode() ? is##thisType(*toElement(node)) : false; } \
+ template<typename T> inline bool is##thisType(const PassRefPtr<T>& node) { return is##thisType(node.get()); } \
+ template<typename T> inline bool is##thisType(const RefPtr<T>& node) { return is##thisType(node.get()); } \
+ template <> inline bool isElementOfType<const thisType>(const HTMLElement& element) { return is##thisType(element); } \
+ DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType)
+
} // namespace WebCore
+#include "core/HTMLElementTypeHelpers.h"
+
#endif // HTMLElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl
index 5d065681ee8..65e7cb26ae9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl
@@ -24,7 +24,7 @@
[Reflect] attribute DOMString title;
[Reflect] attribute DOMString lang;
attribute boolean translate;
- [Reflect] attribute DOMString dir;
+ attribute DOMString dir;
[CustomElementCallbacks] attribute long tabIndex;
[CustomElementCallbacks] attribute boolean draggable;
@@ -36,11 +36,6 @@
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute DOMString innerText;
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute DOMString outerText;
- [RaisesException, CustomElementCallbacks, MeasureAs=InsertAdjacentElement] Element insertAdjacentElement([Default=Undefined] optional DOMString where,
- [Default=Undefined] optional Element element);
- [RaisesException, MeasureAs=InsertAdjacentText] void insertAdjacentText([Default=Undefined] optional DOMString where,
- [Default=Undefined] optional DOMString text);
-
[RuntimeEnabled=IMEAPI] readonly attribute InputMethodContext inputMethodContext;
[CustomElementCallbacks, RaisesException=Setter] attribute DOMString contentEditable;
@@ -52,3 +47,4 @@
};
HTMLElement implements GlobalEventHandlers;
+
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
index c6bde0181e1..99e3467a03f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "core/html/HTMLEmbedElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLImageLoader.h"
@@ -45,9 +45,9 @@ inline HTMLEmbedElement::HTMLEmbedElement(Document& document, bool createdByPars
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool createdByParser)
{
- RefPtr<HTMLEmbedElement> element = adoptRef(new HTMLEmbedElement(document, createdByParser));
+ RefPtrWillBeRawPtr<HTMLEmbedElement> element = adoptRefWillBeNoop(new HTMLEmbedElement(document, createdByParser));
element->ensureUserAgentShadowRoot();
return element.release();
}
@@ -55,9 +55,7 @@ PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool c
static inline RenderWidget* findWidgetRenderer(const Node* n)
{
if (!n->renderer())
- do
- n = n->parentNode();
- while (n && !n->hasTagName(objectTag));
+ n = Traversal<HTMLObjectElement>::firstAncestor(*n);
if (n && n->renderer() && n->renderer()->isWidget())
return toRenderWidget(n->renderer());
@@ -96,13 +94,15 @@ void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicStr
size_t pos = m_serviceType.find(";");
if (pos != kNotFound)
m_serviceType = m_serviceType.left(pos);
+ if (!renderer())
+ requestPluginCreationWithoutRendererIfPossible();
} else if (name == codeAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
} else if (name == srcAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
if (renderer() && isImageType()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElementIgnoringPreviousError();
}
} else {
@@ -115,10 +115,11 @@ void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<St
if (!hasAttributes())
return;
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- paramNames.append(attribute->localName().string());
- paramValues.append(attribute->value().string());
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ paramNames.append(it->localName().string());
+ paramValues.append(it->value().string());
}
}
@@ -143,21 +144,12 @@ void HTMLEmbedElement::updateWidgetInternal()
Vector<String> paramValues;
parametersForPlugin(paramNames, paramValues);
- RefPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
- bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(m_url);
- 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;
- }
- if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
+ RefPtrWillBeRawPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
+
+ // FIXME: Can we not have renderer here now that beforeload events are gone?
+ if (!renderer())
return;
- // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
requestObject(m_url, m_serviceType, paramNames, paramValues);
}
@@ -166,14 +158,14 @@ bool HTMLEmbedElement::rendererIsNeeded(const RenderStyle& style)
if (isImageType())
return HTMLPlugInElement::rendererIsNeeded(style);
- Frame* frame = document().frame();
+ LocalFrame* 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)) {
+ if (isHTMLObjectElement(p)) {
ASSERT(p->renderer());
if (!toHTMLObjectElement(p)->useFallbackContent()) {
ASSERT(!p->renderer()->isEmbeddedObject());
@@ -188,16 +180,14 @@ bool HTMLEmbedElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLPlugInElement::isURLAttribute(attribute);
}
-const AtomicString HTMLEmbedElement::imageSourceURL() const
+const QualifiedName& HTMLEmbedElement::subResourceAttributeName() const
{
- return getAttribute(srcAttr);
+ return srcAttr;
}
-void HTMLEmbedElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+const AtomicString HTMLEmbedElement::imageSourceURL() const
{
- HTMLPlugInElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(srcAttr)));
+ return getAttribute(srcAttr);
}
bool HTMLEmbedElement::isInteractiveContent() const
@@ -208,8 +198,8 @@ bool HTMLEmbedElement::isInteractiveContent() const
bool HTMLEmbedElement::isExposed() const
{
// http://www.whatwg.org/specs/web-apps/current-work/#exposed
- for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(objectTag) && toHTMLObjectElement(ancestor)->isExposed())
+ for (HTMLObjectElement* object = Traversal<HTMLObjectElement>::firstAncestor(*this); object; object = Traversal<HTMLObjectElement>::firstAncestor(*object)) {
+ if (object->isExposed())
return false;
}
return true;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h
index 8107fd188f2..becba85d94c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLEmbedElement FINAL : public HTMLPlugInElement {
public:
- static PassRefPtr<HTMLEmbedElement> create(Document&, bool createdByParser = false);
+ static PassRefPtrWillBeRawPtr<HTMLEmbedElement> create(Document&, bool createdByParser = false);
bool isExposed() const;
@@ -40,25 +40,22 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
virtual RenderWidget* existingRenderWidget() const OVERRIDE;
virtual void updateWidgetInternal() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues);
virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLEmbedElement, hasTagName(HTMLNames::embedTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
index 74524f3ec05..399417d8c00 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
@@ -24,7 +24,7 @@
[Reflect] attribute DOMString align;
[Reflect] attribute DOMString height;
[Reflect] attribute DOMString name;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly, LogPreviousValue] attribute DOMString src;
[Reflect] attribute DOMString type;
[Reflect] attribute DOMString width;
[Custom, NotEnumerable] getter boolean (unsigned long index);
@@ -32,5 +32,7 @@
[Custom, NotEnumerable] getter Node (DOMString name);
[Custom] setter Node (DOMString name, Node value);
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
index bf568d1417c..54f6d7bbb93 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
@@ -25,9 +25,10 @@
#include "config.h"
#include "core/html/HTMLFieldSetElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLCollection.h"
+#include "core/html/HTMLFormControlsCollection.h"
#include "core/html/HTMLLegendElement.h"
#include "core/html/HTMLObjectElement.h"
#include "core/rendering/RenderFieldset.h"
@@ -44,9 +45,17 @@ inline HTMLFieldSetElement::HTMLFieldSetElement(Document& document, HTMLFormElem
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLFieldSetElement(document, form));
+ return adoptRefWillBeNoop(new HTMLFieldSetElement(document, form));
+}
+
+void HTMLFieldSetElement::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_associatedElements);
+#endif
+ HTMLFormControlElement::trace(visitor);
}
void HTMLFieldSetElement::invalidateDisabledStateUnder(Element& base)
@@ -67,10 +76,8 @@ void HTMLFieldSetElement::disabledAttributeChanged()
void HTMLFieldSetElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::nextSkippingChildren(*element, this)) {
- if (element->hasTagName(legendTag))
- invalidateDisabledStateUnder(*element);
- }
+ for (HTMLLegendElement* legend = Traversal<HTMLLegendElement>::firstChild(*this); legend; legend = Traversal<HTMLLegendElement>::nextSibling(*legend))
+ invalidateDisabledStateUnder(*legend);
}
bool HTMLFieldSetElement::supportsFocus() const
@@ -91,16 +98,12 @@ RenderObject* HTMLFieldSetElement::createRenderer(RenderStyle*)
HTMLLegendElement* HTMLFieldSetElement::legend() const
{
- for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSkippingChildren(*child, this)) {
- if (child->hasTagName(legendTag))
- return toHTMLLegendElement(child);
- }
- return 0;
+ return Traversal<HTMLLegendElement>::firstChild(*this);
}
-PassRefPtr<HTMLCollection> HTMLFieldSetElement::elements()
+PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> HTMLFieldSetElement::elements()
{
- return ensureCachedHTMLCollection(FormControls);
+ return toHTMLFormControlsCollection(ensureCachedHTMLCollection(FormControls).get());
}
void HTMLFieldSetElement::refreshElementsIfNeeded() const
@@ -113,8 +116,8 @@ void HTMLFieldSetElement::refreshElementsIfNeeded() const
m_associatedElements.clear();
- for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
- if (element->hasTagName(objectTag)) {
+ for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(*this); element; element = Traversal<HTMLElement>::next(*element, this)) {
+ if (isHTMLObjectElement(*element)) {
m_associatedElements.append(toHTMLObjectElement(element));
continue;
}
@@ -126,20 +129,10 @@ void HTMLFieldSetElement::refreshElementsIfNeeded() const
}
}
-const Vector<FormAssociatedElement*>& HTMLFieldSetElement::associatedElements() const
+const FormAssociatedElement::List& HTMLFieldSetElement::associatedElements() const
{
refreshElementsIfNeeded();
return m_associatedElements;
}
-unsigned HTMLFieldSetElement::length() const
-{
- refreshElementsIfNeeded();
- unsigned len = 0;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- if (m_associatedElements[i]->isEnumeratable())
- ++len;
- return len;
-}
-
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
index e0835449cdf..bb6da9e2bc1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
@@ -30,16 +30,17 @@ namespace WebCore {
class FormAssociatedElement;
class HTMLCollection;
+class HTMLFormControlsCollection;
class HTMLFieldSetElement FINAL : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLFieldSetElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLFieldSetElement> create(Document&, HTMLFormElement*);
+ virtual void trace(Visitor*) OVERRIDE;
HTMLLegendElement* legend() const;
- PassRefPtr<HTMLCollection> elements();
+ PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> elements();
- const Vector<FormAssociatedElement*>& associatedElements() const;
- unsigned length() const;
+ const FormAssociatedElement::List& associatedElements() const;
protected:
virtual void disabledAttributeChanged() OVERRIDE;
@@ -47,24 +48,22 @@ protected:
private:
HTMLFieldSetElement(Document&, HTMLFormElement*);
- virtual bool isEnumeratable() const { return true; }
- virtual bool supportsFocus() const;
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual const AtomicString& formControlType() const;
- virtual bool recalcWillValidate() const { return false; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
+ virtual bool supportsFocus() const OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual const AtomicString& formControlType() const OVERRIDE;
+ virtual bool recalcWillValidate() const OVERRIDE { return false; }
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
static void invalidateDisabledStateUnder(Element&);
void refreshElementsIfNeeded() const;
- mutable Vector<FormAssociatedElement*> m_associatedElements;
+ mutable FormAssociatedElement::List m_associatedElements;
// When dom tree is modified, we have to refresh the m_associatedElements array.
mutable uint64_t m_documentVersion;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFieldSetElement, hasTagName(HTMLNames::fieldsetTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp
index 853eae4a786..3f808f855d1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLFontElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSValueList.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
@@ -38,16 +38,13 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLFontElement::HTMLFontElement(Document& document)
+inline HTMLFontElement::HTMLFontElement(Document& document)
: HTMLElement(fontTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFontElement> HTMLFontElement::create(Document& document)
-{
- return adoptRef(new HTMLFontElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLFontElement)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors
template <typename CharacterType>
@@ -193,7 +190,7 @@ void HTMLFontElement::collectStyleForPresentationAttribute(const QualifiedName&
} else if (name == colorAttr)
addHTMLColorToStyle(style, CSSPropertyColor, value);
else if (name == faceAttr) {
- if (RefPtr<CSSValueList> fontFaceValue = cssValuePool().createFontFaceValue(value))
+ if (RefPtrWillBeRawPtr<CSSValueList> fontFaceValue = cssValuePool().createFontFaceValue(value))
style->setProperty(CSSProperty(CSSPropertyFontFamily, fontFaceValue.release()));
} else
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h
index 229c5c94896..e0f542cfb76 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLFontElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLFontElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLFontElement);
static bool cssValueFromFontSizeNumber(const String&, CSSValueID&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
index 4c68907eaf4..d3d3b22cbcb 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
@@ -25,14 +25,12 @@
#include "config.h"
#include "core/html/HTMLFormControlElement.h"
-#include "core/dom/PostAttachCallbacks.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLLegendElement.h"
-#include "core/html/HTMLTextAreaElement.h"
#include "core/html/ValidityState.h"
#include "core/html/forms/ValidationMessage.h"
#include "core/frame/UseCounter.h"
@@ -43,7 +41,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
: LabelableElement(tagName, document)
@@ -51,7 +48,6 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
, m_isAutofilled(false)
, m_isReadOnly(false)
, m_isRequired(false)
- , m_valueMatchesRenderer(false)
, m_ancestorDisabledState(AncestorDisabledStateUnknown)
, m_dataListAncestorState(Unknown)
, m_willValidateInitialized(false)
@@ -59,15 +55,22 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
, m_isValid(true)
, m_wasChangedSinceLastFormControlChangeEvent(false)
, m_wasFocusedByMouse(false)
- , m_hasAutofocused(false)
{
- setForm(form ? form : findFormAncestor());
setHasCustomStyleCallbacks();
+ associateByParser(form);
}
HTMLFormControlElement::~HTMLFormControlElement()
{
+#if !ENABLE(OILPAN)
setForm(0);
+#endif
+}
+
+void HTMLFormControlElement::trace(Visitor* visitor)
+{
+ FormAssociatedElement::trace(visitor);
+ LabelableElement::trace(visitor);
}
String HTMLFormControlElement::formEnctype() const
@@ -105,10 +108,10 @@ void HTMLFormControlElement::updateAncestorDisabledState() const
{
HTMLFieldSetElement* fieldSetAncestor = 0;
ContainerNode* legendAncestor = 0;
- for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (!legendAncestor && ancestor->hasTagName(legendTag))
+ for (HTMLElement* ancestor = Traversal<HTMLElement>::firstAncestor(*this); ancestor; ancestor = Traversal<HTMLElement>::firstAncestor(*ancestor)) {
+ if (!legendAncestor && isHTMLLegendElement(*ancestor))
legendAncestor = ancestor;
- if (ancestor->hasTagName(fieldsetTag)) {
+ if (isHTMLFieldSetElement(*ancestor)) {
fieldSetAncestor = toHTMLFieldSetElement(ancestor);
break;
}
@@ -143,9 +146,9 @@ void HTMLFormControlElement::parseAttribute(const QualifiedName& name, const Ato
m_isReadOnly = !value.isNull();
if (wasReadOnly != m_isReadOnly) {
setNeedsWillValidateCheck();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), ReadOnlyState);
+ RenderTheme::theme().stateChanged(renderer(), ReadOnlyControlState);
}
} else if (name == requiredAttr) {
bool wasRequired = m_isRequired;
@@ -165,7 +168,7 @@ void HTMLFormControlElement::disabledAttributeChanged()
setNeedsWillValidateCheck();
didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), EnabledState);
+ RenderTheme::theme().stateChanged(renderer(), EnabledControlState);
if (isDisabledFormControl() && treeScope().adjustedFocusedElement() == this) {
// We might want to call blur(), but it's dangerous to dispatch events
// here.
@@ -178,33 +181,17 @@ void HTMLFormControlElement::requiredAttributeChanged()
setNeedsValidityCheck();
// Style recalculation is needed because style selectors may include
// :required and :optional pseudo-classes.
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
-static void focusPostAttach(Node* element)
+bool HTMLFormControlElement::supportsAutofocus() const
{
- toElement(element)->focus();
- element->deref();
+ return false;
}
bool HTMLFormControlElement::isAutofocusable() const
{
- if (!fastHasAttribute(autofocusAttr))
- return false;
-
- // FIXME: Should this set of hasTagName checks be replaced by a
- // virtual member function?
- if (hasTagName(inputTag))
- return !toHTMLInputElement(this)->isInputTypeHidden();
- if (hasTagName(selectTag))
- return true;
- if (hasTagName(keygenTag))
- return true;
- if (hasTagName(buttonTag))
- return true;
- if (isHTMLTextAreaElement(this))
- return true;
- return false;
+ return fastHasAttribute(autofocusAttr) && supportsAutofocus();
}
void HTMLFormControlElement::setAutofilled(bool autofilled)
@@ -213,15 +200,13 @@ void HTMLFormControlElement::setAutofilled(bool autofilled)
return;
m_isAutofilled = autofilled;
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
static bool shouldAutofocusOnAttach(const HTMLFormControlElement* element)
{
if (!element->isAutofocusable())
return false;
- if (element->hasAutofocused())
- return false;
if (element->document().isSandboxed(SandboxAutomaticFeatures)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
element->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked autofocusing on a form control because the form's frame is sandboxed and the 'allow-scripts' permission is not set.");
@@ -243,11 +228,10 @@ void HTMLFormControlElement::attach(const AttachContext& context)
// on the renderer.
renderer()->updateFromElement();
- if (shouldAutofocusOnAttach(this)) {
- setAutofocused();
- ref();
- PostAttachCallbacks::queueCallback(focusPostAttach, this);
- }
+ // FIXME: Autofocus handling should be moved to insertedInto according to
+ // the standard.
+ if (shouldAutofocusOnAttach(this))
+ document().setAutofocusElement(this);
}
void HTMLFormControlElement::didMoveToNewDocument(Document& oldDocument)
@@ -268,6 +252,7 @@ Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Containe
void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint)
{
+ hideVisibleValidationMessage();
m_validationMessage = nullptr;
m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown;
@@ -275,19 +260,19 @@ void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint)
FormAssociatedElement::removedFrom(insertionPoint);
}
-bool HTMLFormControlElement::wasChangedSinceLastFormControlChangeEvent() const
+void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
{
- return m_wasChangedSinceLastFormControlChangeEvent;
+ m_wasChangedSinceLastFormControlChangeEvent = changed;
}
-void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
+void HTMLFormControlElement::dispatchChangeEvent()
{
- m_wasChangedSinceLastFormControlChangeEvent = changed;
+ dispatchScopedEvent(Event::createBubble(EventTypeNames::change));
}
void HTMLFormControlElement::dispatchFormControlChangeEvent()
{
- HTMLElement::dispatchChangeEvent();
+ dispatchChangeEvent();
setChangedSinceLastFormControlChangeEvent(false);
}
@@ -322,20 +307,10 @@ String HTMLFormControlElement::resultForDialogSubmit()
return fastGetAttribute(valueAttr);
}
-static void updateFromElementCallback(Node* node)
-{
- ASSERT_ARG(node, node->isElementNode());
- ASSERT_ARG(node, toElement(node)->isFormControlElement());
- if (RenderObject* renderer = node->renderer())
- renderer->updateFromElement();
-}
-
void HTMLFormControlElement::didRecalcStyle(StyleRecalcChange)
{
- // updateFromElement() can cause the selection to change, and in turn
- // trigger synchronous layout, so it must not be called during style recalc.
- if (renderer())
- PostAttachCallbacks::queueCallback(updateFromElementCallback, this);
+ if (RenderObject* renderer = this->renderer())
+ renderer->updateFromElement();
}
bool HTMLFormControlElement::supportsFocus() const
@@ -354,11 +329,11 @@ bool HTMLFormControlElement::shouldShowFocusRingOnMouseFocus() const
return false;
}
-void HTMLFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
{
- if (direction != FocusDirectionPage)
- m_wasFocusedByMouse = direction == FocusDirectionMouse;
- HTMLElement::dispatchFocusEvent(oldFocusedElement, direction);
+ if (type != FocusTypePage)
+ m_wasFocusedByMouse = type == FocusTypeMouse;
+ HTMLElement::dispatchFocusEvent(oldFocusedElement, type);
}
bool HTMLFormControlElement::shouldHaveFocusAppearance() const
@@ -375,7 +350,7 @@ void HTMLFormControlElement::willCallDefaultEventHandler(const Event& event)
return;
m_wasFocusedByMouse = false;
if (renderer())
- renderer()->repaint();
+ renderer()->paintInvalidationForWholeRenderer();
}
@@ -388,13 +363,9 @@ short HTMLFormControlElement::tabIndex() const
bool HTMLFormControlElement::recalcWillValidate() const
{
if (m_dataListAncestorState == Unknown) {
- for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(datalistTag)) {
- m_dataListAncestorState = InsideDataList;
- break;
- }
- }
- if (m_dataListAncestorState == Unknown)
+ if (Traversal<HTMLDataListElement>::firstAncestor(*this))
+ m_dataListAncestorState = InsideDataList;
+ else
m_dataListAncestorState = NotInsideDataList;
}
return m_dataListAncestorState == NotInsideDataList && !isDisabledOrReadOnly();
@@ -427,7 +398,7 @@ void HTMLFormControlElement::setNeedsWillValidateCheck()
m_willValidateInitialized = true;
m_willValidate = newWillValidate;
setNeedsValidityCheck();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (!m_willValidate)
hideVisibleValidationMessage();
}
@@ -451,15 +422,13 @@ void HTMLFormControlElement::hideVisibleValidationMessage()
m_validationMessage->requestToHideMessage();
}
-bool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls, CheckValidityDispatchEvents dispatchEvents)
+bool HTMLFormControlElement::checkValidity(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >* unhandledInvalidControls)
{
if (!willValidate() || isValidFormControlElement())
return true;
- if (dispatchEvents == CheckValidityDispatchEventsNone)
- return false;
// An event handler can deref this object.
- RefPtr<HTMLFormControlElement> protector(this);
- RefPtr<Document> originalDocument(document());
+ RefPtrWillBeRawPtr<HTMLFormControlElement> protector(this);
+ RefPtrWillBeRawPtr<Document> originalDocument(document());
bool needsDefaultAction = dispatchEvent(Event::createCancelable(EventTypeNames::invalid));
if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument == document())
unhandledInvalidControls->append(this);
@@ -479,11 +448,11 @@ void HTMLFormControlElement::setNeedsValidityCheck()
bool newIsValid = valid();
if (willValidate() && newIsValid != m_isValid) {
// Update style for pseudo classes such as :valid :invalid.
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
m_isValid = newIsValid;
- // Updates only if this control already has a validtion message.
+ // Updates only if this control already has a validation message.
if (m_validationMessage && m_validationMessage->isVisible()) {
// Calls updateVisibleValidationMessage() even if m_isValid is not
// changed because a validation message can be chagned.
@@ -515,11 +484,9 @@ bool HTMLFormControlElement::isDefaultButtonForForm() const
HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node* node)
{
- for (; node; node = node->parentNode()) {
- if (node->isElementNode() && toElement(node)->isFormControlElement())
- return toHTMLFormControlElement(node);
- }
- return 0;
+ if (!node)
+ return 0;
+ return Traversal<HTMLFormControlElement>::firstAncestorOrSelf(*node);
}
String HTMLFormControlElement::nameForAutofill() const
@@ -533,4 +500,12 @@ String HTMLFormControlElement::nameForAutofill() const
return trimmedName;
}
+void HTMLFormControlElement::setFocus(bool flag)
+{
+ LabelableElement::setFocus(flag);
+
+ if (!flag && wasChangedSinceLastFormControlChangeEvent())
+ dispatchFormControlChangeEvent();
+}
+
} // namespace Webcore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
index bb5cdd8c8a2..eae67074b0b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
@@ -40,8 +40,11 @@ class ValidityState;
// and form-associated element implementations should use HTMLFormControlElement
// unless there is a special reason.
class HTMLFormControlElement : public LabelableElement, public FormAssociatedElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLFormControlElement);
+
public:
virtual ~HTMLFormControlElement();
+ virtual void trace(Visitor*) OVERRIDE;
String formEnctype() const;
void setFormEnctype(const AtomicString&);
@@ -53,32 +56,30 @@ public:
void reset();
- virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
- virtual void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
-
- virtual bool wasChangedSinceLastFormControlChangeEvent() const;
- virtual void setChangedSinceLastFormControlChangeEvent(bool);
+ bool wasChangedSinceLastFormControlChangeEvent() const { return m_wasChangedSinceLastFormControlChangeEvent; }
+ void setChangedSinceLastFormControlChangeEvent(bool);
virtual void dispatchFormControlChangeEvent();
- virtual void dispatchFormControlInputEvent();
+ void dispatchChangeEvent();
+ void dispatchFormControlInputEvent();
- virtual HTMLFormElement* formOwner() const OVERRIDE;
+ virtual HTMLFormElement* formOwner() const OVERRIDE FINAL;
virtual bool isDisabledFormControl() const OVERRIDE;
- virtual bool isEnumeratable() const { return false; }
+ virtual bool isEnumeratable() const OVERRIDE { return false; }
bool isRequired() const;
const AtomicString& type() const { return formControlType(); }
- virtual const AtomicString& formControlType() const OVERRIDE = 0;
+ virtual const AtomicString& formControlType() const = 0;
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 appendFormData(FormDataList&, bool) OVERRIDE { return false; }
virtual String resultForDialogSubmit();
virtual bool canBeSuccessfulSubmitButton() const { return false; }
@@ -86,21 +87,17 @@ public:
virtual bool isActivatedSubmit() const { return false; }
virtual void setActivatedSubmit(bool) { }
- enum CheckValidityDispatchEvents { CheckValidityDispatchEventsAllowed, CheckValidityDispatchEventsNone };
-
- virtual bool willValidate() const;
+ virtual bool willValidate() const OVERRIDE;
void updateVisibleValidationMessage();
void hideVisibleValidationMessage();
- bool checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls = 0, CheckValidityDispatchEvents = CheckValidityDispatchEventsAllowed);
+ bool checkValidity(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >* unhandledInvalidControls = 0);
// This must be called when a validation constraint or control value is changed.
void setNeedsValidityCheck();
- virtual void setCustomValidity(const String&) OVERRIDE;
+ virtual void setCustomValidity(const String&) OVERRIDE FINAL;
bool isReadOnly() const { return m_isReadOnly; }
bool isDisabledOrReadOnly() const { return isDisabledFormControl() || m_isReadOnly; }
- bool hasAutofocused() const { return m_hasAutofocused; }
- void setAutofocused() { m_hasAutofocused = true; }
bool isAutofocusable() const;
bool isAutofilled() const { return m_isAutofilled; }
@@ -110,8 +107,12 @@ public:
String nameForAutofill() const;
+ virtual void setFocus(bool flag) OVERRIDE;
+
+#if !ENABLE(OILPAN)
using Node::ref;
using Node::deref;
+#endif
protected:
HTMLFormControlElement(const QualifiedName& tagName, Document&, HTMLFormElement*);
@@ -127,30 +128,33 @@ protected:
virtual bool supportsFocus() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
virtual bool shouldShowFocusRingOnMouseFocus() const;
- virtual bool shouldHaveFocusAppearance() const OVERRIDE;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
+ virtual bool shouldHaveFocusAppearance() const OVERRIDE FINAL;
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE;
virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE;
- virtual void willCallDefaultEventHandler(const Event&) OVERRIDE;
+ virtual void willCallDefaultEventHandler(const Event&) OVERRIDE FINAL;
- virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE FINAL;
// This must be called any time the result of willValidate() has changed.
void setNeedsWillValidateCheck();
virtual bool recalcWillValidate() const;
virtual void resetImpl() { }
+ virtual bool supportsAutofocus() const;
private:
- virtual void refFormAssociatedElement() { ref(); }
- virtual void derefFormAssociatedElement() { deref(); }
+#if !ENABLE(OILPAN)
+ virtual void refFormAssociatedElement() OVERRIDE FINAL { ref(); }
+ virtual void derefFormAssociatedElement() OVERRIDE FINAL { deref(); }
+#endif
- virtual bool isFormControlElement() const { return true; }
+ virtual bool isFormControlElement() const OVERRIDE FINAL { return true; }
virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return true; }
- virtual short tabIndex() const;
+ virtual short tabIndex() const OVERRIDE FINAL;
- virtual bool isDefaultButtonForForm() const;
- virtual bool isValidFormControlElement();
+ virtual bool isDefaultButtonForForm() const OVERRIDE FINAL;
+ virtual bool isValidFormControlElement() OVERRIDE FINAL;
void updateAncestorDisabledState() const;
OwnPtr<ValidationMessage> m_validationMessage;
@@ -158,7 +162,6 @@ private:
bool m_isAutofilled : 1;
bool m_isReadOnly : 1;
bool m_isRequired : 1;
- bool m_valueMatchesRenderer : 1;
enum AncestorDisabledState { AncestorDisabledStateUnknown, AncestorDisabledStateEnabled, AncestorDisabledStateDisabled };
mutable AncestorDisabledState m_ancestorDisabledState;
@@ -177,15 +180,14 @@ private:
bool m_wasChangedSinceLastFormControlChangeEvent : 1;
bool m_wasFocusedByMouse : 1;
- bool m_hasAutofocused : 1;
};
-inline bool isHTMLFormControlElement(const Node& node)
+inline bool isHTMLFormControlElement(const Element& element)
{
- return node.isElementNode() && toElement(node).isFormControlElement();
+ return element.isFormControlElement();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
DEFINE_TYPE_CASTS(HTMLFormControlElement, FormAssociatedElement, control, control->isFormControlElement(), control.isFormControlElement());
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
index 1508d798f18..23375e1dd90 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
@@ -25,12 +25,13 @@
#include "config.h"
#include "core/html/HTMLFormControlElementWithState.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/forms/FormController.h"
+#include "core/loader/FrameLoaderClient.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
namespace WebCore {
@@ -46,14 +47,14 @@ HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
Node::InsertionNotificationRequest HTMLFormControlElementWithState::insertedInto(ContainerNode* insertionPoint)
{
if (insertionPoint->inDocument() && !containingShadowRoot())
- document().formController()->registerFormElementWithState(this);
+ document().formController().registerStatefulFormControl(*this);
return HTMLFormControlElement::insertedInto(insertionPoint);
}
void HTMLFormControlElementWithState::removedFrom(ContainerNode* insertionPoint)
{
if (insertionPoint->inDocument() && !containingShadowRoot() && !insertionPoint->containingShadowRoot())
- document().formController()->unregisterFormElementWithState(this);
+ document().formController().unregisterStatefulFormControl(*this);
HTMLFormControlElement::removedFrom(insertionPoint);
}
@@ -66,18 +67,17 @@ bool HTMLFormControlElementWithState::shouldAutocomplete() const
void HTMLFormControlElementWithState::notifyFormStateChanged()
{
- Frame* frame = document().frame();
- if (!frame)
+ // This can be called during fragment parsing as a result of option
+ // selection before the document is active (or even in a frame).
+ if (!document().isActive())
return;
-
- if (Page* page = frame->page())
- page->chrome().client().formStateDidChange(this);
+ document().frame()->loader().client()->didUpdateCurrentHistoryItem();
}
bool HTMLFormControlElementWithState::shouldSaveAndRestoreFormControlState() const
{
// We don't save/restore control state in a form with autocomplete=off.
- return inActiveDocument() && shouldAutocomplete();
+ return inDocument() && shouldAutocomplete();
}
FormControlState HTMLFormControlElementWithState::saveFormControlState() const
@@ -88,7 +88,7 @@ FormControlState HTMLFormControlElementWithState::saveFormControlState() const
void HTMLFormControlElementWithState::finishParsingChildren()
{
HTMLFormControlElement::finishParsingChildren();
- document().formController()->restoreControlStateFor(*this);
+ document().formController().restoreControlStateFor(*this);
}
bool HTMLFormControlElementWithState::isFormControlElementWithState() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
index 0328920e53a..d81fd207d69 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
@@ -34,8 +34,9 @@ class HTMLFormControlElementWithState : public HTMLFormControlElement {
public:
virtual ~HTMLFormControlElementWithState();
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return false; }
+ virtual bool shouldAutocomplete() const;
virtual bool shouldSaveAndRestoreFormControlState() const;
virtual FormControlState saveFormControlState() const;
// The specified FormControlState must have at least one string value.
@@ -45,11 +46,10 @@ public:
protected:
HTMLFormControlElementWithState(const QualifiedName& tagName, Document&, HTMLFormElement*);
- virtual bool shouldAutocomplete() const;
- virtual void finishParsingChildren();
+ virtual void finishParsingChildren() OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool isFormControlElementWithState() const OVERRIDE;
+ virtual bool isFormControlElementWithState() const OVERRIDE FINAL;
};
DEFINE_TYPE_CASTS(HTMLFormControlElementWithState, FormAssociatedElement, control, control->isFormControlElementWithState(), control.isFormControlElementWithState());
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp
index 972bb757c54..a7c4a9fecb9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,10 +24,12 @@
#include "config.h"
#include "core/html/HTMLFormControlsCollection.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLImageElement.h"
+#include "wtf/HashSet.h"
namespace WebCore {
@@ -35,53 +38,80 @@ using namespace HTMLNames;
// Since the collections are to be "live", we have to do the
// calculation every time if anything has changed.
-HTMLFormControlsCollection::HTMLFormControlsCollection(Node* ownerNode)
+HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode& ownerNode)
: HTMLCollection(ownerNode, FormControls, OverridesItemAfter)
+ , m_cachedElement(nullptr)
+ , m_cachedElementOffsetInArray(0)
{
- ASSERT(ownerNode->hasTagName(formTag) || ownerNode->hasTagName(fieldsetTag));
+ ASSERT(isHTMLFormElement(ownerNode) || isHTMLFieldSetElement(ownerNode));
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(Node* ownerNode, CollectionType)
+PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode& ownerNode, CollectionType type)
{
- return adoptRef(new HTMLFormControlsCollection(ownerNode));
+ ASSERT_UNUSED(type, type == FormControls);
+ return adoptRefWillBeNoop(new HTMLFormControlsCollection(ownerNode));
}
HTMLFormControlsCollection::~HTMLFormControlsCollection()
{
}
-const Vector<FormAssociatedElement*>& HTMLFormControlsCollection::formControlElements() const
+const FormAssociatedElement::List& HTMLFormControlsCollection::formControlElements() const
{
- ASSERT(ownerNode());
- ASSERT(ownerNode()->hasTagName(formTag) || ownerNode()->hasTagName(fieldsetTag));
- if (ownerNode()->hasTagName(formTag))
- return toHTMLFormElement(ownerNode())->associatedElements();
- return toHTMLFieldSetElement(ownerNode())->associatedElements();
+ ASSERT(isHTMLFormElement(ownerNode()) || isHTMLFieldSetElement(ownerNode()));
+ if (isHTMLFormElement(ownerNode()))
+ return toHTMLFormElement(ownerNode()).associatedElements();
+ return toHTMLFieldSetElement(ownerNode()).associatedElements();
}
-const Vector<HTMLImageElement*>& HTMLFormControlsCollection::formImageElements() const
+const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& HTMLFormControlsCollection::formImageElements() const
{
- ASSERT(ownerNode());
- return toHTMLFormElement(ownerNode())->imageElements();
+ return toHTMLFormElement(ownerNode()).imageElements();
}
-Element* HTMLFormControlsCollection::virtualItemAfter(unsigned& offset, Element* previousItem) const
+static unsigned findFormAssociatedElement(const FormAssociatedElement::List& associatedElements, Element* element)
{
- const Vector<FormAssociatedElement*>& elementsArray = formControlElements();
- if (previousItem)
- offset++;
- while (offset < elementsArray.size()) {
- FormAssociatedElement* element = elementsArray[offset];
- if (element->isEnumeratable())
- return toHTMLElement(element);
- offset++;
+ unsigned i = 0;
+ for (; i < associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = associatedElements[i];
+ if (associatedElement->isEnumeratable() && toHTMLElement(associatedElement) == element)
+ break;
+ }
+ return i;
+}
+
+Element* HTMLFormControlsCollection::virtualItemAfter(Element* previous) const
+{
+ const FormAssociatedElement::List& associatedElements = formControlElements();
+ unsigned offset;
+ if (!previous)
+ offset = 0;
+ else if (m_cachedElement == previous)
+ offset = m_cachedElementOffsetInArray + 1;
+ else
+ offset = findFormAssociatedElement(associatedElements, previous) + 1;
+
+ for (unsigned i = offset; i < associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = associatedElements[i];
+ if (associatedElement->isEnumeratable()) {
+ m_cachedElement = toHTMLElement(associatedElement);
+ m_cachedElementOffsetInArray = i;
+ return m_cachedElement;
+ }
}
return 0;
}
-static HTMLElement* firstNamedItem(const Vector<FormAssociatedElement*>& elementsArray,
- const Vector<HTMLImageElement*>* imageElementsArray, const QualifiedName& attrName, const String& name)
+void HTMLFormControlsCollection::invalidateCache(Document* oldDocument) const
+{
+ HTMLCollection::invalidateCache(oldDocument);
+ m_cachedElement = nullptr;
+ m_cachedElementOffsetInArray = 0;
+}
+
+static HTMLElement* firstNamedItem(const FormAssociatedElement::List& elementsArray,
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >* imageElementsArray, const QualifiedName& attrName, const String& name)
{
ASSERT(attrName == idAttr || attrName == nameAttr);
@@ -96,35 +126,38 @@ static HTMLElement* firstNamedItem(const Vector<FormAssociatedElement*>& element
for (unsigned i = 0; i < imageElementsArray->size(); ++i) {
HTMLImageElement* element = (*imageElementsArray)[i];
- if (element->fastGetAttribute(attrName) == name)
+ if (element->fastGetAttribute(attrName) == name) {
+ UseCounter::count(element->document(), UseCounter::FormNameAccessForImageElement);
return element;
+ }
}
return 0;
}
-Node* HTMLFormControlsCollection::namedItem(const AtomicString& name) const
+Element* HTMLFormControlsCollection::namedItem(const AtomicString& name) const
{
// http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
// This method first searches for an object with a matching id
// attribute. If a match is not found, the method then searches for an
// object with a matching name attribute, but only on those elements
// that are allowed a name attribute.
- const Vector<HTMLImageElement*>* imagesElements = ownerNode()->hasTagName(fieldsetTag) ? 0 : &formImageElements();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >* imagesElements = isHTMLFieldSetElement(ownerNode()) ? 0 : &formImageElements();
if (HTMLElement* item = firstNamedItem(formControlElements(), imagesElements, idAttr, name))
return item;
return firstNamedItem(formControlElements(), imagesElements, nameAttr, name);
}
-void HTMLFormControlsCollection::updateNameCache() const
+void HTMLFormControlsCollection::updateIdNameCache() const
{
- if (hasNameCache())
+ if (hasValidIdNameCache())
return;
+ OwnPtrWillBeRawPtr<NamedItemCache> cache = NamedItemCache::create();
HashSet<StringImpl*> foundInputElements;
- const Vector<FormAssociatedElement*>& elementsArray = formControlElements();
+ const FormAssociatedElement::List& elementsArray = formControlElements();
for (unsigned i = 0; i < elementsArray.size(); ++i) {
FormAssociatedElement* associatedElement = elementsArray[i];
@@ -133,48 +166,82 @@ void HTMLFormControlsCollection::updateNameCache() const
const AtomicString& idAttrVal = element->getIdAttribute();
const AtomicString& nameAttrVal = element->getNameAttribute();
if (!idAttrVal.isEmpty()) {
- appendIdCache(idAttrVal, element);
+ cache->addElementWithId(idAttrVal, element);
foundInputElements.add(idAttrVal.impl());
}
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
- appendNameCache(nameAttrVal, element);
+ cache->addElementWithName(nameAttrVal, element);
foundInputElements.add(nameAttrVal.impl());
}
}
}
- if (ownerNode()->hasTagName(formTag)) {
- const Vector<HTMLImageElement*>& imageElementsArray = formImageElements();
+ if (isHTMLFormElement(ownerNode())) {
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& imageElementsArray = formImageElements();
for (unsigned i = 0; i < imageElementsArray.size(); ++i) {
HTMLImageElement* element = imageElementsArray[i];
const AtomicString& idAttrVal = element->getIdAttribute();
const AtomicString& nameAttrVal = element->getNameAttribute();
if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl()))
- appendIdCache(idAttrVal, element);
+ cache->addElementWithId(idAttrVal, element);
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl()))
- appendNameCache(nameAttrVal, element);
+ cache->addElementWithName(nameAttrVal, element);
}
}
- setHasNameCache();
+ // Set the named item cache last as traversing the tree may cause cache invalidation.
+ setNamedItemCache(cache.release());
}
-void HTMLFormControlsCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<RadioNodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLFormControlsCollection::namedGetter(const AtomicString& name, bool& radioNodeListEnabled, RefPtrWillBeRawPtr<RadioNodeList>& radioNodeList, bool& elementEnabled, RefPtrWillBeRawPtr<Element>& element)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
this->namedItems(name, namedItems);
- if (!namedItems.size())
+ if (namedItems.isEmpty())
return;
if (namedItems.size() == 1) {
- returnValue1Enabled = true;
- returnValue1 = namedItems.at(0);
+ elementEnabled = true;
+ element = namedItems.at(0);
return;
}
- returnValue0Enabled = true;
- returnValue0 = this->ownerNode()->radioNodeList(name);
+ radioNodeListEnabled = true;
+ radioNodeList = ownerNode().radioNodeList(name);
+}
+
+void HTMLFormControlsCollection::supportedPropertyNames(Vector<String>& names)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlformcontrolscollection-0:
+ // The supported property names consist of the non-empty values of all the id and name attributes
+ // of all the elements represented by the collection, in tree order, ignoring later duplicates,
+ // with the id of an element preceding its name if it contributes both, they differ from each
+ // other, and neither is the duplicate of an earlier entry.
+ HashSet<AtomicString> existingNames;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
+ ASSERT(element);
+ const AtomicString& idAttribute = element->getIdAttribute();
+ if (!idAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(idAttribute);
+ if (addResult.isNewEntry)
+ names.append(idAttribute);
+ }
+ const AtomicString& nameAttribute = element->getNameAttribute();
+ if (!nameAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(nameAttribute);
+ if (addResult.isNewEntry)
+ names.append(nameAttribute);
+ }
+ }
+}
+
+void HTMLFormControlsCollection::trace(Visitor* visitor)
+{
+ visitor->trace(m_cachedElement);
+ HTMLCollection::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h
index 45b286ccb78..df90351776a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h
@@ -2,6 +2,7 @@
* 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) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,12 +24,12 @@
#ifndef HTMLFormControlsCollection_h
#define HTMLFormControlsCollection_h
+#include "core/html/FormAssociatedElement.h"
#include "core/html/HTMLCollection.h"
#include "core/html/RadioNodeList.h"
namespace WebCore {
-class FormAssociatedElement;
class HTMLElement;
class HTMLImageElement;
class QualifiedName;
@@ -38,22 +39,30 @@ class QualifiedName;
class HTMLFormControlsCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLFormControlsCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> create(ContainerNode&, CollectionType);
virtual ~HTMLFormControlsCollection();
- virtual Node* namedItem(const AtomicString& name) const;
- void namedGetter(const AtomicString& name, bool&, RefPtr<RadioNodeList>&, bool&, RefPtr<Node>&);
+ virtual Element* namedItem(const AtomicString& name) const OVERRIDE;
+ void namedGetter(const AtomicString& name, bool& radioNodeListEnabled, RefPtrWillBeRawPtr<RadioNodeList>&, bool& elementEnabled, RefPtrWillBeRawPtr<Element>&);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- explicit HTMLFormControlsCollection(Node*);
+ explicit HTMLFormControlsCollection(ContainerNode&);
+
+ virtual void updateIdNameCache() const OVERRIDE;
+ virtual void supportedPropertyNames(Vector<String>& names) OVERRIDE;
- virtual void updateNameCache() const OVERRIDE;
+ const FormAssociatedElement::List& formControlElements() const;
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& formImageElements() const;
+ virtual Element* virtualItemAfter(Element*) const OVERRIDE;
+ virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
- const Vector<FormAssociatedElement*>& formControlElements() const;
- const Vector<HTMLImageElement*>& formImageElements() const;
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
+ mutable RawPtrWillBeMember<Element> m_cachedElement;
+ mutable unsigned m_cachedElementOffsetInArray;
};
+DEFINE_TYPE_CASTS(HTMLFormControlsCollection, LiveNodeListBase, collection, collection->type() == FormControls, collection.type() == FormControls);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl
index f483a675a31..5ed779f2dfa 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2014 Samsung Electronics. 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
@@ -20,9 +21,8 @@
[
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
] interface HTMLFormControlsCollection : HTMLCollection {
- [ImplementedAs=item] getter Node(unsigned long index);
- [Custom] Node namedItem([Default=Undefined] optional DOMString name);
- [ImplementedAs=namedGetter, NotEnumerable] getter (RadioNodeList or Node)(DOMString name);
+ [ImplementedAs=item] getter Node (unsigned long index);
+ [ImplementedAs=namedGetter] getter (RadioNodeList or Element) namedItem(DOMString name); // shadows inherited namedItem()
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
index 0e5cc98d302..18ef044388a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
@@ -26,34 +26,35 @@
#include "core/html/HTMLFormElement.h"
#include <limits>
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NamedNodesCollection.h"
+#include "core/dom/IdTargetObserverRegistry.h"
#include "core/events/AutocompleteErrorEvent.h"
#include "core/events/Event.h"
+#include "core/events/GenericEventQueue.h"
#include "core/events/ScopedEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDialogElement.h"
+#include "core/html/HTMLFormControlsCollection.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLObjectElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/RadioNodeList.h"
#include "core/html/forms/FormController.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
-#include "core/frame/UseCounter.h"
+#include "core/loader/MixedContentChecker.h"
#include "core/rendering/RenderTextControl.h"
#include "platform/UserGestureIndicator.h"
-
-using namespace std;
+#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -61,37 +62,47 @@ using namespace HTMLNames;
HTMLFormElement::HTMLFormElement(Document& document)
: HTMLElement(formTag, document)
- , m_associatedElementsBeforeIndex(0)
- , m_associatedElementsAfterIndex(0)
+#if !ENABLE(OILPAN)
+ , m_weakPtrFactory(this)
+#endif
+ , m_associatedElementsAreDirty(false)
+ , m_imageElementsAreDirty(false)
+ , m_hasElementsAssociatedByParser(false)
+ , m_didFinishParsingChildren(false)
, m_wasUserSubmitted(false)
- , m_isSubmittingOrPreparingForSubmission(false)
- , m_shouldSubmit(false)
, m_isInResetFunction(false)
, m_wasDemoted(false)
- , m_requestAutocompleteTimer(this, &HTMLFormElement::requestAutocompleteTimerFired)
+ , m_pendingAutocompleteEventsQueue(GenericEventQueue::create(this))
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFormElement> HTMLFormElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLFormElement> HTMLFormElement::create(Document& document)
{
UseCounter::count(document, UseCounter::FormElement);
- return adoptRef(new HTMLFormElement(document));
+ return adoptRefWillBeNoop(new HTMLFormElement(document));
}
HTMLFormElement::~HTMLFormElement()
{
- document().formController()->willDeleteForm(this);
-
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- m_associatedElements[i]->formWillBeDestroyed();
- for (unsigned i = 0; i < m_imageElements.size(); ++i)
- m_imageElements[i]->m_form = 0;
+#if !ENABLE(OILPAN)
+ // With Oilpan, either removedFrom is called or the document and
+ // form controller are dead as well and there is no need to remove
+ // this form element from it.
+ document().formController().willDeleteForm(this);
+#endif
}
-bool HTMLFormElement::formWouldHaveSecureSubmission(const String& url)
+void HTMLFormElement::trace(Visitor* visitor)
{
- return document().completeURL(url).protocolIs("https");
+#if ENABLE(OILPAN)
+ visitor->trace(m_pastNamesMap);
+ visitor->trace(m_radioButtonGroupScope);
+ visitor->trace(m_associatedElements);
+ visitor->trace(m_imageElements);
+ visitor->trace(m_pendingAutocompleteEventsQueue);
+#endif
+ HTMLElement::trace(visitor);
}
bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style)
@@ -100,14 +111,16 @@ bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style)
return HTMLElement::rendererIsNeeded(style);
ContainerNode* node = parentNode();
+ if (!node || !node->renderer())
+ return HTMLElement::rendererIsNeeded(style);
RenderObject* parentRenderer = node->renderer();
// FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below).
// FIXME: This check is not correct for Shadow DOM.
- bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(node))
- || (parentRenderer->isTableRow() && node->hasTagName(trTag))
+ bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(*node))
+ || (parentRenderer->isTableRow() && isHTMLTableRowElement(*node))
|| (parentRenderer->isTableSection() && node->hasTagName(tbodyTag))
|| (parentRenderer->isRenderTableCol() && node->hasTagName(colTag))
- || (parentRenderer->isTableCell() && node->hasTagName(trTag));
+ || (parentRenderer->isTableCell() && isHTMLTableRowElement(*node));
if (!parentIsTableElementPart)
return true;
@@ -129,20 +142,46 @@ Node::InsertionNotificationRequest HTMLFormElement::insertedInto(ContainerNode*
return InsertionDone;
}
-static inline Node* findRoot(Node* n)
+template<class T>
+void notifyFormRemovedFromTree(const T& elements, Node& root)
{
- Node* root = n;
- for (; n; n = n->parentNode())
- root = n;
- return root;
+ size_t size = elements.size();
+ for (size_t i = 0; i < size; ++i)
+ elements[i]->formRemovedFromTree(root);
+ ASSERT(elements.size() == size);
}
void HTMLFormElement::removedFrom(ContainerNode* insertionPoint)
{
- Node* root = findRoot(this);
- Vector<FormAssociatedElement*> associatedElements(m_associatedElements);
- for (unsigned i = 0; i < associatedElements.size(); ++i)
- associatedElements[i]->formRemovedFromTree(root);
+ // We don't need to take care of form association by 'form' content
+ // attribute becuse IdTargetObserver handles it.
+ if (m_hasElementsAssociatedByParser) {
+ Node& root = highestAncestorOrSelf();
+ if (!m_associatedElementsAreDirty) {
+ FormAssociatedElement::List elements(associatedElements());
+ notifyFormRemovedFromTree(elements, root);
+ } else {
+ FormAssociatedElement::List elements;
+ collectAssociatedElements(insertionPoint->highestAncestorOrSelf(), elements);
+ notifyFormRemovedFromTree(elements, root);
+ collectAssociatedElements(root, elements);
+ notifyFormRemovedFromTree(elements, root);
+ }
+
+ if (!m_imageElementsAreDirty) {
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > images(imageElements());
+ notifyFormRemovedFromTree(images, root);
+ } else {
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > images;
+ collectImageElements(insertionPoint->highestAncestorOrSelf(), images);
+ notifyFormRemovedFromTree(images, root);
+ collectImageElements(root, images);
+ notifyFormRemovedFromTree(images, root);
+ }
+ }
+#if ENABLE(OILPAN)
+ document().formController().willDeleteForm(this);
+#endif
HTMLElement::removedFrom(insertionPoint);
}
@@ -158,14 +197,16 @@ void HTMLFormElement::handleLocalEvents(Event* event)
unsigned HTMLFormElement::length() const
{
+ const FormAssociatedElement::List& elements = associatedElements();
unsigned len = 0;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- if (m_associatedElements[i]->isEnumeratable())
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->isEnumeratable())
++len;
+ }
return len;
}
-Node* HTMLFormElement::item(unsigned index)
+Element* HTMLFormElement::item(unsigned index)
{
return elements()->item(index);
}
@@ -174,8 +215,9 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
{
int submissionTriggerCount = 0;
bool seenDefaultButton = false;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- FormAssociatedElement* formAssociatedElement = m_associatedElements[i];
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ FormAssociatedElement* formAssociatedElement = elements[i];
if (!formAssociatedElement->isFormControlElement())
continue;
HTMLFormControlElement* control = toHTMLFormControlElement(formAssociatedElement);
@@ -183,10 +225,8 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
if (fromImplicitSubmissionTrigger)
seenDefaultButton = true;
if (control->isSuccessfulSubmitButton()) {
- if (control->renderer()) {
- control->dispatchSimulatedClick(event);
- return;
- }
+ control->dispatchSimulatedClick(event);
+ return;
} else if (fromImplicitSubmissionTrigger) {
// Default (submit) button is not activated; no implicit submission.
return;
@@ -219,12 +259,13 @@ bool HTMLFormElement::validateInteractively(Event* event)
if (submitElement && submitElement->formNoValidate())
return true;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (m_associatedElements[i]->isFormControlElement())
- toHTMLFormControlElement(m_associatedElements[i])->hideVisibleValidationMessage();
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->isFormControlElement())
+ toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage();
}
- Vector<RefPtr<FormAssociatedElement> > unhandledInvalidControls;
+ WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > unhandledInvalidControls;
if (!checkInvalidControlsAndCollectUnhandled(&unhandledInvalidControls))
return true;
// Because the form has invalid controls, we abort the form submission and
@@ -234,7 +275,7 @@ bool HTMLFormElement::validateInteractively(Event* event)
// has !renderer()->needsLayout() assertion.
document().updateLayoutIgnorePendingStylesheets();
- RefPtr<HTMLFormElement> protector(this);
+ RefPtrWillBeRawPtr<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();
@@ -262,36 +303,21 @@ bool HTMLFormElement::validateInteractively(Event* event)
return false;
}
-bool HTMLFormElement::prepareForSubmission(Event* event)
+void HTMLFormElement::prepareForSubmission(Event* event)
{
- RefPtr<HTMLFormElement> protector(this);
- Frame* frame = document().frame();
- if (m_isSubmittingOrPreparingForSubmission || !frame)
- return m_isSubmittingOrPreparingForSubmission;
-
- m_isSubmittingOrPreparingForSubmission = true;
- m_shouldSubmit = false;
+ RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
+ LocalFrame* frame = document().frame();
+ if (!frame)
+ return;
// Interactive validation must be done before dispatching the submit event.
- if (!validateInteractively(event)) {
- m_isSubmittingOrPreparingForSubmission = false;
- return false;
- }
+ if (!validateInteractively(event))
+ return;
- StringPairVector controlNamesAndValues;
- getTextFieldValues(controlNamesAndValues);
- RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), NotSubmittedByJavaScript);
- frame->loader().client()->dispatchWillSendSubmitEvent(formState.release());
+ frame->loader().client()->dispatchWillSendSubmitEvent(this);
if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit)))
- m_shouldSubmit = true;
-
- m_isSubmittingOrPreparingForSubmission = false;
-
- if (m_shouldSubmit)
submit(event, true, true, NotSubmittedByJavaScript);
-
- return m_shouldSubmit;
}
void HTMLFormElement::submit()
@@ -304,30 +330,11 @@ void HTMLFormElement::submitFromJavaScript()
submit(0, false, UserGestureIndicator::processingUserGesture(), SubmittedByJavaScript);
}
-void HTMLFormElement::getTextFieldValues(StringPairVector& fieldNamesAndValues) const
-{
- ASSERT_ARG(fieldNamesAndValues, fieldNamesAndValues.isEmpty());
-
- fieldNamesAndValues.reserveCapacity(m_associatedElements.size());
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- FormAssociatedElement* control = m_associatedElements[i];
- HTMLElement* element = toHTMLElement(control);
- if (!element->hasTagName(inputTag))
- continue;
-
- HTMLInputElement* input = toHTMLInputElement(element);
- if (!input->isTextField())
- continue;
-
- fieldNamesAndValues.append(make_pair(input->name().string(), input->value()));
- }
-}
-
-void HTMLFormElement::submitDialog(PassRefPtr<FormSubmission> formSubmission)
+void HTMLFormElement::submitDialog(PassRefPtrWillBeRawPtr<FormSubmission> formSubmission)
{
for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
- if (node->hasTagName(dialogTag)) {
- toHTMLDialogElement(node)->closeDialog(formSubmission->result());
+ if (isHTMLDialogElement(*node)) {
+ toHTMLDialogElement(*node).closeDialog(formSubmission->result());
return;
}
}
@@ -336,23 +343,18 @@ void HTMLFormElement::submitDialog(PassRefPtr<FormSubmission> formSubmission)
void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger formSubmissionTrigger)
{
FrameView* view = document().view();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!view || !frame || !frame->page())
return;
- if (m_isSubmittingOrPreparingForSubmission) {
- m_shouldSubmit = true;
- return;
- }
-
- m_isSubmittingOrPreparingForSubmission = true;
m_wasUserSubmitted = processingUserGesture;
- RefPtr<HTMLFormControlElement> firstSuccessfulSubmitButton;
+ RefPtrWillBeRawPtr<HTMLFormControlElement> firstSuccessfulSubmitButton = nullptr;
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];
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ FormAssociatedElement* associatedElement = elements[i];
if (!associatedElement->isFormControlElement())
continue;
if (needButtonActivation) {
@@ -367,7 +369,7 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool proce
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(true);
- RefPtr<FormSubmission> formSubmission = FormSubmission::create(this, m_attributes, event, formSubmissionTrigger);
+ RefPtrWillBeRawPtr<FormSubmission> formSubmission = FormSubmission::create(this, m_attributes, event, formSubmissionTrigger);
EventQueueScope scopeForDialogClose; // Delay dispatching 'close' to dialog until done submitting.
if (formSubmission->method() == FormSubmission::DialogMethod)
submitDialog(formSubmission.release());
@@ -376,12 +378,9 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool proce
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(false);
-
- m_shouldSubmit = false;
- m_isSubmittingOrPreparingForSubmission = false;
}
-void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submission)
+void HTMLFormElement::scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission> submission)
{
ASSERT(submission->method() == FormSubmission::PostMethod || submission->method() == FormSubmission::GetMethod);
ASSERT(submission->data());
@@ -395,15 +394,15 @@ void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submissi
}
if (protocolIsJavaScript(submission->action())) {
- if (!document().contentSecurityPolicy()->allowFormAction(KURL(submission->action())))
+ if (!document().contentSecurityPolicy()->allowFormAction(submission->action()))
return;
document().frame()->script().executeScriptIfJavaScriptURL(submission->action());
return;
}
- Frame* targetFrame = document().frame()->loader().findFrameForNavigation(submission->target(), submission->state()->sourceDocument());
+ LocalFrame* targetFrame = document().frame()->loader().findFrameForNavigation(submission->target(), submission->state()->sourceDocument());
if (!targetFrame) {
- if (!DOMWindow::allowPopUp(document().frame()) && !UserGestureIndicator::processingUserGesture())
+ if (!LocalDOMWindow::allowPopUp(*document().frame()) && !UserGestureIndicator::processingUserGesture())
return;
targetFrame = document().frame();
} else {
@@ -412,7 +411,15 @@ void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submissi
if (!targetFrame->page())
return;
- submission->setReferrer(document().outgoingReferrer());
+ if (MixedContentChecker::isMixedContent(document().securityOrigin(), submission->action())) {
+ UseCounter::count(document(), UseCounter::MixedContentFormsSubmitted);
+ if (!document().frame()->loader().mixedContentChecker()->canSubmitToInsecureForm(document().securityOrigin(), submission->action()))
+ return;
+ } else {
+ UseCounter::count(document(), UseCounter::FormsSubmitted);
+ }
+
+ submission->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
submission->setOrigin(document().outgoingOrigin());
targetFrame->navigationScheduler().scheduleFormSubmission(submission);
@@ -420,7 +427,7 @@ void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submissi
void HTMLFormElement::reset()
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (m_isInResetFunction || !frame)
return;
@@ -431,9 +438,10 @@ void HTMLFormElement::reset()
return;
}
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (m_associatedElements[i]->isFormControlElement())
- toHTMLFormControlElement(m_associatedElements[i])->reset();
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->isFormControlElement())
+ toHTMLFormControlElement(elements[i])->reset();
}
m_isInResetFunction = false;
@@ -441,54 +449,51 @@ void HTMLFormElement::reset()
void HTMLFormElement::requestAutocomplete()
{
- Frame* frame = document().frame();
- if (!frame)
- return;
+ String errorMessage;
+
+ if (!document().frame())
+ errorMessage = "requestAutocomplete: form is not owned by a displayed document.";
+ else if (!shouldAutocomplete())
+ errorMessage = "requestAutocomplete: form autocomplete attribute is set to off.";
+ else if (!UserGestureIndicator::processingUserGesture())
+ errorMessage = "requestAutocomplete: must be called in response to a user gesture.";
- if (!shouldAutocomplete() || !UserGestureIndicator::processingUserGesture()) {
+ if (!errorMessage.isEmpty()) {
+ document().addConsoleMessage(RenderingMessageSource, LogMessageLevel, errorMessage);
finishRequestAutocomplete(AutocompleteResultErrorDisabled);
- return;
+ } else {
+ document().frame()->loader().client()->didRequestAutocomplete(this);
}
-
- StringPairVector controlNamesAndValues;
- getTextFieldValues(controlNamesAndValues);
- RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), SubmittedByJavaScript);
- frame->loader().client()->didRequestAutocomplete(formState.release());
}
void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result)
{
- RefPtr<Event> event;
+ RefPtrWillBeRawPtr<Event> event = nullptr;
if (result == AutocompleteResultSuccess)
- event = Event::create(EventTypeNames::autocomplete);
+ event = Event::createBubble(EventTypeNames::autocomplete);
else if (result == AutocompleteResultErrorDisabled)
event = AutocompleteErrorEvent::create("disabled");
else if (result == AutocompleteResultErrorCancel)
event = AutocompleteErrorEvent::create("cancel");
else if (result == AutocompleteResultErrorInvalid)
event = AutocompleteErrorEvent::create("invalid");
+ else
+ ASSERT_NOT_REACHED();
event->setTarget(this);
- m_pendingAutocompleteEvents.append(event.release());
-
- // Dispatch events later as this API is meant to work asynchronously in all situations and implementations.
- if (!m_requestAutocompleteTimer.isActive())
- m_requestAutocompleteTimer.startOneShot(0);
-}
-
-void HTMLFormElement::requestAutocompleteTimerFired(Timer<HTMLFormElement>*)
-{
- Vector<RefPtr<Event> > pendingEvents;
- m_pendingAutocompleteEvents.swap(pendingEvents);
- for (size_t i = 0; i < pendingEvents.size(); ++i)
- dispatchEvent(pendingEvents[i].release());
+ m_pendingAutocompleteEventsQueue->enqueueEvent(event.release());
}
void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (name == actionAttr)
+ if (name == actionAttr) {
m_attributes.parseAction(value);
- else if (name == targetAttr)
+ // If the new action attribute is pointing to insecure "action" location from a secure page
+ // it is marked as "passive" mixed content.
+ KURL actionURL = document().completeURL(m_attributes.action().isEmpty() ? document().url().string() : m_attributes.action());
+ if (MixedContentChecker::isMixedContent(document().securityOrigin(), actionURL))
+ document().frame()->loader().mixedContentChecker()->canSubmitToInsecureForm(document().securityOrigin(), actionURL);
+ } else if (name == targetAttr)
m_attributes.setTarget(value);
else if (name == methodAttr)
m_attributes.updateMethodType(value);
@@ -497,135 +502,119 @@ void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicStri
else if (name == accept_charsetAttr)
m_attributes.setAcceptCharset(value);
else if (name == onautocompleteAttr)
- setAttributeEventListener(EventTypeNames::autocomplete, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::autocomplete, createAttributeEventListener(this, name, value, eventParameterName()));
else if (name == onautocompleteerrorAttr)
- setAttributeEventListener(EventTypeNames::autocompleteerror, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::autocompleteerror, createAttributeEventListener(this, name, value, eventParameterName()));
else
HTMLElement::parseAttribute(name, value);
}
-template<class T, size_t n> static void removeFromVector(Vector<T*, n> & vec, T* item)
+void HTMLFormElement::associate(FormAssociatedElement& e)
{
- size_t size = vec.size();
- for (size_t i = 0; i != size; ++i)
- if (vec[i] == item) {
- vec.remove(i);
- break;
- }
+ m_associatedElementsAreDirty = true;
+ m_associatedElements.clear();
}
-unsigned HTMLFormElement::formElementIndexWithFormAttribute(Element* element, unsigned rangeStart, unsigned rangeEnd)
+void HTMLFormElement::disassociate(FormAssociatedElement& e)
{
- if (m_associatedElements.isEmpty())
- return 0;
-
- ASSERT(rangeStart <= rangeEnd);
-
- if (rangeStart == rangeEnd)
- return rangeStart;
+ m_associatedElementsAreDirty = true;
+ m_associatedElements.clear();
+ removeFromPastNamesMap(toHTMLElement(e));
+}
- unsigned left = rangeStart;
- unsigned right = rangeEnd - 1;
- unsigned short position;
+bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const
+{
+ return attribute.name() == actionAttr || HTMLElement::isURLAttribute(attribute);
+}
- // Does binary search on m_associatedElements in order to find the index
- // to be inserted.
- while (left != right) {
- unsigned middle = left + ((right - left) / 2);
- ASSERT(middle < m_associatedElementsBeforeIndex || middle >= m_associatedElementsAfterIndex);
- position = element->compareDocumentPosition(toHTMLElement(m_associatedElements[middle]));
- if (position & DOCUMENT_POSITION_FOLLOWING)
- right = middle;
- else
- left = middle + 1;
- }
+bool HTMLFormElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == actionAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
- ASSERT(left < m_associatedElementsBeforeIndex || left >= m_associatedElementsAfterIndex);
- position = element->compareDocumentPosition(toHTMLElement(m_associatedElements[left]));
- if (position & DOCUMENT_POSITION_FOLLOWING)
- return left;
- return left + 1;
+void HTMLFormElement::associate(HTMLImageElement& e)
+{
+ m_imageElementsAreDirty = true;
+ m_imageElements.clear();
}
-unsigned HTMLFormElement::formElementIndex(FormAssociatedElement& associatedElement)
+void HTMLFormElement::disassociate(HTMLImageElement& e)
{
- HTMLElement& associatedHTMLElement = toHTMLElement(associatedElement);
- // Treats separately the case where this element has the form attribute
- // for performance consideration.
- if (associatedHTMLElement.fastHasAttribute(formAttr)) {
- unsigned short position = compareDocumentPosition(&associatedHTMLElement);
- if (position & DOCUMENT_POSITION_PRECEDING) {
- ++m_associatedElementsBeforeIndex;
- ++m_associatedElementsAfterIndex;
- return HTMLFormElement::formElementIndexWithFormAttribute(&associatedHTMLElement, 0, m_associatedElementsBeforeIndex - 1);
- }
- if (position & DOCUMENT_POSITION_FOLLOWING && !(position & DOCUMENT_POSITION_CONTAINED_BY))
- return HTMLFormElement::formElementIndexWithFormAttribute(&associatedHTMLElement, m_associatedElementsAfterIndex, m_associatedElements.size());
- }
+ m_imageElementsAreDirty = true;
+ m_imageElements.clear();
+ removeFromPastNamesMap(e);
+}
- // 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 (ElementTraversal::next(associatedHTMLElement, this)) {
- unsigned i = m_associatedElementsBeforeIndex;
- for (Element* element = this; element; element = ElementTraversal::next(*element, this)) {
- if (element == associatedHTMLElement) {
- ++m_associatedElementsAfterIndex;
- return i;
- }
- if (!element->isFormControlElement() && !element->hasTagName(objectTag))
- continue;
- if (!element->isHTMLElement() || toHTMLElement(element)->formOwner() != this)
- continue;
- ++i;
- }
- }
- return m_associatedElementsAfterIndex++;
+#if !ENABLE(OILPAN)
+WeakPtr<HTMLFormElement> HTMLFormElement::createWeakPtr()
+{
+ return m_weakPtrFactory.createWeakPtr();
}
+#endif
-void HTMLFormElement::registerFormElement(FormAssociatedElement& e)
+void HTMLFormElement::didAssociateByParser()
{
- m_associatedElements.insert(formElementIndex(e), &e);
+ if (!m_didFinishParsingChildren)
+ return;
+ m_hasElementsAssociatedByParser = true;
+ UseCounter::count(document(), UseCounter::FormAssociationByParser);
}
-void HTMLFormElement::removeFormElement(FormAssociatedElement* e)
+PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> HTMLFormElement::elements()
{
- unsigned index;
- for (index = 0; index < m_associatedElements.size(); ++index) {
- if (m_associatedElements[index] == e)
- break;
- }
- ASSERT_WITH_SECURITY_IMPLICATION(index < m_associatedElements.size());
- if (index < m_associatedElementsBeforeIndex)
- --m_associatedElementsBeforeIndex;
- if (index < m_associatedElementsAfterIndex)
- --m_associatedElementsAfterIndex;
- removeFromPastNamesMap(*toHTMLElement(e));
- removeFromVector(m_associatedElements, e);
+ return toHTMLFormControlsCollection(ensureCachedHTMLCollection(FormControls).get());
}
-bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const
+void HTMLFormElement::collectAssociatedElements(Node& root, FormAssociatedElement::List& elements) const
{
- return attribute.name() == actionAttr || HTMLElement::isURLAttribute(attribute);
+ elements.clear();
+ for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(root); element; element = Traversal<HTMLElement>::next(*element)) {
+ FormAssociatedElement* associatedElement = 0;
+ if (element->isFormControlElement())
+ associatedElement = toHTMLFormControlElement(element);
+ else if (isHTMLObjectElement(*element))
+ associatedElement = toHTMLObjectElement(element);
+ else
+ continue;
+ if (associatedElement->form()== this)
+ elements.append(associatedElement);
+ }
}
-void HTMLFormElement::registerImgElement(HTMLImageElement* e)
+// This function should be const conceptually. However we update some fields
+// because of lazy evaluation.
+const FormAssociatedElement::List& HTMLFormElement::associatedElements() const
{
- ASSERT(m_imageElements.find(e) == kNotFound);
- m_imageElements.append(e);
+ if (!m_associatedElementsAreDirty)
+ return m_associatedElements;
+ HTMLFormElement* mutableThis = const_cast<HTMLFormElement*>(this);
+ Node* scope = mutableThis;
+ if (m_hasElementsAssociatedByParser)
+ scope = &highestAncestorOrSelf();
+ if (inDocument() && treeScope().idTargetObserverRegistry().hasObservers(fastGetAttribute(idAttr)))
+ scope = &treeScope().rootNode();
+ ASSERT(scope);
+ collectAssociatedElements(*scope, mutableThis->m_associatedElements);
+ mutableThis->m_associatedElementsAreDirty = false;
+ return m_associatedElements;
}
-void HTMLFormElement::removeImgElement(HTMLImageElement* e)
+void HTMLFormElement::collectImageElements(Node& root, WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& elements)
{
- ASSERT(m_imageElements.find(e) != kNotFound);
- removeFromPastNamesMap(*e);
- removeFromVector(m_imageElements, e);
+ elements.clear();
+ for (HTMLImageElement* image = Traversal<HTMLImageElement>::firstWithin(root); image; image = Traversal<HTMLImageElement>::next(*image)) {
+ if (image->formOwner() == this)
+ elements.append(image);
+ }
}
-PassRefPtr<HTMLCollection> HTMLFormElement::elements()
+const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& HTMLFormElement::imageElements()
{
- return ensureCachedHTMLCollection(FormControls);
+ if (!m_imageElementsAreDirty)
+ return m_imageElements;
+ collectImageElements(m_hasElementsAssociatedByParser ? highestAncestorOrSelf() : *this, m_imageElements);
+ m_imageElementsAreDirty = false;
+ return m_imageElements;
}
String HTMLFormElement::name() const
@@ -646,11 +635,6 @@ const AtomicString& HTMLFormElement::action() const
return getAttribute(actionAttr);
}
-void HTMLFormElement::setAction(const AtomicString& value)
-{
- setAttribute(actionAttr, value);
-}
-
void HTMLFormElement::setEnctype(const AtomicString& value)
{
setAttribute(enctypeAttr, value);
@@ -666,11 +650,6 @@ void HTMLFormElement::setMethod(const AtomicString& value)
setAttribute(methodAttr, value);
}
-String HTMLFormElement::target() const
-{
- return getAttribute(targetAttr);
-}
-
bool HTMLFormElement::wasUserSubmitted() const
{
return m_wasUserSubmitted;
@@ -678,10 +657,11 @@ bool HTMLFormElement::wasUserSubmitted() const
HTMLFormControlElement* HTMLFormElement::defaultButton() const
{
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (!m_associatedElements[i]->isFormControlElement())
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (!elements[i]->isFormControlElement())
continue;
- HTMLFormControlElement* control = toHTMLFormControlElement(m_associatedElements[i]);
+ HTMLFormControlElement* control = toHTMLFormControlElement(elements[i]);
if (control->isSuccessfulSubmitButton())
return control;
}
@@ -691,61 +671,56 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const
bool HTMLFormElement::checkValidity()
{
- Vector<RefPtr<FormAssociatedElement> > controls;
- return !checkInvalidControlsAndCollectUnhandled(&controls);
-}
-
-bool HTMLFormElement::checkValidityWithoutDispatchingEvents()
-{
- return !checkInvalidControlsAndCollectUnhandled(0, HTMLFormControlElement::CheckValidityDispatchEventsNone);
+ return !checkInvalidControlsAndCollectUnhandled(0);
}
-bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls, HTMLFormControlElement::CheckValidityDispatchEvents dispatchEvents)
+bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<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]);
+ RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
+ // Copy associatedElements because event handlers called from
+ // HTMLFormControlElement::checkValidity() might change associatedElements.
+ const FormAssociatedElement::List& associatedElements = this->associatedElements();
+ WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > elements;
+ elements.reserveCapacity(associatedElements.size());
+ for (unsigned i = 0; i < associatedElements.size(); ++i)
+ elements.append(associatedElements[i]);
bool hasInvalidControls = false;
for (unsigned i = 0; i < elements.size(); ++i) {
if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get());
- if (!control->checkValidity(unhandledInvalidControls, dispatchEvents) && control->formOwner() == this)
+ if (!control->checkValidity(unhandledInvalidControls) && control->formOwner() == this)
hasInvalidControls = true;
}
}
return hasInvalidControls;
}
-Node* HTMLFormElement::elementFromPastNamesMap(const AtomicString& pastName) const
+Element* HTMLFormElement::elementFromPastNamesMap(const AtomicString& pastName)
{
if (pastName.isEmpty() || !m_pastNamesMap)
return 0;
- Node* node = m_pastNamesMap->get(pastName);
-#if !ASSERT_DISABLED
- if (!node)
+ Element* element = m_pastNamesMap->get(pastName);
+#if ASSERT_ENABLED
+ if (!element)
return 0;
- ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(node)->formOwner() == this);
- if (node->hasTagName(imgTag)) {
- ASSERT_WITH_SECURITY_IMPLICATION(m_imageElements.find(node) != kNotFound);
- } else if (node->hasTagName(objectTag)) {
- ASSERT_WITH_SECURITY_IMPLICATION(m_associatedElements.find(toHTMLObjectElement(node)) != kNotFound);
+ ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(element)->formOwner() == this);
+ if (isHTMLImageElement(*element)) {
+ ASSERT_WITH_SECURITY_IMPLICATION(imageElements().find(element) != kNotFound);
+ } else if (isHTMLObjectElement(*element)) {
+ ASSERT_WITH_SECURITY_IMPLICATION(associatedElements().find(toHTMLObjectElement(element)) != kNotFound);
} else {
- ASSERT_WITH_SECURITY_IMPLICATION(m_associatedElements.find(toHTMLFormControlElement(node)) != kNotFound);
+ ASSERT_WITH_SECURITY_IMPLICATION(associatedElements().find(toHTMLFormControlElement(element)) != kNotFound);
}
#endif
- return node;
+ return element;
}
-void HTMLFormElement::addToPastNamesMap(Node* element, const AtomicString& pastName)
+void HTMLFormElement::addToPastNamesMap(Element* element, const AtomicString& pastName)
{
if (pastName.isEmpty())
return;
if (!m_pastNamesMap)
- m_pastNamesMap = adoptPtr(new PastNamesMap);
+ m_pastNamesMap = adoptPtrWillBeNoop(new PastNamesMap);
m_pastNamesMap->set(pastName, element);
}
@@ -756,22 +731,24 @@ void HTMLFormElement::removeFromPastNamesMap(HTMLElement& element)
PastNamesMap::iterator end = m_pastNamesMap->end();
for (PastNamesMap::iterator it = m_pastNamesMap->begin(); it != end; ++it) {
if (it->value == &element) {
- it->value = 0;
+ it->value = nullptr;
// Keep looping. Single element can have multiple names.
}
}
}
-void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<RefPtr<Node> >& namedItems)
+void HTMLFormElement::getNamedElements(const AtomicString& name, WillBeHeapVector<RefPtrWillBeMember<Element> >& namedItems)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#dom-form-nameditem
elements()->namedItems(name, namedItems);
- Node* elementFromPast = elementFromPastNamesMap(name);
- if (namedItems.size() && namedItems.first() != elementFromPast)
+ Element* elementFromPast = elementFromPastNamesMap(name);
+ if (namedItems.size() && namedItems.first() != elementFromPast) {
addToPastNamesMap(namedItems.first().get(), name);
- else if (elementFromPast && namedItems.isEmpty())
+ } else if (elementFromPast && namedItems.isEmpty()) {
namedItems.append(elementFromPast);
+ UseCounter::count(document(), UseCounter::FormNameAccessForPastNamesMap);
+ }
}
bool HTMLFormElement::shouldAutocomplete() const
@@ -782,7 +759,8 @@ bool HTMLFormElement::shouldAutocomplete() const
void HTMLFormElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
- document().formController()->restoreControlStateIn(*this);
+ document().formController().restoreControlStateIn(*this);
+ m_didFinishParsingChildren = true;
}
void HTMLFormElement::copyNonAttributePropertiesFromElement(const Element& source)
@@ -791,13 +769,13 @@ void HTMLFormElement::copyNonAttributePropertiesFromElement(const Element& sourc
HTMLElement::copyNonAttributePropertiesFromElement(source);
}
-void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtrWillBeRawPtr<RadioNodeList>& returnValue0, bool& returnValue1Enabled, RefPtrWillBeRawPtr<Element>& returnValue1)
{
// Call getNamedElements twice, first time check if it has a value
// and let HTMLFormElement update its cache.
// See issue: 867404
{
- Vector<RefPtr<Node> > elements;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > elements;
getNamedElements(name, elements);
if (elements.isEmpty())
return;
@@ -805,7 +783,7 @@ void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& retur
// Second call may return different results from the first call,
// but if the first the size cannot be zero.
- Vector<RefPtr<Node> > elements;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > elements;
getNamedElements(name, elements);
ASSERT(!elements.isEmpty());
@@ -815,8 +793,9 @@ void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& retur
return;
}
+ bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.first());
returnValue0Enabled = true;
- returnValue0 = NamedNodesCollection::create(elements);
+ returnValue0 = radioNodeList(name, onlyMatchImg);
}
void HTMLFormElement::setDemoted(bool demoted)
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h
index d2f118e08c3..b4fb4793566 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h
@@ -26,10 +26,10 @@
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFormControlElement.h"
-#include "core/html/forms/CheckedRadioButtons.h"
-#include "core/loader/FormState.h"
+#include "core/html/forms/RadioButtonGroupScope.h"
#include "core/loader/FormSubmission.h"
#include "wtf/OwnPtr.h"
+#include "wtf/WeakPtr.h"
namespace WTF{
class TextEncoding;
@@ -40,20 +40,23 @@ namespace WebCore {
class Event;
class FormAssociatedElement;
class FormData;
+class GenericEventQueue;
class HTMLFormControlElement;
+class HTMLFormControlsCollection;
class HTMLImageElement;
class HTMLInputElement;
class HTMLFormElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLFormElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLFormElement> create(Document&);
virtual ~HTMLFormElement();
+ virtual void trace(Visitor*) OVERRIDE;
- PassRefPtr<HTMLCollection> elements();
- void getNamedElements(const AtomicString&, Vector<RefPtr<Node> >&);
+ PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> elements();
+ void getNamedElements(const AtomicString&, WillBeHeapVector<RefPtrWillBeMember<Element> >&);
unsigned length() const;
- Node* item(unsigned index);
+ Element* item(unsigned index);
String enctype() const { return m_attributes.encodingType(); }
void setEnctype(const AtomicString&);
@@ -63,14 +66,16 @@ public:
bool shouldAutocomplete() 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 associate(FormAssociatedElement&);
+ void disassociate(FormAssociatedElement&);
+ void associate(HTMLImageElement&);
+ void disassociate(HTMLImageElement&);
+#if !ENABLE(OILPAN)
+ WeakPtr<HTMLFormElement> createWeakPtr();
+#endif
+ void didAssociateByParser();
- void registerImgElement(HTMLImageElement*);
- void removeImgElement(HTMLImageElement*);
-
- bool prepareForSubmission(Event*);
+ void prepareForSubmission(Event*);
void submit();
void submitFromJavaScript();
void reset();
@@ -78,26 +83,21 @@ public:
void setDemoted(bool);
void submitImplicitly(Event*, bool fromImplicitSubmissionTrigger);
- bool formWouldHaveSecureSubmission(const String& url);
String name() const;
bool noValidate() const;
const AtomicString& action() const;
- void setAction(const AtomicString&);
String method() const;
void setMethod(const AtomicString&);
- virtual String target() const;
-
bool wasUserSubmitted() const;
HTMLFormControlElement* defaultButton() const;
bool checkValidity();
- bool checkValidityWithoutDispatchingEvents();
enum AutocompleteResult {
AutocompleteResultSuccess,
@@ -112,38 +112,38 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(autocomplete);
DEFINE_ATTRIBUTE_EVENT_LISTENER(autocompleteerror);
- CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+ RadioButtonGroupScope& radioButtonGroupScope() { return m_radioButtonGroupScope; }
- const Vector<FormAssociatedElement*>& associatedElements() const { return m_associatedElements; }
- const Vector<HTMLImageElement*>& imageElements() const { return m_imageElements; }
+ const FormAssociatedElement::List& associatedElements() const;
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& imageElements();
- void getTextFieldValues(StringPairVector& fieldNamesAndValues) const;
- void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Node>&);
+ void anonymousNamedGetter(const AtomicString& name, bool&, RefPtrWillBeRawPtr<RadioNodeList>&, bool&, RefPtrWillBeRawPtr<Element>&);
private:
explicit HTMLFormElement(Document&);
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual void finishParsingChildren() OVERRIDE;
- virtual void handleLocalEvents(Event*);
+ virtual void handleLocalEvents(Event*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
virtual void copyNonAttributePropertiesFromElement(const Element&) OVERRIDE;
- void submitDialog(PassRefPtr<FormSubmission>);
+ void submitDialog(PassRefPtrWillBeRawPtr<FormSubmission>);
void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
- void scheduleFormSubmission(PassRefPtr<FormSubmission>);
+ void scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission>);
- unsigned formElementIndexWithFormAttribute(Element*, unsigned rangeStart, unsigned rangeEnd);
- unsigned formElementIndex(FormAssociatedElement&);
+ void collectAssociatedElements(Node& root, FormAssociatedElement::List&) const;
+ void collectImageElements(Node& root, WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >&);
// Returns true if the submission should proceed.
bool validateInteractively(Event*);
@@ -151,40 +151,40 @@ private:
// Validates each of the controls, and stores controls of which 'invalid'
// event was not canceled to the specified vector. Returns true if there
// are any invalid controls in this form.
- bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >*, HTMLFormControlElement::CheckValidityDispatchEvents = HTMLFormControlElement::CheckValidityDispatchEventsAllowed);
+ bool checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >*);
- Node* elementFromPastNamesMap(const AtomicString&) const;
- void addToPastNamesMap(Node*, const AtomicString& pastName);
+ Element* elementFromPastNamesMap(const AtomicString&);
+ void addToPastNamesMap(Element*, const AtomicString& pastName);
void removeFromPastNamesMap(HTMLElement&);
- typedef HashMap<AtomicString, Node*> PastNamesMap;
+ typedef WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<Element> > PastNamesMap;
FormSubmission::Attributes m_attributes;
- OwnPtr<PastNamesMap> m_pastNamesMap;
-
- CheckedRadioButtons m_checkedRadioButtons;
-
- unsigned m_associatedElementsBeforeIndex;
- unsigned m_associatedElementsAfterIndex;
- Vector<FormAssociatedElement*> m_associatedElements;
- Vector<HTMLImageElement*> m_imageElements;
+ OwnPtrWillBeMember<PastNamesMap> m_pastNamesMap;
+
+ RadioButtonGroupScope m_radioButtonGroupScope;
+
+ // Do not access m_associatedElements directly. Use associatedElements() instead.
+ FormAssociatedElement::List m_associatedElements;
+ // Do not access m_imageElements directly. Use imageElements() instead.
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > m_imageElements;
+#if !ENABLE(OILPAN)
+ WeakPtrFactory<HTMLFormElement> m_weakPtrFactory;
+#endif
+ bool m_associatedElementsAreDirty;
+ bool m_imageElementsAreDirty;
+ bool m_hasElementsAssociatedByParser;
+ bool m_didFinishParsingChildren;
bool m_wasUserSubmitted;
- bool m_isSubmittingOrPreparingForSubmission;
- bool m_shouldSubmit;
bool m_isInResetFunction;
bool m_wasDemoted;
- void requestAutocompleteTimerFired(Timer<HTMLFormElement>*);
-
- Vector<RefPtr<Event> > m_pendingAutocompleteEvents;
- Timer<HTMLFormElement> m_requestAutocompleteTimer;
+ OwnPtrWillBeMember<GenericEventQueue> m_pendingAutocompleteEventsQueue;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFormElement, hasTagName(HTMLNames::formTag));
-
} // namespace WebCore
#endif // HTMLFormElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl
index 6ba5f418c01..68283fc8058 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl
@@ -18,10 +18,12 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLFormElement : HTMLElement {
+[
+ OverrideBuiltins,
+] interface HTMLFormElement : HTMLElement {
[Reflect=accept_charset] attribute DOMString acceptCharset;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString action;
- [Reflect] attribute DOMString autocomplete;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString action;
+ [Reflect, ReflectOnly="on"|"off", ReflectMissing="on", ReflectInvalid="on"] attribute DOMString autocomplete;
[CustomElementCallbacks] attribute DOMString enctype;
[CustomElementCallbacks] attribute DOMString encoding;
[CustomElementCallbacks] attribute DOMString method;
@@ -31,14 +33,12 @@ interface HTMLFormElement : HTMLElement {
readonly attribute HTMLCollection elements;
readonly attribute long length;
- [ImplementedAs=item] getter Node(unsigned long index);
- [ImplementedAs=anonymousNamedGetter, OverrideBuiltins, NotEnumerable] getter (NodeList or Node)(DOMString name);
+ [ImplementedAs=item] getter Element (unsigned long index);
+ [NotEnumerable] getter (RadioNodeList or Element) (DOMString name);
- [ImplementedAs=submitFromJavaScript, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] void submit();
+ [ImplementedAs=submitFromJavaScript, LogActivity] void submit();
[CustomElementCallbacks] void reset();
boolean checkValidity();
[RuntimeEnabled=RequestAutocomplete] void requestAutocomplete();
- [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocomplete;
- [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocompleteerror;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
index 218a2216167..7f5a19fbf82 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/html/HTMLFrameElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLFrameSetElement.h"
#include "core/rendering/RenderFrame.h"
@@ -40,10 +40,7 @@ inline HTMLFrameElement::HTMLFrameElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFrameElement> HTMLFrameElement::create(Document& document)
-{
- return adoptRef(new HTMLFrameElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLFrameElement)
bool HTMLFrameElement::rendererIsNeeded(const RenderStyle&)
{
@@ -56,15 +53,6 @@ RenderObject* HTMLFrameElement::createRenderer(RenderStyle*)
return new RenderFrame(this);
}
-static inline HTMLFrameSetElement* containingFrameSetElement(Node* node)
-{
- while ((node = node->parentNode())) {
- if (node->hasTagName(framesetTag))
- return toHTMLFrameSetElement(node);
- }
- return 0;
-}
-
bool HTMLFrameElement::noResize() const
{
return hasAttribute(noresizeAttr);
@@ -74,7 +62,7 @@ void HTMLFrameElement::attach(const AttachContext& context)
{
HTMLFrameElementBase::attach(context);
- if (HTMLFrameSetElement* frameSetElement = containingFrameSetElement(this)) {
+ if (HTMLFrameSetElement* frameSetElement = Traversal<HTMLFrameSetElement>::firstAncestor(*this)) {
if (!m_frameBorderSet)
m_frameBorder = frameSetElement->hasFrameBorder();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h
index 72ca10399ab..20ba93597bc 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLFrameElement FINAL : public HTMLFrameElementBase {
public:
- static PassRefPtr<HTMLFrameElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLFrameElement);
bool hasFrameBorder() const { return m_frameBorder; }
@@ -41,19 +41,15 @@ private:
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool allowFullScreen() const { return false; }
-
bool m_frameBorder;
bool m_frameBorderSet;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFrameElement, hasTagName(HTMLNames::frameTag));
-
} // namespace WebCore
#endif // HTMLFrameElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
index 1ab494ce552..ed43c3c69e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
@@ -27,7 +27,7 @@ interface HTMLFrameElement : HTMLElement {
[Reflect] attribute DOMString name;
[Reflect] attribute boolean noResize;
[Reflect] attribute DOMString scrolling;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
// Introduced in DOM Level 2:
[CheckSecurity=Node] readonly attribute Document contentDocument;
@@ -35,10 +35,8 @@ interface HTMLFrameElement : HTMLElement {
// Extensions
readonly attribute Window contentWindow;
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
- [TreatNullAs=NullString, Custom=Setter, MeasureAs=HTMLFrameElementLocation] attribute DOMString location;
-
- readonly attribute long width;
- readonly attribute long height;
+ [MeasureAs=HTMLFrameElementWidth] readonly attribute long width;
+ [MeasureAs=HTMLFrameElementHeight] readonly attribute long height;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp
index fc6bfb98c35..182189a86e5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp
@@ -24,17 +24,17 @@
#include "config.h"
#include "core/html/HTMLFrameElementBase.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/loader/FrameLoader.h"
+#include "core/page/ChromeClient.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/rendering/RenderPart.h"
@@ -63,7 +63,7 @@ bool HTMLFrameElementBase::isURLAllowed() const
return false;
}
- Frame* parentFrame = document().frame();
+ LocalFrame* parentFrame = document().frame();
if (parentFrame)
return parentFrame->isURLAllowed(completeURL);
@@ -76,9 +76,9 @@ void HTMLFrameElementBase::openURL(bool lockBackForwardList)
return;
if (m_URL.isEmpty())
- m_URL = blankURL().string();
+ m_URL = AtomicString(blankURL().string());
- Frame* parentFrame = document().frame();
+ LocalFrame* parentFrame = document().frame();
if (!parentFrame)
return;
@@ -92,9 +92,9 @@ void HTMLFrameElementBase::openURL(bool lockBackForwardList)
if (!loadOrRedirectSubframe(url, m_frameName, lockBackForwardList))
return;
- if (!contentFrame() || scriptURL.isEmpty())
+ if (!contentFrame() || scriptURL.isEmpty() || !contentFrame()->isLocalFrame())
return;
- contentFrame()->script().executeScriptIfJavaScriptURL(scriptURL);
+ toLocalFrame(contentFrame())->script().executeScriptIfJavaScriptURL(scriptURL);
}
void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -125,11 +125,9 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
else if (equalIgnoringCase(value, "no"))
m_scrolling = ScrollbarAlwaysOff;
// FIXME: If we are already attached, this has no effect.
- } else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else if (name == onbeforeunloadAttr) {
+ } else if (name == onbeforeunloadAttr) {
// FIXME: should <frame> elements have beforeunload handlers?
- setAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(this, name, value, eventParameterName()));
} else
HTMLFrameOwnerElement::parseAttribute(name, value);
}
@@ -137,8 +135,6 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
void HTMLFrameElementBase::setNameAndOpenURL()
{
m_frameName = getNameAttribute();
- if (m_frameName.isNull())
- m_frameName = getIdAttribute();
openURL();
}
@@ -163,19 +159,14 @@ void HTMLFrameElementBase::attach(const AttachContext& context)
{
HTMLFrameOwnerElement::attach(context);
- if (RenderPart* part = renderPart()) {
- if (Frame* frame = contentFrame())
- part->setWidget(frame->view());
+ if (renderPart()) {
+ if (Frame* frame = contentFrame()) {
+ if (frame->isLocalFrame())
+ setWidget(toLocalFrame(frame)->view());
+ }
}
}
-KURL HTMLFrameElementBase::location() const
-{
- if (fastHasAttribute(srcdocAttr))
- return KURL(ParsedURLString, "about:srcdoc");
- return document().completeURL(getAttribute(srcAttr));
-}
-
void HTMLFrameElementBase::setLocation(const String& str)
{
m_URL = AtomicString(str);
@@ -196,7 +187,7 @@ void HTMLFrameElementBase::setFocus(bool received)
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);
+ page->focusController().setFocusedFrame(nullptr);
}
}
@@ -206,6 +197,11 @@ bool HTMLFrameElementBase::isURLAttribute(const Attribute& attribute) const
|| HTMLFrameOwnerElement::isURLAttribute(attribute);
}
+bool HTMLFrameElementBase::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || HTMLFrameOwnerElement::hasLegalLinkAttribute(name);
+}
+
bool HTMLFrameElementBase::isHTMLContentAttribute(const Attribute& attribute) const
{
return attribute.name() == srcdocAttr || HTMLFrameOwnerElement::isHTMLContentAttribute(attribute);
@@ -227,4 +223,15 @@ int HTMLFrameElementBase::height()
return renderBox()->height();
}
+// FIXME: Remove this code once we have input routing in the browser
+// process. See http://crbug.com/339659.
+void HTMLFrameElementBase::defaultEventHandler(Event* event)
+{
+ if (contentFrame() && contentFrame()->isRemoteFrameTemporary()) {
+ contentFrame()->chromeClient().forwardInputEvent(contentFrame(), event);
+ return;
+ }
+ HTMLFrameOwnerElement::defaultEventHandler(event);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h
index 9352e4e7056..dc6d9204385 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h
@@ -31,10 +31,7 @@ namespace WebCore {
class HTMLFrameElementBase : public HTMLFrameOwnerElement {
public:
- KURL location() const;
- void setLocation(const String&);
-
- virtual ScrollbarMode scrollingMode() const { return m_scrolling; }
+ virtual ScrollbarMode scrollingMode() const OVERRIDE FINAL { return m_scrolling; }
int marginWidth() const { return m_marginWidth; }
int marginHeight() const { return m_marginHeight; }
@@ -42,7 +39,7 @@ public:
int width();
int height();
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return false; }
protected:
HTMLFrameElementBase(const QualifiedName&, Document&);
@@ -51,20 +48,24 @@ protected:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE FINAL;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
-private:
- virtual bool supportsFocus() const;
- virtual void setFocus(bool) OVERRIDE;
+ // FIXME: Remove this method once we have input routing in the browser
+ // process. See http://crbug.com/339659.
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool isHTMLContentAttribute(const Attribute&) const OVERRIDE;
+private:
+ virtual bool supportsFocus() const OVERRIDE FINAL;
+ virtual void setFocus(bool) OVERRIDE FINAL;
- virtual bool isFrameElementBase() const { return true; }
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE FINAL;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual bool isHTMLContentAttribute(const Attribute&) const OVERRIDE FINAL;
- virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
+ virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; }
+ void setLocation(const String&);
void setNameAndOpenURL();
void openURL(bool lockBackForwardList = true);
@@ -77,12 +78,17 @@ private:
int m_marginHeight;
};
-inline bool isHTMLFrameElementBase(const Node& node)
+inline bool isHTMLFrameElementBase(const Element& element)
+{
+ return isHTMLFrameElement(element) || isHTMLIFrameElement(element);
+}
+
+inline bool isHTMLFrameElementBase(const HTMLElement& element)
{
- return node.isElementNode() && toElement(node).isFrameElementBase();
+ return isHTMLFrameElement(element) || isHTMLIFrameElement(element);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
index aaa73ff224c..3a5fea5d421 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
@@ -23,21 +23,77 @@
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/accessibility/AXObjectCache.h"
#include "core/dom/ExceptionCode.h"
+#include "core/events/Event.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderPart.h"
-#include "core/svg/SVGDocument.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "platform/weborigin/SecurityPolicy.h"
namespace WebCore {
+typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
+static WidgetToParentMap& widgetNewParentMap()
+{
+ DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
+ return map;
+}
+
+static unsigned s_updateSuspendCount = 0;
+
+HTMLFrameOwnerElement::UpdateSuspendScope::UpdateSuspendScope()
+{
+ ++s_updateSuspendCount;
+}
+
+void HTMLFrameOwnerElement::UpdateSuspendScope::performDeferredWidgetTreeOperations()
+{
+ WidgetToParentMap map;
+ widgetNewParentMap().swap(map);
+ WidgetToParentMap::iterator end = map.end();
+ for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
+ Widget* child = it->key.get();
+ ScrollView* currentParent = toScrollView(child->parent());
+ FrameView* newParent = it->value;
+ if (newParent != currentParent) {
+ if (currentParent)
+ currentParent->removeChild(child);
+ if (newParent)
+ newParent->addChild(child);
+ }
+ }
+}
+
+HTMLFrameOwnerElement::UpdateSuspendScope::~UpdateSuspendScope()
+{
+ ASSERT(s_updateSuspendCount > 0);
+ if (s_updateSuspendCount == 1)
+ performDeferredWidgetTreeOperations();
+ --s_updateSuspendCount;
+}
+
+static void moveWidgetToParentSoon(Widget* child, FrameView* parent)
+{
+ if (!s_updateSuspendCount) {
+ if (parent)
+ parent->addChild(child);
+ else if (toScrollView(child->parent()))
+ toScrollView(child->parent())->removeChild(child);
+ return;
+ }
+ widgetNewParentMap().set(child, parent);
+}
+
HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
, m_contentFrame(0)
+ , m_widget(nullptr)
, m_sandboxFlags(SandboxNone)
{
}
@@ -54,7 +110,7 @@ RenderPart* HTMLFrameOwnerElement::renderPart() const
void HTMLFrameOwnerElement::setContentFrame(Frame& frame)
{
// Make sure we will not end up with two frames referencing the same owner element.
- ASSERT(!m_contentFrame || m_contentFrame->ownerElement() != this);
+ ASSERT(!m_contentFrame || m_contentFrame->owner() != this);
// Disconnected frames should not be allowed to load.
ASSERT(inDocument());
m_contentFrame = &frame;
@@ -82,7 +138,8 @@ void HTMLFrameOwnerElement::disconnectContentFrame()
// see if this behavior is really needed as Gecko does not allow this.
if (Frame* frame = contentFrame()) {
RefPtr<Frame> protect(frame);
- frame->loader().frameDetached();
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->loader().frameDetached();
frame->disconnectOwnerElement();
}
}
@@ -95,10 +152,10 @@ HTMLFrameOwnerElement::~HTMLFrameOwnerElement()
Document* HTMLFrameOwnerElement::contentDocument() const
{
- return m_contentFrame ? m_contentFrame->document() : 0;
+ return (m_contentFrame && m_contentFrame->isLocalFrame()) ? toLocalFrame(m_contentFrame)->document() : 0;
}
-DOMWindow* HTMLFrameOwnerElement::contentWindow() const
+LocalDOMWindow* HTMLFrameOwnerElement::contentWindow() const
{
return m_contentFrame ? m_contentFrame->domWindow() : 0;
}
@@ -113,19 +170,59 @@ bool HTMLFrameOwnerElement::isKeyboardFocusable() const
return m_contentFrame && HTMLElement::isKeyboardFocusable();
}
-SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionState& exceptionState) const
+void HTMLFrameOwnerElement::dispatchLoad()
+{
+ dispatchEvent(Event::create(EventTypeNames::load));
+}
+
+Document* HTMLFrameOwnerElement::getSVGDocument(ExceptionState& exceptionState) const
{
Document* doc = contentDocument();
if (doc && doc->isSVGDocument())
- return toSVGDocument(doc);
+ return doc;
return 0;
}
+void HTMLFrameOwnerElement::setWidget(PassRefPtr<Widget> widget)
+{
+ if (widget == m_widget)
+ return;
+
+ if (m_widget) {
+ if (m_widget->parent())
+ moveWidgetToParentSoon(m_widget.get(), 0);
+ m_widget = nullptr;
+ }
+
+ m_widget = widget;
+
+ RenderWidget* renderWidget = toRenderWidget(renderer());
+ if (!renderWidget)
+ return;
+
+ if (m_widget) {
+ renderWidget->updateOnWidgetChange();
+
+ ASSERT(document().view() == renderWidget->frameView());
+ ASSERT(renderWidget->frameView());
+ moveWidgetToParentSoon(m_widget.get(), renderWidget->frameView());
+ }
+
+ if (AXObjectCache* cache = document().existingAXObjectCache())
+ cache->childrenChanged(renderWidget);
+}
+
+Widget* HTMLFrameOwnerElement::ownedWidget() const
+{
+ return m_widget.get();
+}
+
bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const AtomicString& frameName, bool lockBackForwardList)
{
- RefPtr<Frame> parentFrame = document().frame();
- if (contentFrame()) {
- contentFrame()->navigationScheduler().scheduleLocationChange(&document(), url.string(), document().outgoingReferrer(), lockBackForwardList);
+ RefPtr<LocalFrame> parentFrame = document().frame();
+ // FIXME(kenrb): The necessary semantics for RemoteFrames have not been worked out yet, but this will likely need some logic to handle them.
+ if (contentFrame() && contentFrame()->isLocalFrame()) {
+ toLocalFrame(contentFrame())->navigationScheduler().scheduleLocationChange(&document(), url.string(), Referrer(document().outgoingReferrer(), document().referrerPolicy()), lockBackForwardList);
return true;
}
@@ -138,7 +235,7 @@ bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const Atomic
return false;
String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), url, document().outgoingReferrer());
- RefPtr<Frame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, referrer, this);
+ RefPtr<LocalFrame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, Referrer(referrer, document().referrerPolicy()), this);
if (!childFrame) {
parentFrame->loader().checkCompleted();
@@ -153,10 +250,12 @@ bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const Atomic
// FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed.
childFrame->loader().started();
- RenderObject* renderObject = renderer();
FrameView* view = childFrame->view();
+ RenderObject* renderObject = renderer();
+ // We need to test the existence of renderObject and its widget-ness, as
+ // failing to do so causes problems.
if (renderObject && renderObject->isWidget() && view)
- toRenderWidget(renderObject)->setWidget(view);
+ setWidget(view);
// Some loads are performed synchronously (e.g., about:blank and loads
// cancelled by returning a null ResourceRequest from requestFromDelegate).
@@ -164,7 +263,7 @@ bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const Atomic
// before we could connect the signals, so make sure to send the
// completed() signal for the child by hand and mark the load as being
// complete.
- // FIXME: In this case the Frame will have finished loading before
+ // FIXME: In this case the LocalFrame will have finished loading before
// it's being added to the child list. It would be a good idea to
// create the child first, then invoke the loader separately.
if (childFrame->loader().state() == FrameStateComplete && !childFrame->loader().policyDocumentLoader())
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h
index 834ac123c70..b9f4a7bbfe8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h
@@ -21,23 +21,25 @@
#ifndef HTMLFrameOwnerElement_h
#define HTMLFrameOwnerElement_h
+#include "core/dom/Document.h"
+#include "core/frame/FrameOwner.h"
#include "core/html/HTMLElement.h"
#include "wtf/HashCountedSet.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class ExceptionState;
class Frame;
class RenderPart;
-class SVGDocument;
+class Widget;
-class HTMLFrameOwnerElement : public HTMLElement {
+class HTMLFrameOwnerElement : public HTMLElement, public FrameOwner {
public:
virtual ~HTMLFrameOwnerElement();
Frame* contentFrame() const { return m_contentFrame; }
- DOMWindow* contentWindow() const;
+ LocalDOMWindow* contentWindow() const;
Document* contentDocument() const;
void setContentFrame(Frame&);
@@ -50,18 +52,27 @@ public:
// RenderObject when using fallback content.
RenderPart* renderPart() const;
- SVGDocument* getSVGDocument(ExceptionState&) const;
+ Document* getSVGDocument(ExceptionState&) const;
virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; }
- SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
-
virtual bool loadedNonEmptyDocument() const { return false; }
virtual void didLoadNonEmptyDocument() { }
virtual void renderFallbackContent() { }
virtual bool isObjectElement() const { return false; }
+ void setWidget(PassRefPtr<Widget>);
+ Widget* ownedWidget() const;
+
+ class UpdateSuspendScope {
+ public:
+ UpdateSuspendScope();
+ ~UpdateSuspendScope();
+
+ private:
+ void performDeferredWidgetTreeOperations();
+ };
protected:
HTMLFrameOwnerElement(const QualifiedName& tagName, Document&);
@@ -71,13 +82,19 @@ protected:
private:
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool isFrameOwnerElement() const OVERRIDE { return true; }
+ virtual bool isFrameOwnerElement() const OVERRIDE FINAL { return true; }
+
+ // FrameOwner overrides:
+ virtual bool isLocal() const { return true; }
+ virtual SandboxFlags sandboxFlags() const OVERRIDE { return m_sandboxFlags; }
+ virtual void dispatchLoad() OVERRIDE;
Frame* m_contentFrame;
+ RefPtr<Widget> m_widget;
SandboxFlags m_sandboxFlags;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFrameOwnerElement, isFrameOwnerElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLFrameOwnerElement, isFrameOwnerElement());
class SubframeLoadingDisabler {
public:
@@ -94,6 +111,8 @@ public:
static bool canLoadFrame(HTMLFrameOwnerElement& owner)
{
+ if (owner.document().unloadStarted())
+ return false;
for (Node* node = &owner; node; node = node->parentOrShadowHostNode()) {
if (disabledSubtreeRoots().contains(node))
return false;
@@ -111,6 +130,8 @@ private:
Node& m_root;
};
+DEFINE_TYPE_CASTS(HTMLFrameOwnerElement, FrameOwner, owner, owner->isLocal(), owner.isLocal());
+
} // namespace WebCore
#endif // HTMLFrameOwnerElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
index cfa41341e71..0a00f463f19 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
@@ -24,24 +24,23 @@
#include "config.h"
#include "core/html/HTMLFrameSetElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLFrameElement.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderFrameSet.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLFrameSetElement::HTMLFrameSetElement(Document& document)
+inline HTMLFrameSetElement::HTMLFrameSetElement(Document& document)
: HTMLElement(framesetTag, document)
, m_border(6)
, m_borderSet(false)
@@ -54,10 +53,7 @@ HTMLFrameSetElement::HTMLFrameSetElement(Document& document)
setHasCustomStyleCallbacks();
}
-PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(Document& document)
-{
- return adoptRef(new HTMLFrameSetElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLFrameSetElement)
bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -79,12 +75,12 @@ void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const Atomic
if (name == rowsAttr) {
if (!value.isNull()) {
m_rowLengths = parseListOfDimensions(value.string());
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
} else if (name == colsAttr) {
if (!value.isNull()) {
m_colLengths = parseListOfDimensions(value.string());
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
} else if (name == frameborderAttr) {
if (!value.isNull()) {
@@ -109,45 +105,45 @@ void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const Atomic
} else if (name == bordercolorAttr)
m_borderColorSet = !value.isEmpty();
else if (name == onloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onbeforeunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpagehideAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpageshowAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onblurAttr)
- document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onerrorAttr)
- document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusinAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focusin, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::focusin, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusoutAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focusout, createAttributeEventListener(document().frame(), name, value));
-#if ENABLE(ORIENTATION_EVENTS)
- else if (name == onorientationchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value));
-#endif
+ document().setWindowAttributeEventListener(EventTypeNames::focusout, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (RuntimeEnabledFeatures::orientationEventEnabled() && name == onorientationchangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onhashchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onmessageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onresizeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onscrollAttr)
- document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onstorageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == ononlineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onofflineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpopstateAttr)
- document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (name == onlanguagechangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::languagechange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else
HTMLElement::parseAttribute(name, value);
}
@@ -171,21 +167,17 @@ void HTMLFrameSetElement::attach(const AttachContext& context)
{
// 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 = toHTMLFrameSetElement(node);
- if (!m_frameborderSet)
- m_frameborder = frameset->hasFrameBorder();
- if (m_frameborder) {
- if (!m_borderSet)
- m_border = frameset->border();
- if (!m_borderColorSet)
- m_borderColorSet = frameset->hasBorderColor();
- }
- if (!m_noresize)
- m_noresize = frameset->noResize();
- break;
+ if (HTMLFrameSetElement* frameset = Traversal<HTMLFrameSetElement>::firstAncestor(*this)) {
+ if (!m_frameborderSet)
+ m_frameborder = frameset->hasFrameBorder();
+ if (m_frameborder) {
+ if (!m_borderSet)
+ m_border = frameset->border();
+ if (!m_borderColorSet)
+ m_borderColorSet = frameset->hasBorderColor();
}
+ if (!m_noresize)
+ m_noresize = frameset->noResize();
}
HTMLElement::attach(context);
@@ -214,17 +206,17 @@ Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNo
void HTMLFrameSetElement::willRecalcStyle(StyleRecalcChange)
{
if (needsStyleRecalc() && renderer()) {
- renderer()->setNeedsLayout();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
clearNeedsStyleRecalc();
}
}
-DOMWindow* HTMLFrameSetElement::anonymousNamedGetter(const AtomicString& name)
+LocalDOMWindow* HTMLFrameSetElement::anonymousNamedGetter(const AtomicString& name)
{
- Node* frameNode = children()->namedItem(name);
- if (!frameNode || !frameNode->hasTagName(HTMLNames::frameTag))
+ Element* frameElement = children()->namedItem(name);
+ if (!isHTMLFrameElement(frameElement))
return 0;
- Document* document = toHTMLFrameElement(frameNode)->contentDocument();
+ Document* document = toHTMLFrameElement(frameElement)->contentDocument();
if (!document || !document->frame())
return 0;
return document->domWindow();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h
index 3138495cd2b..36ce2073a65 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h
@@ -24,6 +24,7 @@
#ifndef HTMLFrameSetElement_h
#define HTMLFrameSetElement_h
+#include "core/dom/Document.h"
#include "core/html/HTMLDimension.h"
#include "core/html/HTMLElement.h"
@@ -31,7 +32,7 @@ namespace WebCore {
class HTMLFrameSetElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLFrameSetElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLFrameSetElement);
bool hasFrameBorder() const { return m_frameborder; }
bool noResize() const { return m_noresize; }
@@ -45,17 +46,15 @@ public:
const Vector<HTMLDimension>& rowLengths() const { return m_rowLengths; }
const Vector<HTMLDimension>& colLengths() const { return m_colLengths; }
- DOMWindow* anonymousNamedGetter(const AtomicString&);
+ LocalDOMWindow* anonymousNamedGetter(const AtomicString&);
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(resize);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll);
-
-#if ENABLE(ORIENTATION_EVENTS)
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
-#endif
private:
explicit HTMLFrameSetElement(Document&);
@@ -65,10 +64,10 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
@@ -86,8 +85,6 @@ private:
bool m_noresize;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFrameSetElement, hasTagName(HTMLNames::framesetTag));
-
} // namespace WebCore
#endif // HTMLFrameSetElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl
index 38a5f21424b..e7c6a243cf8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl
@@ -18,18 +18,21 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLFrameSetElement : HTMLElement {
- [ImplementedAs=anonymousNamedGetter, OverrideBuiltins, NotEnumerable] getter Window (DOMString name);
+[
+ OverrideBuiltins,
+] interface HTMLFrameSetElement : HTMLElement {
+ [NotEnumerable] getter Window (DOMString name);
[Reflect] attribute DOMString cols;
[Reflect] attribute DOMString rows;
- [Conditional=ORIENTATION_EVENTS] attribute EventHandler onorientationchange;
+ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
// Overrides of GlobalEventHandler attributes
attribute EventHandler onblur;
attribute EventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onload;
+ attribute EventHandler onresize;
attribute EventHandler onscroll;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
index 7a6edf88eb5..9df1cad4af9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLHRElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
@@ -33,16 +33,13 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLHRElement::HTMLHRElement(Document& document)
+inline HTMLHRElement::HTMLHRElement(Document& document)
: HTMLElement(hrTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHRElement> HTMLHRElement::create(Document& document)
-{
- return adoptRef(new HTMLHRElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLHRElement)
bool HTMLHRElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -76,11 +73,13 @@ void HTMLHRElement::collectStyleForPresentationAttribute(const QualifiedName& na
addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
} else if (name == noshadeAttr) {
- addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
+ if (!hasAttribute(colorAttr)) {
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
- RefPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
- style->setProperty(CSSPropertyBorderColor, darkGrayValue);
- style->setProperty(CSSPropertyBackgroundColor, darkGrayValue);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
+ style->setProperty(CSSPropertyBorderColor, darkGrayValue);
+ style->setProperty(CSSPropertyBackgroundColor, darkGrayValue);
+ }
} else if (name == sizeAttr) {
StringImpl* si = value.impl();
int size = si->toInt();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h
index ec5bcb01442..79b2fc410b7 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h
@@ -29,9 +29,9 @@ namespace WebCore {
class HTMLHRElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHRElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLHRElement);
- virtual bool canContainRangeEndPoint() const { return hasChildNodes(); }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return hasChildren(); }
private:
explicit HTMLHRElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp
index 8a25aa6a51d..494154590ac 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp
@@ -24,21 +24,18 @@
#include "config.h"
#include "core/html/HTMLHeadElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLHeadElement::HTMLHeadElement(Document& document)
+inline HTMLHeadElement::HTMLHeadElement(Document& document)
: HTMLElement(headTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(Document& document)
-{
- return adoptRef(new HTMLHeadElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLHeadElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h
index 7abcac7df45..4a68f2e1e85 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h
@@ -30,14 +30,12 @@ namespace WebCore {
class HTMLHeadElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHeadElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLHeadElement);
private:
explicit HTMLHeadElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(HTMLHeadElement, hasTagName(HTMLNames::headTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl
index 738deb73d92..fb54cb5ab73 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl
@@ -18,5 +18,5 @@
*/
interface HTMLHeadElement : HTMLElement {
- [Reflect, TreatNullAs=NullString, MeasureAs=HTMLHeadElementProfile] attribute DOMString profile;
+ [Reflect, TreatNullAs=NullString, DeprecateAs=HTMLHeadElementProfile] attribute DOMString profile;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp
index 7e9c986e4b7..fb0431cd999 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp
@@ -31,9 +31,6 @@ inline HTMLHeadingElement::HTMLHeadingElement(const QualifiedName& tagName, Docu
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHeadingElement> HTMLHeadingElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLHeadingElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLHeadingElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h
index e99bac5867b..fb0a4d52761 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLHeadingElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHeadingElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLHeadingElement);
private:
HTMLHeadingElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp
index e4a56c917c4..991176eee99 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp
@@ -24,28 +24,25 @@
#include "config.h"
#include "core/html/HTMLHtmlElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentParser.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/Frame.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLHtmlElement::HTMLHtmlElement(Document& document)
+inline HTMLHtmlElement::HTMLHtmlElement(Document& document)
: HTMLElement(htmlTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(Document& document)
-{
- return adoptRef(new HTMLHtmlElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLHtmlElement)
bool HTMLHtmlElement::isURLAttribute(const Attribute& attribute) const
{
@@ -65,7 +62,7 @@ void HTMLHtmlElement::insertedByParser()
if (!documentLoader)
return;
- const AtomicString& manifest = getAttribute(manifestAttr);
+ const AtomicString& manifest = fastGetAttribute(manifestAttr);
if (manifest.isEmpty())
documentLoader->applicationCacheHost()->selectCacheWithoutManifest();
else
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h
index 4976aac0c8c..77f43061f74 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLHtmlElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHtmlElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLHtmlElement);
void insertedByParser();
@@ -40,18 +40,6 @@ private:
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
};
-inline bool isHTMLHtmlElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::htmlTag);
-}
-
-inline bool isHTMLHtmlElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::htmlTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLHtmlElement, hasTagName(HTMLNames::htmlTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl
index 3e329da57d1..3099de60b2d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl
@@ -19,5 +19,4 @@
interface HTMLHtmlElement : HTMLElement {
[Reflect] attribute DOMString version;
- [Reflect, TreatNullAs=NullString, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, MeasureAs=HTMLHtmlElementManifest] attribute DOMString manifest;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
index 016fba4ec0e..b447e52765a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLIFrameElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLDocument.h"
#include "core/rendering/RenderIFrame.h"
@@ -39,17 +39,13 @@ inline HTMLIFrameElement::HTMLIFrameElement(Document& document)
, m_didLoadNonEmptyDocument(false)
{
ScriptWrappable::init(this);
- setHasCustomStyleCallbacks();
}
-PassRefPtr<HTMLIFrameElement> HTMLIFrameElement::create(Document& document)
-{
- return adoptRef(new HTMLIFrameElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLIFrameElement)
bool HTMLIFrameElement::isPresentationAttribute(const QualifiedName& name) const
{
- if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr || name == seamlessAttr)
+ if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr)
return true;
return HTMLFrameElementBase::isPresentationAttribute(name);
}
@@ -63,7 +59,7 @@ void HTMLIFrameElement::collectStyleForPresentationAttribute(const QualifiedName
else if (name == alignAttr)
applyAlignmentAttributeToStyle(value, style);
else if (name == frameborderAttr) {
- // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
+ // LocalFrame 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 (!value.toInt()) {
// Add a rule that nulls out our border width.
@@ -87,12 +83,9 @@ void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomicSt
setSandboxFlags(value.isNull() ? SandboxNone : parseSandboxPolicy(value, invalidTokens));
if (!invalidTokens.isNull())
document().addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
- } else if (name == seamlessAttr) {
- // If we're adding or removing the seamless attribute, we need to force the content document to recalculate its StyleResolver.
- if (contentDocument())
- contentDocument()->styleResolverChanged(RecalcStyleDeferred);
- } else
+ } else {
HTMLFrameElementBase::parseAttribute(name, value);
+ }
}
bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style)
@@ -120,20 +113,6 @@ void HTMLIFrameElement::removedFrom(ContainerNode* insertionPoint)
toHTMLDocument(document()).removeExtraNamedItem(m_name);
}
-bool HTMLIFrameElement::shouldDisplaySeamlessly() const
-{
- return contentDocument() && contentDocument()->shouldDisplaySeamlesslyWithParent();
-}
-
-void HTMLIFrameElement::didRecalcStyle(StyleRecalcChange styleChange)
-{
- if (!shouldDisplaySeamlessly())
- return;
- Document* childDocument = contentDocument();
- if (shouldRecalcStyle(styleChange, childDocument))
- contentDocument()->recalcStyle(styleChange);
-}
-
bool HTMLIFrameElement::isInteractiveContent() const
{
return true;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h
index eab2678af2c..9017d774a22 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h
@@ -30,9 +30,7 @@ namespace WebCore {
class HTMLIFrameElement FINAL : public HTMLFrameElementBase {
public:
- static PassRefPtr<HTMLIFrameElement> create(Document&);
-
- bool shouldDisplaySeamlessly() const;
+ DECLARE_NODE_FACTORY(HTMLIFrameElement);
private:
explicit HTMLIFrameElement(Document&);
@@ -44,10 +42,8 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
-
- virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual bool loadedNonEmptyDocument() const OVERRIDE { return m_didLoadNonEmptyDocument; }
virtual void didLoadNonEmptyDocument() OVERRIDE { m_didLoadNonEmptyDocument = true; }
@@ -57,8 +53,6 @@ private:
bool m_didLoadNonEmptyDocument;
};
-DEFINE_NODE_TYPE_CASTS(HTMLIFrameElement, hasTagName(HTMLNames::iframeTag));
-
} // namespace WebCore
#endif // HTMLIFrameElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
index d8a8a8eb700..90c3a7a77f9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
@@ -27,9 +27,8 @@ interface HTMLIFrameElement : HTMLElement {
[Reflect, TreatNullAs=NullString] attribute DOMString marginWidth;
[Reflect] attribute DOMString name;
[Reflect, TreatNullAs=NullString] attribute DOMString sandbox;
- [Reflect, RuntimeEnabled=SeamlessIFrames] attribute boolean seamless;
[Reflect] attribute DOMString scrolling;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly, LogPreviousValue] attribute DOMString src;
[Reflect] attribute DOMString srcdoc;
[Reflect] attribute DOMString width;
@@ -39,5 +38,7 @@ interface HTMLIFrameElement : HTMLElement {
// Extensions
readonly attribute Window contentWindow;
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index d7d8c971b57..cd7063cdcf0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -23,60 +23,84 @@
#include "config.h"
#include "core/html/HTMLImageElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
+#include "core/MediaTypeNames.h"
+#include "core/css/MediaQueryMatcher.h"
+#include "core/css/MediaValuesCached.h"
+#include "core/css/parser/SizesAttributeParser.h"
#include "core/dom/Attribute.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
#include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLFormElement.h"
+#include "core/html/HTMLSourceElement.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/rendering/RenderImage.h"
-
-using namespace std;
+#include "platform/MIMETypeRegistry.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form)
+HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bool createdByParser)
: HTMLElement(imgTag, document)
- , m_imageLoader(this)
- , m_form(form)
+ , m_imageLoader(HTMLImageLoader::create(this))
, m_compositeOperator(CompositeSourceOver)
, m_imageDevicePixelRatio(1.0f)
+ , m_formWasSetByParser(false)
+ , m_elementCreatedByParser(createdByParser)
{
ScriptWrappable::init(this);
- if (form)
- form->registerImgElement(this);
+ if (form && form->inDocument()) {
+#if ENABLE(OILPAN)
+ m_form = form;
+#else
+ m_form = form->createWeakPtr();
+#endif
+ m_formWasSetByParser = true;
+ m_form->associate(*this);
+ m_form->didAssociateByParser();
+ }
}
-PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& document)
{
- return adoptRef(new HTMLImageElement(document));
+ return adoptRefWillBeNoop(new HTMLImageElement(document));
}
-PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
- return adoptRef(new HTMLImageElement(document, form));
+ return adoptRefWillBeNoop(new HTMLImageElement(document, form, createdByParser));
}
HTMLImageElement::~HTMLImageElement()
{
+#if !ENABLE(OILPAN)
if (m_form)
- m_form->removeImgElement(this);
+ m_form->disassociate(*this);
+#endif
+}
+
+void HTMLImageElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageLoader);
+ visitor->trace(m_form);
+ HTMLElement::trace(visitor);
}
-PassRefPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, int width, int height)
+PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, int width, int height)
{
- RefPtr<HTMLImageElement> image = adoptRef(new HTMLImageElement(document));
+ RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImageElement(document));
if (width)
image->setWidth(width);
if (height)
image->setHeight(height);
+ image->m_elementCreatedByParser = false;
return image.release();
}
@@ -116,7 +140,49 @@ const AtomicString HTMLImageElement::imageSourceURL() const
HTMLFormElement* HTMLImageElement::formOwner() const
{
- return findFormAncestor();
+ return m_form.get();
+}
+
+void HTMLImageElement::formRemovedFromTree(const Node& formRoot)
+{
+ ASSERT(m_form);
+ if (highestAncestorOrSelf() != formRoot)
+ resetFormOwner();
+}
+
+void HTMLImageElement::resetFormOwner()
+{
+ m_formWasSetByParser = false;
+ HTMLFormElement* nearestForm = findFormAncestor();
+ if (m_form) {
+ if (nearestForm == m_form.get())
+ return;
+ m_form->disassociate(*this);
+ }
+ if (nearestForm) {
+#if ENABLE(OILPAN)
+ m_form = nearestForm;
+#else
+ m_form = nearestForm->createWeakPtr();
+#endif
+ m_form->associate(*this);
+ } else {
+#if ENABLE(OILPAN)
+ m_form = nullptr;
+#else
+ m_form = WeakPtr<HTMLFormElement>();
+#endif
+ }
+}
+
+void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidate& candidate)
+{
+ m_bestFitImageURL = candidate.url();
+ float candidateDensity = candidate.density();
+ if (candidateDensity >= 0)
+ m_imageDevicePixelRatio = 1.0 / candidateDensity;
+ if (renderer() && renderer()->isImage())
+ toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
}
void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -124,29 +190,18 @@ void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (name == altAttr) {
if (renderer() && renderer()->isImage())
toRenderImage(renderer())->updateAltText();
- } else if (name == srcAttr || name == srcsetAttr) {
- if (RuntimeEnabledFeatures::srcsetEnabled()) {
- ImageCandidate candidate = bestFitSourceForImageAttributes(document().devicePixelRatio(), fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
- m_bestFitImageURL = candidate.toString();
- float candidateScaleFactor = candidate.scaleFactor();
- if (candidateScaleFactor > 0)
- m_imageDevicePixelRatio = 1 / candidateScaleFactor;
- if (renderer() && renderer()->isImage())
- toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
- }
- m_imageLoader.updateFromElementIgnoringPreviousError();
- }
- else if (name == usemapAttr)
+ } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
+ selectSourceURL(UpdateIgnorePreviousError);
+ } else if (name == usemapAttr) {
setIsLink(!value.isNull());
- else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else if (name == compositeAttr) {
+ } else if (name == compositeAttr) {
// FIXME: images don't support blend modes in their compositing attribute.
blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp))
m_compositeOperator = CompositeSourceOver;
- } else
+ } else {
HTMLElement::parseAttribute(name, value);
+ }
}
const AtomicString& HTMLImageElement::altText() const
@@ -154,10 +209,54 @@ const AtomicString& 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
- if (!getAttribute(altAttr).isNull())
- return getAttribute(altAttr);
+ const AtomicString& alt = fastGetAttribute(altAttr);
+ if (!alt.isNull())
+ return alt;
// fall back to title attribute
- return getAttribute(titleAttr);
+ return fastGetAttribute(titleAttr);
+}
+
+static bool supportedImageType(const String& type)
+{
+ return MIMETypeRegistry::isSupportedImageResourceMIMEType(type);
+}
+
+// http://picture.responsiveimages.org/#update-source-set
+ImageCandidate HTMLImageElement::findBestFitImageFromPictureParent()
+{
+ ASSERT(isMainThread());
+ Node* parent = parentNode();
+ if (!parent || !isHTMLPictureElement(*parent))
+ return ImageCandidate();
+ for (Node* child = parent->firstChild(); child; child = child->nextSibling()) {
+ if (child == this)
+ return ImageCandidate();
+
+ if (!isHTMLSourceElement(*child))
+ continue;
+
+ HTMLSourceElement* source = toHTMLSourceElement(child);
+ String srcset = source->fastGetAttribute(srcsetAttr);
+ if (srcset.isEmpty())
+ continue;
+ String type = source->fastGetAttribute(typeAttr);
+ if (!type.isEmpty() && !supportedImageType(type))
+ continue;
+
+ String media = source->fastGetAttribute(mediaAttr);
+ if (!media.isEmpty()) {
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media);
+ if (!document().mediaQueryMatcher().evaluate(mediaQueries.get()))
+ continue;
+ }
+
+ unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source->fastGetAttribute(sizesAttr), MediaValuesCached::create(document()));
+ ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().devicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
+ if (candidate.isEmpty())
+ continue;
+ return candidate;
+ }
+ return ImageCandidate();
}
RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
@@ -183,7 +282,7 @@ void HTMLImageElement::attach(const AttachContext& context)
{
HTMLElement::attach(context);
- if (renderer() && renderer()->isImage() && !m_imageLoader.hasPendingBeforeLoadEvent()) {
+ if (renderer() && renderer()->isImage()) {
RenderImage* renderImage = toRenderImage(renderer());
RenderImageResource* renderImageResource = renderImage->imageResource();
if (renderImageResource->hasImage())
@@ -191,41 +290,40 @@ void HTMLImageElement::attach(const AttachContext& context)
// 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())
+ if (!imageLoader().image() && !renderImageResource->cachedImage())
renderImage->setImageSizeForAltText();
else
- renderImageResource->setImageResource(m_imageLoader.image());
+ renderImageResource->setImageResource(imageLoader().image());
}
}
Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint)
{
- // m_form can be non-null if it was set in constructor.
- if (m_form && insertionPoint->highestAncestor() != m_form->highestAncestor()) {
- m_form->removeImgElement(this);
- m_form = 0;
- }
+ if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_form->highestAncestorOrSelf())
+ resetFormOwner();
- if (!m_form) {
- m_form = findFormAncestor();
- if (m_form)
- m_form->registerImgElement(this);
+ bool imageWasModified = false;
+ if (RuntimeEnabledFeatures::pictureEnabled()) {
+ ImageCandidate candidate = findBestFitImageFromPictureParent();
+ if (!candidate.isEmpty()) {
+ setBestFitURLAndDPRFromImageCandidate(candidate);
+ imageWasModified = true;
+ }
}
// If we have been inserted from a renderer-less document,
// our loader may have not fetched the image, so do it now.
- if (insertionPoint->inDocument() && !m_imageLoader.image())
- m_imageLoader.updateFromElement();
+ if ((insertionPoint->inDocument() && !imageLoader().image()) || imageWasModified)
+ imageLoader().updateFromElement(m_elementCreatedByParser ? ImageLoader::ForceLoadImmediately : ImageLoader::LoadNormally);
return HTMLElement::insertedInto(insertionPoint);
}
void HTMLImageElement::removedFrom(ContainerNode* insertionPoint)
{
- if (m_form)
- m_form->removeImgElement(this);
- m_form = 0;
+ if (!m_form || m_form->highestAncestorOrSelf() != highestAncestorOrSelf())
+ resetFormOwner();
HTMLElement::removedFrom(insertionPoint);
}
@@ -239,8 +337,8 @@ int HTMLImageElement::width(bool ignorePendingStylesheets)
return width;
// if the image is available, use its width
- if (m_imageLoader.image())
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).width();
+ if (imageLoader().image())
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).width();
}
if (ignorePendingStylesheets)
@@ -262,8 +360,8 @@ int HTMLImageElement::height(bool ignorePendingStylesheets)
return height;
// if the image is available, use its height
- if (m_imageLoader.image())
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height();
+ if (imageLoader().image())
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).height();
}
if (ignorePendingStylesheets)
@@ -277,18 +375,30 @@ int HTMLImageElement::height(bool ignorePendingStylesheets)
int HTMLImageElement::naturalWidth() const
{
- if (!m_imageLoader.image())
+ if (!imageLoader().image())
return 0;
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).width();
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).width();
}
int HTMLImageElement::naturalHeight() const
{
- if (!m_imageLoader.image())
+ if (!imageLoader().image())
return 0;
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height();
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).height();
+}
+
+const String& HTMLImageElement::currentSrc() const
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/edits.html#dom-img-currentsrc
+ // The currentSrc IDL attribute must return the img element's current request's current URL.
+ // Initially, the pending request turns into current request when it is either available or broken.
+ // We use the image's dimensions as a proxy to it being in any of these states.
+ if (!imageLoader().image() || !imageLoader().image()->image() || !imageLoader().image()->image()->width())
+ return emptyAtom;
+
+ return imageLoader().image()->url().string();
}
bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
@@ -300,9 +410,19 @@ bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
|| HTMLElement::isURLAttribute(attribute);
}
+bool HTMLImageElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLImageElement::subResourceAttributeName() const
+{
+ return srcAttr;
+}
+
const AtomicString& HTMLImageElement::alt() const
{
- return getAttribute(altAttr);
+ return fastGetAttribute(altAttr);
}
bool HTMLImageElement::draggable() const
@@ -355,21 +475,12 @@ int HTMLImageElement::y() const
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)));
+ return imageLoader().imageComplete();
}
void HTMLImageElement::didMoveToNewDocument(Document& oldDocument)
{
- m_imageLoader.elementDidMoveToNewDocument();
+ imageLoader().elementDidMoveToNewDocument();
HTMLElement::didMoveToNewDocument(oldDocument);
}
@@ -389,10 +500,10 @@ bool HTMLImageElement::isServerMap() const
Image* HTMLImageElement::imageContents()
{
- if (!m_imageLoader.imageComplete())
+ if (!imageLoader().imageComplete())
return 0;
- return m_imageLoader.image()->image();
+ return imageLoader().image()->image();
}
bool HTMLImageElement::isInteractiveContent() const
@@ -400,4 +511,86 @@ bool HTMLImageElement::isInteractiveContent() const
return fastHasAttribute(usemapAttr);
}
+PassRefPtr<Image> HTMLImageElement::getSourceImageForCanvas(SourceImageMode, SourceImageStatus* status) const
+{
+ if (!complete() || !cachedImage()) {
+ *status = IncompleteSourceImageStatus;
+ return nullptr;
+ }
+
+ if (cachedImage()->errorOccurred()) {
+ *status = UndecodableSourceImageStatus;
+ return nullptr;
+ }
+
+ RefPtr<Image> sourceImage = cachedImage()->imageForRenderer(renderer());
+
+ // We need to synthesize a container size if a renderer is not available to provide one.
+ if (!renderer() && sourceImage->usesContainerSize())
+ sourceImage->setContainerSize(sourceImage->size());
+
+ *status = NormalSourceImageStatus;
+ return sourceImage.release();
+}
+
+bool HTMLImageElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+ ImageResource* image = cachedImage();
+ if (!image)
+ return false;
+ return !image->isAccessAllowed(destinationSecurityOrigin);
+}
+
+FloatSize HTMLImageElement::sourceSize() const
+{
+ ImageResource* image = cachedImage();
+ if (!image)
+ return FloatSize();
+ LayoutSize size;
+ size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure about this.
+
+ return size;
+}
+
+FloatSize HTMLImageElement::defaultDestinationSize() const
+{
+ ImageResource* image = cachedImage();
+ if (!image)
+ return FloatSize();
+ LayoutSize size;
+ size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure about this.
+ if (renderer() && renderer()->isRenderImage() && image->image() && !image->image()->hasRelativeWidth())
+ size.scale(toRenderImage(renderer())->imageDevicePixelRatio());
+ return size;
+}
+
+void HTMLImageElement::selectSourceURL(UpdateFromElementBehavior behavior)
+{
+ bool foundURL = false;
+ if (RuntimeEnabledFeatures::pictureEnabled()) {
+ ImageCandidate candidate = findBestFitImageFromPictureParent();
+ if (!candidate.isEmpty()) {
+ setBestFitURLAndDPRFromImageCandidate(candidate);
+ foundURL = true;
+ }
+ }
+
+ if (!foundURL) {
+ unsigned effectiveSize = 0;
+ if (RuntimeEnabledFeatures::pictureSizesEnabled())
+ effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttribute(sizesAttr), MediaValuesCached::create(document()));
+ ImageCandidate candidate = bestFitSourceForImageAttributes(document().devicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
+ setBestFitURLAndDPRFromImageCandidate(candidate);
+ }
+ if (behavior == UpdateIgnorePreviousError)
+ imageLoader().updateFromElementIgnoringPreviousError();
+ else
+ imageLoader().updateFromElement();
+}
+
+const KURL& HTMLImageElement::sourceURL() const
+{
+ return cachedImage()->response().url();
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 05c5d81db3f..4328dceceba 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -26,26 +26,30 @@
#include "core/html/HTMLElement.h"
#include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/graphics/GraphicsTypes.h"
+#include "wtf/WeakPtr.h"
namespace WebCore {
class HTMLFormElement;
+class ImageCandidate;
-class HTMLImageElement FINAL : public HTMLElement {
- friend class HTMLFormElement;
+class HTMLImageElement FINAL : public HTMLElement, public CanvasImageSource {
public:
- static PassRefPtr<HTMLImageElement> create(Document&);
- static PassRefPtr<HTMLImageElement> create(Document&, HTMLFormElement*);
- static PassRefPtr<HTMLImageElement> createForJSConstructor(Document&, int width, int height);
+ static PassRefPtrWillBeRawPtr<HTMLImageElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLImageElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLImageElement> createForJSConstructor(Document&, int width, int height);
virtual ~HTMLImageElement();
+ virtual void trace(Visitor*) OVERRIDE;
int width(bool ignorePendingStylesheets = false);
int height(bool ignorePendingStylesheets = false);
int naturalWidth() const;
int naturalHeight() const;
+ const String& currentSrc() const;
bool isServerMap() const;
@@ -53,10 +57,10 @@ public:
CompositeOperator compositeOperator() const { return m_compositeOperator; }
- ImageResource* cachedImage() const { return m_imageLoader.image(); }
- void setImageResource(ImageResource* i) { m_imageLoader.setImage(i); };
+ ImageResource* cachedImage() const { return imageLoader().image(); }
+ void setImageResource(ImageResource* i) { imageLoader().setImage(i); };
- void setLoadManually(bool loadManually) { m_imageLoader.setLoadManually(loadManually); }
+ void setLoadManually(bool loadManually) { imageLoader().setLoadManually(loadManually); }
const AtomicString& alt() const;
@@ -72,19 +76,33 @@ public:
bool complete() const;
- bool hasPendingActivity() const { return m_imageLoader.hasPendingActivity(); }
+ bool hasPendingActivity() const { return imageLoader().hasPendingActivity(); }
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
- void addClient(ImageLoaderClient* client) { m_imageLoader.addClient(client); }
- void removeClient(ImageLoaderClient* client) { m_imageLoader.removeClient(client); }
+ void addClient(ImageLoaderClient* client) { imageLoader().addClient(client); }
+ void removeClient(ImageLoaderClient* client) { imageLoader().removeClient(client); }
virtual const AtomicString imageSourceURL() const OVERRIDE;
virtual HTMLFormElement* formOwner() const OVERRIDE;
-
+ void formRemovedFromTree(const Node& formRoot);
+
+ // CanvasImageSourceImplementations
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const;
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+ virtual FloatSize defaultDestinationSize() const OVERRIDE;
+ virtual const KURL& sourceURL() const OVERRIDE;
+
+ enum UpdateFromElementBehavior {
+ UpdateNormal,
+ UpdateIgnorePreviousError
+ };
+ // public so that HTMLPictureElement can call this as well.
+ void selectSourceURL(UpdateFromElementBehavior);
protected:
- explicit HTMLImageElement(Document&, HTMLFormElement* = 0);
+ explicit HTMLImageElement(Document&, HTMLFormElement* = 0, bool createdByParser = false);
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
@@ -96,15 +114,15 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool canStartSelection() const;
+ virtual bool canStartSelection() const OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
- virtual bool draggable() const;
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool draggable() const OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
@@ -113,15 +131,24 @@ private:
virtual bool isInteractiveContent() const OVERRIDE;
virtual Image* imageContents() OVERRIDE;
- HTMLImageLoader m_imageLoader;
- HTMLFormElement* m_form;
+ void resetFormOwner();
+ ImageCandidate findBestFitImageFromPictureParent();
+ void setBestFitURLAndDPRFromImageCandidate(const ImageCandidate&);
+ HTMLImageLoader& imageLoader() const { return *m_imageLoader; }
+
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
+#if ENABLE(OILPAN)
+ Member<HTMLFormElement> m_form;
+#else
+ WeakPtr<HTMLFormElement> m_form;
+#endif
CompositeOperator m_compositeOperator;
AtomicString m_bestFitImageURL;
float m_imageDevicePixelRatio;
+ bool m_formWasSetByParser;
+ bool m_elementCreatedByParser;
};
-DEFINE_NODE_TYPE_CASTS(HTMLImageElement, hasTagName(HTMLNames::imgTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl
index a5480236fd6..1914a5fad72 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl
@@ -21,28 +21,33 @@
// FIXME: NamedConstructor does not support optional without Default. Fortunately using Undefined makes
// us use 0 which happens to be the default width and height anyway.
[
- NamedConstructor=Image([Default=Undefined] optional long width, [Default=Undefined] optional long height)
+ NamedConstructor=Image([Default=Undefined] optional long width, [Default=Undefined] optional long height),
+ ConstructorCallWith=Document
] interface HTMLImageElement : HTMLElement {
[Reflect] attribute DOMString align;
[Reflect] attribute DOMString alt;
[Reflect, TreatNullAs=NullString] attribute DOMString border;
readonly attribute boolean complete;
- [Reflect] attribute DOMString crossOrigin;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
attribute long height;
[Reflect] attribute long hspace;
[Reflect] attribute boolean isMap;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString longDesc;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString lowsrc;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString longDesc;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString lowsrc;
[Reflect] attribute DOMString name;
readonly attribute long naturalHeight;
readonly attribute long naturalWidth;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
- [Reflect, RuntimeEnabled=Srcset] attribute DOMString srcset;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
+ [Reflect] attribute DOMString srcset;
+ [Reflect, RuntimeEnabled=PictureSizes] attribute DOMString sizes;
+ [RuntimeEnabled=PictureSizes] readonly attribute DOMString currentSrc;
[Reflect] attribute DOMString useMap;
[Reflect] attribute long vspace;
attribute long width;
// Extensions
- readonly attribute long x;
- readonly attribute long y;
+ [MeasureAs=HTMLImageElementX] readonly attribute long x;
+ [MeasureAs=HTMLImageElementY] readonly attribute long y;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
index 9a50c5f94db..1a909a71555 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
@@ -22,13 +22,12 @@
#include "config.h"
#include "core/html/HTMLImageLoader.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
+#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLObjectElement.h"
-#include "core/html/HTMLVideoElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
namespace WebCore {
@@ -45,12 +44,12 @@ HTMLImageLoader::~HTMLImageLoader()
void HTMLImageLoader::dispatchLoadEvent()
{
// HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure.
- if (isHTMLVideoElement(element()))
+ if (isHTMLVideoElement(*element()))
return;
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.
+ if (isHTMLObjectElement(*element()) && !errorOccurred)
+ errorOccurred = (image()->response().httpStatusCode() >= 400); // An <object> considers a 404 to be an error and should fire onerror.
element()->dispatchEvent(Event::create(errorOccurred ? EventTypeNames::error : EventTypeNames::load));
}
@@ -63,12 +62,12 @@ void HTMLImageLoader::notifyFinished(Resource*)
{
ImageResource* cachedImage = image();
- RefPtr<Element> element = this->element();
+ RefPtrWillBeRawPtr<Element> element = this->element();
ImageLoader::notifyFinished(cachedImage);
bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
- if (loadError && element->hasTagName(HTMLNames::objectTag))
+ if (loadError && isHTMLObjectElement(*element))
toHTMLObjectElement(element)->renderFallbackContent();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h
index 4ee2d8e419e..b9b93b8f9bd 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h
@@ -27,15 +27,21 @@
namespace WebCore {
-class HTMLImageLoader : public ImageLoader {
+class HTMLImageLoader FINAL : public ImageLoader {
public:
- HTMLImageLoader(Element*);
+ static PassOwnPtrWillBeRawPtr<HTMLImageLoader> create(Element* element)
+ {
+ return adoptPtrWillBeNoop(new HTMLImageLoader(element));
+ }
virtual ~HTMLImageLoader();
- virtual void dispatchLoadEvent();
- virtual String sourceURI(const AtomicString&) const;
+ virtual void dispatchLoadEvent() OVERRIDE;
+ virtual String sourceURI(const AtomicString&) const OVERRIDE;
- virtual void notifyFinished(Resource*);
+ virtual void notifyFinished(Resource*) OVERRIDE;
+
+private:
+ explicit HTMLImageLoader(Element*);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp
deleted file mode 100644
index 8ac2d7d127c..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "core/html/HTMLImport.h"
-
-#include "core/dom/Document.h"
-
-namespace WebCore {
-
-Frame* HTMLImport::frame()
-{
- return master()->frame();
-}
-
-Document* HTMLImport::master()
-{
- return root()->document();
-}
-
-HTMLImportsController* HTMLImport::controller()
-{
- return root()->toController();
-}
-
-void HTMLImport::appendChild(HTMLImport* child)
-{
- if (isScriptBlocked())
- child->blockScript();
- if (lastChild() && !lastChild()->isDone())
- child->blockDocument();
- TreeNode<HTMLImport>::appendChild(child);
- blockAfter(child);
-}
-
-bool HTMLImport::areChilrenLoaded() const
-{
- for (HTMLImport* child = firstChild(); child; child = child->next()) {
- if (!child->isLoaded())
- return false;
- }
-
- return true;
-}
-
-bool HTMLImport::arePredecessorsLoaded() const
-{
- HTMLImport* parent = this->parent();
- if (!parent)
- return true;
-
- for (HTMLImport* sibling = parent->firstChild(); sibling; sibling = sibling->next()) {
- if (sibling == this)
- break;
- if (!sibling->isLoaded())
- return false;
- }
-
- return true;
-}
-
-void HTMLImport::blockScript()
-{
- m_scriptBlocked = true;
-}
-
-void HTMLImport::unblockScript()
-{
- bool wasBlocked = m_scriptBlocked;
- m_scriptBlocked = false;
- if (wasBlocked)
- didUnblockScript();
-}
-
-void HTMLImport::didUnblockScript()
-{
- ASSERT(!isDocumentBlocked());
- ASSERT(!isScriptBlocked());
-
- if (!isProcessing())
- return;
-
- if (Document* document = this->document())
- document->didLoadAllImports();
-}
-
-
-void HTMLImport::blockDocument()
-{
- m_documentBlocked = true;
-}
-
-void HTMLImport::unblockDocument()
-{
- bool wasBlocked = m_documentBlocked;
- m_documentBlocked = false;
- if (wasBlocked)
- didUnblockDocument();
-}
-
-void HTMLImport::didUnblockDocument()
-{
- ASSERT(!isDocumentBlocked());
- ASSERT(isScriptBlocked());
-}
-
-inline bool HTMLImport::needsBlockingDocument() const
-{
- ASSERT(isDocumentBlocked());
- HTMLImport* elder = previous();
- return (elder && !elder->isDone());
-}
-
-bool HTMLImport::unblock(HTMLImport* import)
-{
- ASSERT(import->arePredecessorsLoaded());
- ASSERT(import->isScriptBlocked() || import->areChilrenLoaded());
-
- if (import->isDocumentBlocked() && import->needsBlockingDocument())
- return false;
- import->unblockDocument();
-
- if (import->isScriptBlocked()) {
- for (HTMLImport* child = import->firstChild(); child; child = child->next()) {
- if (!unblock(child))
- return false;
- }
- }
-
- import->unblockScript();
- return import->isLoaded();
-}
-
-void HTMLImport::block(HTMLImport* import)
-{
- for (HTMLImport* child = import; child; child = traverseNext(child, import))
- child->blockScript();
-}
-
-void HTMLImport::blockAfter(HTMLImport* child)
-{
- ASSERT(child->parent() == this);
-
- for (HTMLImport* sibling = lastChild(); sibling; sibling = sibling->previous()) {
- if (sibling == child)
- break;
- HTMLImport::block(sibling);
- }
-
- this->blockScript();
-
- if (HTMLImport* parent = this->parent())
- parent->blockAfter(this);
-}
-
-bool HTMLImport::isMaster(Document* document)
-{
- if (!document->import())
- return true;
- return (document->import()->master() == document);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImport.h b/chromium/third_party/WebKit/Source/core/html/HTMLImport.h
deleted file mode 100644
index 2c80c9775e9..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImport.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 HTMLImport_h
-#define HTMLImport_h
-
-#include "wtf/TreeNode.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Frame;
-class Document;
-class Frame;
-class HTMLImportChild;
-class HTMLImportRoot;
-class HTMLImportsController;
-class KURL;
-
-//
-// # Basic Data Structure and Algorithms of HTML Imports implemenation.
-//
-// ## The Import Tree
-//
-// HTML Imports form a tree:
-//
-// * The root of the tree is HTMLImportsController, which is owned by the master
-// document as a DocumentSupplement. HTMLImportsController has an abstract class called
-// HTMLImportRoot to deal with cycler dependency.
-//
-// * The non-root nodes are HTMLImportChild, which is owned by LinkStyle, that is owned by HTMLLinkElement.
-// LinkStyle is wired into HTMLImportChild by implementing HTMLImportChildClient interface
-//
-// * Both HTMLImportsController and HTMLImportChild are derived from HTMLImport superclass
-// that models the tree data structure using WTF::TreeNode and provides a set of
-// virtual functions.
-//
-// HTMLImportsController also owns all loaders in the tree and manages their lifetime through it.
-// One assumption is that the tree is append-only and nodes are never inserted in the middle of the tree nor removed.
-//
-//
-// HTMLImport <|- HTMLImportRoot <|- HTMLImportsController <- Document
-// *
-// |
-// <|- HTMLImportChild <- LinkStyle <- HTMLLinkElement
-//
-//
-// # Import Sharing and HTMLImportLoader
-//
-// The HTML Imports spec calls for de-dup mechanism to share already loaded imports.
-// To implement this, the actual loading machinery is split out from HTMLImportChild to
-// HTMLImportLoader, and each loader shares HTMLImportLoader with other loader if the URL is same.
-// Check around HTMLImportsController::findLink() for more detail.
-//
-// Note that HTMLImportLoader provides HTMLImportLoaderClient to hook it up.
-// As it can be shared, HTMLImportLoader supports multiple clients.
-//
-// HTMLImportChild (1)-->(*) HTMLImportLoader
-//
-//
-// # Script Blocking
-//
-// The HTML parser blocks on <script> when preceding <link>s aren't finish loading imports.
-// Each HTMLImport instance tracks such a blocking state, that is called "script-blocked"
-// or HTMLImport::isScriptBlocked().
-//
-// ## Blocking Imports
-//
-// Each imports can become being script-blocked when new imports are added to the import tree.
-// For example, the parser of a parent import is blocked when new child import is given.
-// See HTMLImport::appendChild() to see how it is handled. Note that this blocking-ness is
-// transitive. HTMLImport::blockAfter() flips the flags iteratively to fullfill this transitivity.
-//
-// ## Unblocking Imports
-//
-// The blocking state can change when one of the imports finish loading. The Document notices it through
-// HTMLImportRoot::blockerGone(). The blockerGone() triggers HTMLImport::unblockScript(), which traverses
-// whole import tree and find unblock-able imports and unblock them.
-// Unblocked imported documents are notified through Document::didLoadAllImports() so that
-// it can resume its parser.
-//
-// # Document Blocking
-//
-// There is another type of blocking state that is called
-// "document-blocked". If the import is document-blocked, it cannot
-// create its own document object because sharable imported document
-// can appear later. The spec defines the loading order of the
-// import: The earlier one in the import-tree order should win and
-// later ones should share earlier one.
-//
-// The "document-blocked" state keeps the tree node from loading its
-// import until all preceding imports are ready t respect the
-// order. Note that the node may fetch the bytes from the URL
-// speculatively, even though it doesn't process it.
-//
-// The node is "document-unblocked" when there are unfinished,
-// preceeding import loading. Unblocking attempt for
-// "document-blocked" happens at the same timing as unblocking
-// "script-blocked".
-//
-
-// The superclass of HTMLImportsController and HTMLImportChild
-// This represents the import tree data structure.
-class HTMLImport : public TreeNode<HTMLImport> {
-public:
- static bool unblock(HTMLImport*);
- static bool isMaster(Document*);
-
- virtual ~HTMLImport() { }
-
- Frame* frame();
- Document* master();
- HTMLImportsController* controller();
-
- bool isLoaded() const { return !isScriptBlocked() && !isProcessing(); }
- bool isScriptBlocked() const { return m_scriptBlocked; }
- bool isDocumentBlocked() const { return m_documentBlocked; }
- bool isBlocked() const { return m_scriptBlocked || m_documentBlocked; }
-
- void appendChild(HTMLImport*);
-
- virtual HTMLImportRoot* root() = 0;
- virtual Document* document() const = 0;
- virtual void wasDetachedFromDocument() = 0;
- virtual void didFinishParsing() = 0;
- virtual bool isProcessing() const = 0;
- virtual bool isDone() const = 0;
-
-protected:
- HTMLImport()
- : m_scriptBlocked(false)
- , m_documentBlocked(false)
- { }
-
- virtual void didUnblockDocument();
-
-private:
- static void block(HTMLImport*);
-
- void blockAfter(HTMLImport* child);
- void blockScript();
- void unblockScript();
- void didUnblockScript();
-
- void blockDocument();
- void unblockDocument();
-
- bool needsBlockingDocument() const;
- bool arePredecessorsLoaded() const;
- bool areChilrenLoaded() const;
-
- bool m_scriptBlocked; // If any of decendants or predecessors is in processing, the parser blocks on <script>.
- bool m_documentBlocked; // If its predecessor is not done yet, the document creation is blocked.
-};
-
-// An abstract class to decouple its sublcass HTMLImportsController.
-class HTMLImportRoot : public HTMLImport {
-public:
- virtual void blockerGone() = 0;
- virtual HTMLImportsController* toController() = 0;
- virtual HTMLImportChild* findLinkFor(const KURL&, HTMLImport* excluding = 0) const = 0;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImport_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp
deleted file mode 100644
index 52445f355ea..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "core/html/HTMLImportChild.h"
-
-#include "core/dom/Document.h"
-#include "core/html/HTMLImportChildClient.h"
-#include "core/html/HTMLImportLoader.h"
-
-namespace WebCore {
-
-HTMLImportChild::HTMLImportChild(const KURL& url, HTMLImportChildClient* client)
- : m_url(url)
- , m_client(client)
-{
-}
-
-HTMLImportChild::~HTMLImportChild()
-{
- // importDestroyed() should be called before the destruction.
- ASSERT(!m_loader);
-}
-
-void HTMLImportChild::wasAlreadyLoadedAs(HTMLImportChild* found)
-{
- ASSERT(!m_loader);
- ASSERT(m_client);
- shareLoader(found);
-}
-
-void HTMLImportChild::startLoading(const ResourcePtr<RawResource>& resource)
-{
- ASSERT(!hasResource());
- ASSERT(!m_loader);
-
- HTMLImportResourceOwner::setResource(resource);
-
- // If the node is "document blocked", it cannot create HTMLImportLoader
- // even if there is no sharable one found, as there is possibility that
- // preceding imports load the sharable imports.
- // In that case preceding one should win because it comes first in the tree order.
- // See also didUnblockDocument().
- if (isDocumentBlocked())
- return;
-
- createLoader();
-}
-
-void HTMLImportChild::didFinish()
-{
- if (m_client)
- m_client->didFinish();
- clearResource();
- root()->blockerGone();
-}
-
-Document* HTMLImportChild::importedDocument() const
-{
- if (!m_loader)
- return 0;
- return m_loader->importedDocument();
-}
-
-void HTMLImportChild::importDestroyed()
-{
- if (parent())
- parent()->removeChild(this);
- if (m_loader) {
- m_loader->removeClient(this);
- m_loader.clear();
- }
-}
-
-HTMLImportRoot* HTMLImportChild::root()
-{
- return parent() ? parent()->root() : 0;
-}
-
-Document* HTMLImportChild::document() const
-{
- return (m_loader && m_loader->isOwnedBy(this)) ? m_loader->document() : 0;
-}
-
-void HTMLImportChild::wasDetachedFromDocument()
-{
- // For imported documens this shouldn't be called because Document::m_import is
- // cleared before Document is destroyed by HTMLImportChild::importDestroyed().
- ASSERT_NOT_REACHED();
-}
-
-void HTMLImportChild::didFinishParsing()
-{
- ASSERT(m_loader->isOwnedBy(this));
- m_loader->didFinishParsing();
-}
-
-// Once all preceding imports are loaded and "document blocking" ends,
-// HTMLImportChild can decide whether it should load the import by itself
-// or it can share existing one.
-void HTMLImportChild::didUnblockDocument()
-{
- HTMLImport::didUnblockDocument();
- ASSERT(!isDocumentBlocked());
- ASSERT(!m_loader || !m_loader->isOwnedBy(this));
-
- if (m_loader)
- return;
- if (HTMLImportChild* found = root()->findLinkFor(m_url, this))
- shareLoader(found);
- else
- createLoader();
-}
-
-void HTMLImportChild::createLoader()
-{
- ASSERT(!isDocumentBlocked());
- ASSERT(!m_loader);
- m_loader = HTMLImportLoader::create(this, parent()->document()->fetcher());
- m_loader->addClient(this);
- m_loader->startLoading(resource());
-}
-
-void HTMLImportChild::shareLoader(HTMLImportChild* loader)
-{
- ASSERT(!m_loader);
- m_loader = loader->m_loader;
- m_loader->addClient(this);
- root()->blockerGone();
-}
-
-bool HTMLImportChild::isProcessing() const
-{
- return m_loader && m_loader->isOwnedBy(this) && m_loader->isProcessing();
-}
-
-bool HTMLImportChild::isDone() const
-{
- return m_loader && m_loader->isDone();
-}
-
-bool HTMLImportChild::isLoaded() const
-{
- return m_loader->isLoaded();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp
deleted file mode 100644
index 5781c79791e..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "core/html/HTMLImportLoader.h"
-
-#include "core/dom/Document.h"
-#include "core/dom/custom/CustomElementRegistrationContext.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-#include "core/html/HTMLDocument.h"
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportLoaderClient.h"
-#include "core/loader/DocumentWriter.h"
-
-
-namespace WebCore {
-
-PassRefPtr<HTMLImportLoader> HTMLImportLoader::create(HTMLImport* import, ResourceFetcher* fetcher)
-{
- RefPtr<HTMLImportLoader> self = adoptRef(new HTMLImportLoader(import, fetcher));
- return self.release();
-}
-
-HTMLImportLoader::HTMLImportLoader(HTMLImport* import, ResourceFetcher* fetcher)
- : m_import(import)
- , m_fetcher(fetcher)
- , m_state(StateLoading)
-{
-}
-
-HTMLImportLoader::~HTMLImportLoader()
-{
- if (m_importedDocument)
- m_importedDocument->setImport(0);
-}
-
-void HTMLImportLoader::startLoading(const ResourcePtr<RawResource>& resource)
-{
- setResource(resource);
-}
-
-void HTMLImportLoader::responseReceived(Resource* resource, const ResourceResponse& response)
-{
- // Current canAccess() implementation isn't sufficient for catching cross-domain redirects: http://crbug.com/256976
- if (!m_fetcher->canAccess(resource, PotentiallyCORSEnabled)) {
- setState(StateError);
- return;
- }
-
- setState(startWritingAndParsing(response));
-}
-
-void HTMLImportLoader::dataReceived(Resource*, const char* data, int length)
-{
- RefPtr<DocumentWriter> protectingWriter(m_writer);
- m_writer->addData(data, length);
-}
-
-void HTMLImportLoader::notifyFinished(Resource* resource)
-{
- // The writer instance indicates that a part of the document can be already loaded.
- // We don't take such a case as an error because the partially-loaded document has been visible from script at this point.
- if (resource->loadFailedOrCanceled() && !m_writer) {
- setState(StateError);
- return;
- }
-
- setState(finishWriting());
-}
-
-HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(const ResourceResponse& response)
-{
- DocumentInit init = DocumentInit(response.url(), 0, m_import->master()->contextDocument(), m_import)
- .withRegistrationContext(m_import->master()->registrationContext());
- m_importedDocument = HTMLDocument::create(init);
- m_importedDocument->initContentSecurityPolicy(ContentSecurityPolicyResponseHeaders(response));
- m_writer = DocumentWriter::create(m_importedDocument.get(), response.mimeType(), response.textEncodingName());
-
- return StateLoading;
-}
-
-HTMLImportLoader::State HTMLImportLoader::finishWriting()
-{
- return StateWritten;
-}
-
-HTMLImportLoader::State HTMLImportLoader::finishParsing()
-{
- return StateReady;
-}
-
-void HTMLImportLoader::setState(State state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
-
- if (m_state == StateReady || m_state == StateError || m_state == StateWritten) {
- if (RefPtr<DocumentWriter> writer = m_writer.release())
- writer->end();
- }
-
- // Since DocumentWriter::end() can let setState() reenter, we shouldn't refer to m_state here.
- if (state == StateReady || state == StateError)
- didFinish();
-}
-
-void HTMLImportLoader::didFinishParsing()
-{
- setState(finishParsing());
-}
-
-Document* HTMLImportLoader::importedDocument() const
-{
- if (m_state == StateError)
- return 0;
- return m_importedDocument.get();
-}
-
-bool HTMLImportLoader::isProcessing() const
-{
- if (!m_importedDocument)
- return !isDone();
- return m_importedDocument->parsing();
-}
-
-void HTMLImportLoader::didFinish()
-{
- for (size_t i = 0; i < m_clients.size(); ++i)
- m_clients[i]->didFinish();
-
- clearResource();
-
- ASSERT(!m_importedDocument || !m_importedDocument->parsing());
-}
-
-void HTMLImportLoader::addClient(HTMLImportLoaderClient* client)
-{
- ASSERT(kNotFound == m_clients.find(client));
- m_clients.append(client);
- if (isDone())
- client->didFinish();
-}
-
-void HTMLImportLoader::removeClient(HTMLImportLoaderClient* client)
-{
- ASSERT(kNotFound != m_clients.find(client));
- m_clients.remove(m_clients.find(client));
-}
-
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h
deleted file mode 100644
index a8f5c52a193..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 HTMLImportResourceOwner_h
-#define HTMLImportResourceOwner_h
-
-#include "core/fetch/RawResource.h"
-#include "core/fetch/ResourcePtr.h"
-
-namespace WebCore {
-
-// A RawResourceClient implenetation which is responsible for
-// owning RawResource object and adding/removing itself as a client
-// according to its lifetime.
-//
-// FIXME: This could be geneeric ResouceOwner<ResourceType> once it is
-// found that this class is broadly useful even outside HTMLImports module.
-//
-class HTMLImportResourceOwner : public RawResourceClient {
-public:
- HTMLImportResourceOwner();
- virtual ~HTMLImportResourceOwner();
-
-protected:
- const ResourcePtr<RawResource>& resource() const { return m_resource; }
-
- void setResource(const ResourcePtr<RawResource>&);
- void clearResource();
- bool hasResource() const { return m_resource.get(); }
-
-private:
- ResourcePtr<RawResource> m_resource;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImportResourceOwner_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp
deleted file mode 100644
index bc057d50390..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "core/html/HTMLImportsController.h"
-
-#include "core/dom/Document.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLImportChild.h"
-#include "core/html/HTMLImportChildClient.h"
-
-namespace WebCore {
-
-void HTMLImportsController::provideTo(Document* master)
-{
- DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController"));
- OwnPtr<HTMLImportsController> controller = adoptPtr(new HTMLImportsController(master));
- master->setImport(controller.get());
- DocumentSupplement::provideTo(master, name, controller.release());
-}
-
-HTMLImportsController::HTMLImportsController(Document* master)
- : m_master(master)
- , m_unblockTimer(this, &HTMLImportsController::unblockTimerFired)
-{
-}
-
-HTMLImportsController::~HTMLImportsController()
-{
- ASSERT(!m_master);
-}
-
-void HTMLImportsController::clear()
-{
- for (size_t i = 0; i < m_imports.size(); ++i)
- m_imports[i]->importDestroyed();
- if (m_master)
- m_master->setImport(0);
- m_master = 0;
-}
-
-HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImport* parent, HTMLImportChildClient* client)
-{
- OwnPtr<HTMLImportChild> loader = adoptPtr(new HTMLImportChild(url, client));
- parent->appendChild(loader.get());
- m_imports.append(loader.release());
- return m_imports.last().get();
-}
-
-HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChildClient* client, FetchRequest request)
-{
- ASSERT(!request.url().isEmpty() && request.url().isValid());
-
- if (HTMLImportChild* found = findLinkFor(request.url())) {
- HTMLImportChild* child = createChild(request.url(), parent, client);
- child->wasAlreadyLoadedAs(found);
- return child;
- }
-
- request.setCrossOriginAccessControl(securityOrigin(), DoNotAllowStoredCredentials);
- ResourcePtr<RawResource> resource = parent->document()->fetcher()->fetchImport(request);
- if (!resource)
- return 0;
-
- HTMLImportChild* child = createChild(request.url(), parent, client);
- // We set resource after the import tree is built since
- // Resource::addClient() immediately calls back to feed the bytes when the resource is cached.
- child->startLoading(resource);
-
- return child;
-}
-
-void HTMLImportsController::showSecurityErrorMessage(const String& message)
-{
- m_master->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
-}
-
-HTMLImportChild* HTMLImportsController::findLinkFor(const KURL& url, HTMLImport* excluding) const
-{
- for (size_t i = 0; i < m_imports.size(); ++i) {
- HTMLImportChild* candidate = m_imports[i].get();
- if (candidate != excluding && equalIgnoringFragmentIdentifier(candidate->url(), url) && !candidate->isDocumentBlocked())
- return candidate;
- }
-
- return 0;
-}
-
-SecurityOrigin* HTMLImportsController::securityOrigin() const
-{
- return m_master->securityOrigin();
-}
-
-ResourceFetcher* HTMLImportsController::fetcher() const
-{
- return m_master->fetcher();
-}
-
-HTMLImportRoot* HTMLImportsController::root()
-{
- return this;
-}
-
-Document* HTMLImportsController::document() const
-{
- return m_master;
-}
-
-void HTMLImportsController::wasDetachedFromDocument()
-{
- clear();
-}
-
-void HTMLImportsController::didFinishParsing()
-{
-}
-
-bool HTMLImportsController::isProcessing() const
-{
- return m_master->parsing();
-}
-
-bool HTMLImportsController::isDone() const
-{
- return !m_master->parsing();
-}
-
-void HTMLImportsController::blockerGone()
-{
- scheduleUnblock();
-}
-
-void HTMLImportsController::scheduleUnblock()
-{
- if (m_unblockTimer.isActive())
- return;
- m_unblockTimer.startOneShot(0);
-}
-
-void HTMLImportsController::unblockTimerFired(Timer<HTMLImportsController>*)
-{
- do {
- m_unblockTimer.stop();
- HTMLImport::unblock(this);
- } while (m_unblockTimer.isActive());
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
index 6d2e2e8eeb6..6cc8bddeacb 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
@@ -29,12 +29,11 @@
#include "config.h"
#include "core/html/HTMLInputElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
@@ -48,11 +47,12 @@
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
#include "core/events/ScopedEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/TouchEvent.h"
#include "core/fileapi/FileList.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLFormElement.h"
@@ -65,34 +65,33 @@
#include "core/html/forms/SearchInputType.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/UseCounter.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderTextControlSingleLine.h"
#include "core/rendering/RenderTheme.h"
+#include "platform/ColorChooser.h"
#include "platform/DateTimeChooser.h"
#include "platform/Language.h"
#include "platform/PlatformMouseEvent.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/MathExtras.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
-class ListAttributeTargetObserver : IdTargetObserver {
- WTF_MAKE_FAST_ALLOCATED;
+class ListAttributeTargetObserver : public IdTargetObserver {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
+ static PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
+ virtual void trace(Visitor*) OVERRIDE;
virtual void idTargetChanged() OVERRIDE;
private:
ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
- HTMLInputElement* m_element;
+ RawPtrWillBeMember<HTMLInputElement> m_element;
};
// FIXME: According to HTML4, the length attribute's value can be arbitrarily
@@ -111,7 +110,6 @@ HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo
, m_isChecked(false)
, m_reflectsCheckedAttribute(true)
, m_isIndeterminate(false)
- , m_hasType(false)
, m_isActivatedSubmit(false)
, m_autocomplete(Uninitialized)
, m_hasNonEmptyList(false)
@@ -120,6 +118,8 @@ HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo
, m_valueAttributeWasUpdatedAfterParsing(false)
, m_canReceiveDroppedFiles(false)
, m_hasTouchEventHandler(false)
+ , m_shouldRevealPassword(false)
+ , m_needsToUpdateViewValue(true)
, m_inputType(InputType::createText(*this))
, m_inputTypeView(m_inputType)
{
@@ -129,17 +129,26 @@ HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLInputElement> HTMLInputElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLInputElement> HTMLInputElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
- RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(document, form, createdByParser));
+ RefPtrWillBeRawPtr<HTMLInputElement> inputElement = adoptRefWillBeNoop(new HTMLInputElement(document, form, createdByParser));
inputElement->ensureUserAgentShadowRoot();
return inputElement.release();
}
+void HTMLInputElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_inputType);
+ visitor->trace(m_inputTypeView);
+ visitor->trace(m_listAttributeTargetObserver);
+ visitor->trace(m_imageLoader);
+ HTMLTextFormControlElement::trace(visitor);
+}
+
HTMLImageLoader* HTMLInputElement::imageLoader()
{
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
return m_imageLoader.get();
}
@@ -148,10 +157,8 @@ void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot&)
m_inputTypeView->createShadowSubtree();
}
-void HTMLInputElement::didAddShadowRoot(ShadowRoot& root)
+void HTMLInputElement::willAddFirstAuthorShadowRoot()
{
- if (!root.isOldestAuthorShadowRoot())
- return;
m_inputTypeView->destroyShadowSubtree();
m_inputTypeView = InputTypeView::create(*this);
lazyReattachIfAttached();
@@ -159,15 +166,17 @@ void HTMLInputElement::didAddShadowRoot(ShadowRoot& root)
HTMLInputElement::~HTMLInputElement()
{
+#if !ENABLE(OILPAN)
// Need to remove form association while this is still an HTMLInputElement
// so that virtual functions are called correctly.
setForm(0);
// setForm(0) may register this to a document-level radio button group.
// We should unregister it to avoid accessing a deleted object.
if (isRadioButton())
- document().formController()->checkedRadioButtons().removeButton(this);
+ document().formController().radioButtonGroupScope().removeButton(this);
if (m_hasTouchEventHandler)
- document().didRemoveEventTargetNode(this);
+ document().didRemoveTouchEventHandler(this);
+#endif
}
const AtomicString& HTMLInputElement::name() const
@@ -180,11 +189,6 @@ Vector<FileChooserFileInfo> HTMLInputElement::filesFromFileInputFormControlState
return FileInputType::filesFromFormControlState(state);
}
-HTMLElement* HTMLInputElement::passwordGeneratorButtonElement() const
-{
- return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::passwordGenerator()));
-}
-
bool HTMLInputElement::shouldAutocomplete() const
{
if (m_autocomplete != Uninitialized)
@@ -339,7 +343,7 @@ bool HTMLInputElement::shouldShowFocusRingOnMouseFocus() const
void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
{
if (isTextField()) {
- if (!restorePreviousSelection || !hasCachedSelection())
+ if (!restorePreviousSelection)
select();
else
restoreCachedSelection();
@@ -351,23 +355,28 @@ void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
void HTMLInputElement::beginEditing()
{
+ ASSERT(document().isActive());
+ if (!document().isActive())
+ return;
+
if (!isTextField())
return;
- if (Frame* frame = document().frame())
- frame->spellChecker().didBeginEditing(this);
+ document().frame()->spellChecker().didBeginEditing(this);
}
void HTMLInputElement::endEditing()
{
+ ASSERT(document().isActive());
+ if (!document().isActive())
+ return;
+
if (!isTextField())
return;
- if (Frame* frame = document().frame()) {
- frame->spellChecker().didEndEditingOnTextField(this);
- if (Page* page = frame->page())
- page->chrome().client().didEndEditingOnTextField(*this);
- }
+ LocalFrame* frame = document().frame();
+ frame->spellChecker().didEndEditingOnTextField(this);
+ frame->host()->chrome().client().didEndEditingOnTextField(*this);
}
bool HTMLInputElement::shouldUseInputMethod()
@@ -375,9 +384,9 @@ bool HTMLInputElement::shouldUseInputMethod()
return m_inputType->shouldUseInputMethod();
}
-void HTMLInputElement::handleFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLInputElement::handleFocusEvent(Element* oldFocusedElement, FocusType type)
{
- m_inputTypeView->handleFocusEvent(oldFocusedElement, direction);
+ m_inputTypeView->handleFocusEvent(oldFocusedElement, type);
m_inputType->enableSecureTextInput();
}
@@ -389,32 +398,17 @@ void HTMLInputElement::handleBlurEvent()
void HTMLInputElement::setType(const AtomicString& type)
{
- // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
- // We should write a test case to show that setting to the empty string does not remove the
- // attribute in other browsers and then fix this. Note that setting to null *does* remove
- // the attribute and setAttribute implements that.
- if (type.isEmpty())
- removeAttribute(typeAttr);
- else
- setAttribute(typeAttr, type);
+ setAttribute(typeAttr, type);
}
void HTMLInputElement::updateType()
{
const AtomicString& newTypeName = InputType::normalizeTypeName(fastGetAttribute(typeAttr));
- bool hadType = m_hasType;
- m_hasType = true;
- if (m_inputType->formControlType() == newTypeName)
- return;
- if (hadType && !InputType::canChangeFromAnotherType(newTypeName)) {
- // Set the attribute back to the old value.
- // Useful in case we were called from inside parseAttribute.
- setAttribute(typeAttr, type());
+ if (m_inputType->formControlType() == newTypeName)
return;
- }
- RefPtr<InputType> newType = InputType::create(*this, newTypeName);
+ RefPtrWillBeRawPtr<InputType> newType = InputType::create(*this, newTypeName);
removeFromRadioButtonGroup();
bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
@@ -453,16 +447,16 @@ void HTMLInputElement::updateType()
} else
updateValueIfNeeded();
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_inputTypeView->updateView();
if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
ASSERT(elementData());
- if (const Attribute* height = getAttributeItem(heightAttr))
+ if (const Attribute* height = findAttributeByName(heightAttr))
attributeChanged(heightAttr, height->value());
- if (const Attribute* width = getAttributeItem(widthAttr))
+ if (const Attribute* width = findAttributeByName(widthAttr))
attributeChanged(widthAttr, width->value());
- if (const Attribute* align = getAttributeItem(alignAttr))
+ if (const Attribute* align = findAttributeByName(alignAttr))
attributeChanged(alignAttr, align->value());
}
@@ -514,11 +508,6 @@ bool HTMLInputElement::canStartSelection() const
return HTMLTextFormControlElement::canStartSelection();
}
-bool HTMLInputElement::canHaveSelection() const
-{
- return isTextField();
-}
-
int HTMLInputElement::selectionStartForBinding(ExceptionState& exceptionState) const
{
if (!m_inputType->supportsSelectionAPI()) {
@@ -648,9 +637,9 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
// We only need to setChanged if the form is looking at the default value right now.
if (!hasDirtyValue()) {
updatePlaceholderVisibility(false);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
setNeedsValidityCheck();
m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
m_inputTypeView->valueAttributeChanged();
@@ -670,7 +659,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
int valueAsInteger = value.toInt();
m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
if (m_size != oldSize && renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
} else if (name == altAttr)
m_inputTypeView->altAttributeChanged();
else if (name == srcAttr)
@@ -679,7 +668,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
// FIXME: ignore for the moment
} else if (name == onsearchAttr) {
// Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
- setAttributeEventListener(EventTypeNames::search, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::search, createAttributeEventListener(this, name, value, eventParameterName()));
} else if (name == resultsAttr) {
int oldResults = m_maxResults;
m_maxResults = !value.isNull() ? std::min(value.toInt(), maxSavedResults) : -1;
@@ -687,10 +676,10 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
// time to relayout for this change.
if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0))
lazyReattachIfAttached();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
UseCounter::count(document(), UseCounter::ResultsAttribute);
} else if (name == incrementalAttr) {
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
UseCounter::count(document(), UseCounter::IncrementalAttribute);
} else if (name == minAttr) {
m_inputTypeView->minOrMaxAttributeChanged();
@@ -711,9 +700,6 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
} else if (name == patternAttr) {
setNeedsValidityCheck();
UseCounter::count(document(), UseCounter::PatternAttribute);
- } else if (name == precisionAttr) {
- setNeedsValidityCheck();
- UseCounter::count(document(), UseCounter::PrecisionAttribute);
} else if (name == disabledAttr) {
HTMLTextFormControlElement::parseAttribute(name, value);
m_inputTypeView->disabledAttributeChanged();
@@ -727,24 +713,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
listAttributeTargetChanged();
}
UseCounter::count(document(), UseCounter::ListAttribute);
- }
-#if ENABLE(INPUT_SPEECH)
- else if (name == webkitspeechAttr) {
- if (RuntimeEnabledFeatures::speechInputEnabled() && m_inputType->shouldRespectSpeechAttribute()) {
- // This renderer and its children have quite different layouts and
- // styles depending on whether the speech button is visible or
- // not. So we reset the whole thing and recreate to get the right
- // styles and layout.
- m_inputTypeView->destroyShadowSubtree();
- lazyReattachIfAttached();
- m_inputTypeView->createShadowSubtree();
- setFormControlValueMatchesRenderer(false);
- }
- UseCounter::count(document(), UseCounter::PrefixedSpeechAttribute);
- } else if (name == onwebkitspeechchangeAttr)
- setAttributeEventListener(EventTypeNames::webkitspeechchange, createAttributeEventListener(this, name, value));
-#endif
- else if (name == webkitdirectoryAttr) {
+ } else if (name == webkitdirectoryAttr) {
HTMLTextFormControlElement::parseAttribute(name, value);
UseCounter::count(document(), UseCounter::PrefixedDirectoryAttribute);
}
@@ -777,9 +746,6 @@ RenderObject* HTMLInputElement::createRenderer(RenderStyle* style)
void HTMLInputElement::attach(const AttachContext& context)
{
- if (!m_hasType)
- updateType();
-
HTMLTextFormControlElement::attach(context);
m_inputTypeView->startResourceLoading();
@@ -792,7 +758,7 @@ void HTMLInputElement::attach(const AttachContext& context)
void HTMLInputElement::detach(const AttachContext& context)
{
HTMLTextFormControlElement::detach(context);
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_inputTypeView->closePopupView();
}
@@ -804,9 +770,9 @@ String HTMLInputElement::altText() const
String alt = fastGetAttribute(altAttr);
// fall back to title attribute
if (alt.isNull())
- alt = getAttribute(titleAttr);
+ alt = fastGetAttribute(titleAttr);
if (alt.isNull())
- alt = getAttribute(valueAttr);
+ alt = fastGetAttribute(valueAttr);
if (alt.isEmpty())
alt = locale().queryString(blink::WebLocalizedString::InputElementAltText);
return alt;
@@ -839,8 +805,10 @@ String HTMLInputElement::resultForDialogSubmit()
void HTMLInputElement::resetImpl()
{
- if (m_inputType->storesValueSeparateFromAttribute())
+ if (m_inputType->storesValueSeparateFromAttribute()) {
setValue(String());
+ setNeedsValidityCheck();
+ }
setChecked(hasAttribute(checkedAttr));
m_reflectsCheckedAttribute = true;
@@ -861,14 +829,15 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
if (checked() == nowChecked)
return;
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(this);
m_reflectsCheckedAttribute = false;
m_isChecked = nowChecked;
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->updateCheckedState(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->updateCheckedState(this);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), CheckedState);
+ RenderTheme::theme().stateChanged(renderer(), CheckedControlState);
setNeedsValidityCheck();
@@ -887,6 +856,8 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
// definitely wrong in practice for these types of elements.
if (eventBehavior != DispatchNoEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
setTextAsOfLastFormControlChangeEvent(String());
+ if (eventBehavior == DispatchInputAndChangeEvent)
+ dispatchFormControlInputEvent();
dispatchFormControlChangeEvent();
}
@@ -903,7 +874,7 @@ void HTMLInputElement::setIndeterminate(bool newValue)
didAffectSelector(AffectedSelectorIndeterminate);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), CheckedState);
+ RenderTheme::theme().stateChanged(renderer(), CheckedControlState);
}
int HTMLInputElement::size() const
@@ -927,7 +898,7 @@ void HTMLInputElement::copyNonAttributePropertiesFromElement(const Element& sour
HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(source);
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_inputTypeView->updateView();
}
@@ -973,9 +944,9 @@ void HTMLInputElement::setSuggestedValue(const String& value)
{
if (!m_inputType->canSetSuggestedValue())
return;
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_suggestedValue = sanitizeValue(value);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
m_inputTypeView->updateView();
}
@@ -983,7 +954,7 @@ void HTMLInputElement::setEditingValue(const String& value)
{
if (!renderer() || !isTextField())
return;
- setInnerTextValue(value);
+ setInnerEditorValue(value);
subtreeHasChanged();
unsigned max = value.length();
@@ -995,10 +966,16 @@ void HTMLInputElement::setEditingValue(const String& value)
dispatchInputEvent();
}
+void HTMLInputElement::setInnerEditorValue(const String& value)
+{
+ HTMLTextFormControlElement::setInnerEditorValue(value);
+ m_needsToUpdateViewValue = false;
+}
+
void HTMLInputElement::setValue(const String& value, ExceptionState& exceptionState, TextFieldEventBehavior eventBehavior)
{
if (isFileUpload() && !value.isEmpty()) {
- exceptionState.throwDOMException(InvalidStateError, "This input element accepts a filename, which may only be programatically set to the empty string.");
+ exceptionState.throwDOMException(InvalidStateError, "This input element accepts a filename, which may only be programmatically set to the empty string.");
return;
}
setValue(value, eventBehavior);
@@ -1009,13 +986,13 @@ void HTMLInputElement::setValue(const String& value, TextFieldEventBehavior even
if (!m_inputType->canSetValue(value))
return;
- RefPtr<HTMLInputElement> protector(this);
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(this);
EventQueueScope scope;
String sanitizedValue = sanitizeValue(value);
bool valueChanged = sanitizedValue != this->value();
setLastChangeWasNotUserEdit();
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_suggestedValue = String(); // Prevent TextFieldInputType::setValue from using the suggested value.
m_inputType->setValue(sanitizedValue, valueChanged, eventBehavior);
@@ -1033,11 +1010,20 @@ void HTMLInputElement::setValueInternal(const String& sanitizedValue, TextFieldE
{
m_valueIfDirty = sanitizedValue;
setNeedsValidityCheck();
+ if (document().focusedElement() == this)
+ document().frameHost()->chrome().client().didUpdateTextOfFocusedElementByNonUserInput();
+}
+
+void HTMLInputElement::updateView()
+{
+ m_inputTypeView->updateView();
}
-double HTMLInputElement::valueAsDate() const
+double HTMLInputElement::valueAsDate(bool& isNull) const
{
- return m_inputType->valueAsDate();
+ double date = m_inputType->valueAsDate();
+ isNull = !std::isfinite(date);
+ return date;
}
void HTMLInputElement::setValueAsDate(double value, ExceptionState& exceptionState)
@@ -1052,8 +1038,10 @@ double HTMLInputElement::valueAsNumber() const
void HTMLInputElement::setValueAsNumber(double newValue, ExceptionState& exceptionState, TextFieldEventBehavior eventBehavior)
{
- if (!std::isfinite(newValue)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(newValue));
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#dom-input-valueasnumber
+ // On setting, if the new value is infinite, then throw a TypeError exception.
+ if (std::isinf(newValue)) {
+ exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(newValue));
return;
}
m_inputType->setValueAsDouble(newValue, eventBehavior, exceptionState);
@@ -1070,8 +1058,7 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
ASSERT(value == sanitizeValue(value) || sanitizeValue(value).isEmpty());
m_valueIfDirty = value;
-
- setFormControlValueMatchesRenderer(true);
+ m_needsToUpdateViewValue = false;
// Input event is fired by the Node::defaultEventHandler for editable controls.
if (!isTextField())
@@ -1094,13 +1081,17 @@ void* HTMLInputElement::preDispatchEventHandler(Event* event)
return 0;
if (!event->isMouseEvent() || toMouseEvent(event)->button() != LeftButton)
return 0;
+#if ENABLE(OILPAN)
+ return m_inputTypeView->willDispatchClick();
+#else
// FIXME: Check whether there are any cases where this actually ends up leaking.
return m_inputTypeView->willDispatchClick().leakPtr();
+#endif
}
void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
{
- OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
+ OwnPtrWillBeRawPtr<ClickHandlingState> state = adoptPtrWillBeNoop(static_cast<ClickHandlingState*>(dataFromPreDispatch));
if (!state)
return;
m_inputTypeView->didDispatchClick(event, *state);
@@ -1114,7 +1105,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
return;
}
- if (evt->isTouchEvent()) {
+ if (evt->isTouchEvent() && m_inputTypeView->hasTouchEventHandler()) {
m_inputTypeView->handleTouchEvent(toTouchEvent(evt));
if (evt->defaultHandled())
return;
@@ -1167,7 +1158,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
if (wasChangedSinceLastFormControlChangeEvent())
dispatchFormControlChangeEvent();
- RefPtr<HTMLFormElement> formForSubmission = m_inputTypeView->formForSubmission();
+ RefPtrWillBeRawPtr<HTMLFormElement> formForSubmission = m_inputTypeView->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());
@@ -1205,6 +1196,16 @@ bool HTMLInputElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || attribute.name() == formactionAttr || HTMLTextFormControlElement::isURLAttribute(attribute);
}
+bool HTMLInputElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return m_inputType->hasLegalLinkAttribute(name) || HTMLTextFormControlElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLInputElement::subResourceAttributeName() const
+{
+ return m_inputType->subResourceAttributeName();
+}
+
const AtomicString& HTMLInputElement::defaultValue() const
{
return fastGetAttribute(valueAttr);
@@ -1269,11 +1270,6 @@ Vector<String> HTMLInputElement::acceptFileExtensions()
return parseAcceptAttribute(fastGetAttribute(acceptAttr), isValidFileExtension);
}
-const AtomicString& HTMLInputElement::accept() const
-{
- return fastGetAttribute(acceptAttr);
-}
-
const AtomicString& HTMLInputElement::alt() const
{
return fastGetAttribute(altAttr);
@@ -1320,7 +1316,7 @@ FileList* HTMLInputElement::files()
return m_inputType->files();
}
-void HTMLInputElement::setFiles(PassRefPtr<FileList> files)
+void HTMLInputElement::setFiles(PassRefPtrWillBeRawPtr<FileList> files)
{
m_inputType->setFiles(files);
}
@@ -1349,11 +1345,6 @@ void HTMLInputElement::setCanReceiveDroppedFiles(bool canReceiveDroppedFiles)
renderer()->updateFromElement();
}
-String HTMLInputElement::visibleValue() const
-{
- return m_inputType->visibleValue();
-}
-
String HTMLInputElement::sanitizeValue(const String& proposedValue) const
{
if (proposedValue.isNull())
@@ -1442,9 +1433,9 @@ void HTMLInputElement::didMoveToNewDocument(Document& oldDocument)
imageLoader()->elementDidMoveToNewDocument();
if (isRadioButton())
- oldDocument.formController()->checkedRadioButtons().removeButton(this);
+ oldDocument.formController().radioButtonGroupScope().removeButton(this);
if (m_hasTouchEventHandler)
- oldDocument.didRemoveEventTargetNode(this);
+ oldDocument.didRemoveTouchEventHandler(this);
if (m_hasTouchEventHandler)
document().didAddTouchEventHandler(this);
@@ -1452,11 +1443,10 @@ void HTMLInputElement::didMoveToNewDocument(Document& oldDocument)
HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
}
-void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+void HTMLInputElement::removeAllEventListeners()
{
- HTMLTextFormControlElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, src());
+ HTMLTextFormControlElement::removeAllEventListeners();
+ m_hasTouchEventHandler = false;
}
bool HTMLInputElement::recalcWillValidate() const
@@ -1467,8 +1457,8 @@ bool HTMLInputElement::recalcWillValidate() const
void HTMLInputElement::requiredAttributeChanged()
{
HTMLTextFormControlElement::requiredAttributeChanged();
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->requiredAttributeChanged(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->requiredAttributeChanged(this);
m_inputTypeView->requiredAttributeChanged();
}
@@ -1495,7 +1485,7 @@ HTMLDataListElement* HTMLInputElement::dataList() const
Element* element = treeScope().getElementById(fastGetAttribute(listAttr));
if (!element)
return 0;
- if (!element->hasTagName(datalistTag))
+ if (!isHTMLDataListElement(*element))
return 0;
return toHTMLDataListElement(element);
@@ -1506,7 +1496,7 @@ bool HTMLInputElement::hasValidDataListOptions() const
HTMLDataListElement* dataList = this->dataList();
if (!dataList)
return false;
- RefPtr<HTMLCollection> options = dataList->options();
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
if (isValidValue(option->value()))
return true;
@@ -1514,12 +1504,19 @@ bool HTMLInputElement::hasValidDataListOptions() const
return false;
}
+void HTMLInputElement::setListAttributeTargetObserver(PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver> newObserver)
+{
+ if (m_listAttributeTargetObserver)
+ m_listAttributeTargetObserver->unregister();
+ m_listAttributeTargetObserver = newObserver;
+}
+
void HTMLInputElement::resetListAttributeTargetObserver()
{
if (inDocument())
- m_listAttributeTargetObserver = ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this);
+ setListAttributeTargetObserver(ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this));
else
- m_listAttributeTargetObserver = nullptr;
+ setListAttributeTargetObserver(nullptr);
}
void HTMLInputElement::listAttributeTargetChanged()
@@ -1532,16 +1529,6 @@ bool HTMLInputElement::isSteppable() const
return m_inputType->isSteppable();
}
-#if ENABLE(INPUT_SPEECH)
-
-bool HTMLInputElement::isSpeechEnabled() const
-{
- // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
- return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
-}
-
-#endif
-
bool HTMLInputElement::isTextButton() const
{
return m_inputType->isTextButton();
@@ -1577,11 +1564,6 @@ bool HTMLInputElement::isRangeControl() const
return m_inputType->isRangeControl();
}
-bool HTMLInputElement::isColorControl() const
-{
- return m_inputType->isColorControl();
-}
-
bool HTMLInputElement::isText() const
{
return m_inputType->isTextType();
@@ -1607,11 +1589,6 @@ bool HTMLInputElement::isNumberField() const
return m_inputType->isNumberField();
}
-bool HTMLInputElement::isSubmitButton() const
-{
- return m_inputType->isSubmitButton();
-}
-
bool HTMLInputElement::isTelephoneField() const
{
return m_inputType->isTelephoneField();
@@ -1669,7 +1646,7 @@ bool HTMLInputElement::supportsPlaceholder() const
void HTMLInputElement::updatePlaceholderText()
{
- return m_inputType->updatePlaceholderText();
+ return m_inputTypeView->updatePlaceholderText();
}
void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
@@ -1683,7 +1660,7 @@ void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
m_maxLength = maxLength;
if (oldMaxLength != maxLength)
updateValueIfNeeded();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
setNeedsValidityCheck();
}
@@ -1705,61 +1682,42 @@ bool HTMLInputElement::shouldAppearIndeterminate() const
return m_inputType->supportsIndeterminateAppearance() && indeterminate();
}
-#if ENABLE(MEDIA_CAPTURE)
-bool HTMLInputElement::capture() const
-{
- if (!isFileUpload() || !fastHasAttribute(captureAttr))
- return false;
-
- // As per crbug.com/240252, emit a deprecation warning when the "capture"
- // attribute is used as an enum. The spec has been updated and "capture" is
- // supposed to be used as a boolean.
- bool hasDeprecatedUsage = !fastGetAttribute(captureAttr).isNull();
- if (hasDeprecatedUsage)
- UseCounter::countDeprecation(document(), UseCounter::CaptureAttributeAsEnum);
- else
- UseCounter::count(document(), UseCounter::CaptureAttributeAsEnum);
-
- return true;
-}
-#endif
-
bool HTMLInputElement::isInRequiredRadioButtonGroup()
{
ASSERT(isRadioButton());
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- return buttons->isInRequiredGroup(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ return scope->isInRequiredGroup(this);
return false;
}
HTMLInputElement* HTMLInputElement::checkedRadioButtonForGroup() const
{
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- return buttons->checkedButtonForGroup(name());
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ return scope->checkedButtonForGroup(name());
return 0;
}
-CheckedRadioButtons* HTMLInputElement::checkedRadioButtons() const
+RadioButtonGroupScope* HTMLInputElement::radioButtonGroupScope() const
{
if (!isRadioButton())
return 0;
if (HTMLFormElement* formElement = form())
- return &formElement->checkedRadioButtons();
+ return &formElement->radioButtonGroupScope();
if (inDocument())
- return &document().formController()->checkedRadioButtons();
+ return &document().formController().radioButtonGroupScope();
return 0;
}
inline void HTMLInputElement::addToRadioButtonGroup()
{
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->addButton(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->addButton(this);
}
inline void HTMLInputElement::removeFromRadioButtonGroup()
{
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->removeButton(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->removeButton(this);
}
unsigned HTMLInputElement::height() const
@@ -1782,9 +1740,9 @@ void HTMLInputElement::setWidth(unsigned width)
setUnsignedIntegralAttribute(widthAttr, width);
}
-PassOwnPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
+PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
{
- return adoptPtr(new ListAttributeTargetObserver(id, element));
+ return adoptPtrWillBeNoop(new ListAttributeTargetObserver(id, element));
}
ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element)
@@ -1793,6 +1751,12 @@ ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id,
{
}
+void ListAttributeTargetObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ IdTargetObserver::trace(visitor);
+}
+
void ListAttributeTargetObserver::idTargetChanged()
{
m_element->listAttributeTargetChanged();
@@ -1831,7 +1795,7 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
parameters.locale = defaultLanguage();
else {
AtomicString computedLocale = computeInheritedLanguage();
- parameters.locale = computedLocale.isEmpty() ? AtomicString(defaultLanguage()) : computedLocale;
+ parameters.locale = computedLocale.isEmpty() ? defaultLanguage() : computedLocale;
}
StepRange stepRange = createStepRange(RejectAny);
@@ -1847,20 +1811,18 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
parameters.currentValue = value();
parameters.doubleValue = m_inputType->valueAsDouble();
parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- if (HTMLDataListElement* dataList = this->dataList()) {
- RefPtr<HTMLCollection> options = dataList->options();
- for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
- if (!isValidValue(option->value()))
- continue;
- DateTimeSuggestion suggestion;
- suggestion.value = m_inputType->parseToNumber(option->value(), Decimal::nan()).toDouble();
- if (std::isnan(suggestion.value))
- continue;
- suggestion.localizedValue = localizeValue(option->value());
- suggestion.label = option->value() == option->label() ? String() : option->label();
- parameters.suggestions.append(suggestion);
- }
+ if (HTMLDataListElement* dataList = this->dataList()) {
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
+ if (!isValidValue(option->value()))
+ continue;
+ DateTimeSuggestion suggestion;
+ suggestion.value = m_inputType->parseToNumber(option->value(), Decimal::nan()).toDouble();
+ if (std::isnan(suggestion.value))
+ continue;
+ suggestion.localizedValue = localizeValue(option->value());
+ suggestion.label = option->value() == option->label() ? String() : option->label();
+ parameters.suggestions.append(suggestion);
}
}
return true;
@@ -1871,11 +1833,24 @@ bool HTMLInputElement::supportsInputModeAttribute() const
return m_inputType->supportsInputModeAttribute();
}
+void HTMLInputElement::setShouldRevealPassword(bool value)
+{
+ if (m_shouldRevealPassword == value)
+ return;
+ m_shouldRevealPassword = value;
+ lazyReattachIfAttached();
+}
+
bool HTMLInputElement::isInteractiveContent() const
{
return m_inputType->isInteractiveContent();
}
+bool HTMLInputElement::supportsAutofocus() const
+{
+ return m_inputType->isInteractiveContent();
+}
+
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
PassRefPtr<RenderStyle> HTMLInputElement::customStyleForRenderer()
{
@@ -1883,4 +1858,9 @@ PassRefPtr<RenderStyle> HTMLInputElement::customStyleForRenderer()
}
#endif
+bool HTMLInputElement::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
+{
+ return m_inputType->shouldDispatchFormControlChangeEvent(oldValue, newValue);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h
index 4e61ec102c2..4bf5c86a1ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h
@@ -31,39 +31,39 @@
namespace WebCore {
-class CheckedRadioButtons;
class DragData;
class ExceptionState;
class FileList;
class HTMLDataListElement;
class HTMLImageLoader;
class HTMLOptionElement;
-class Icon;
class InputType;
class InputTypeView;
class KURL;
class ListAttributeTargetObserver;
+class RadioButtonGroupScope;
struct DateTimeChooserParameters;
class HTMLInputElement : public HTMLTextFormControlElement {
public:
- static PassRefPtr<HTMLInputElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLInputElement> create(Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLInputElement();
+ virtual void trace(Visitor*) OVERRIDE;
DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange);
- virtual bool shouldAutocomplete() const;
+ virtual bool shouldAutocomplete() const OVERRIDE FINAL;
// For ValidityState
- virtual bool hasBadInput() const OVERRIDE;
- virtual bool patternMismatch() const OVERRIDE;
- virtual bool rangeUnderflow() const OVERRIDE;
- virtual bool rangeOverflow() const;
- virtual bool stepMismatch() const OVERRIDE;
- virtual bool tooLong() const OVERRIDE;
- virtual bool typeMismatch() const OVERRIDE;
- virtual bool valueMissing() const OVERRIDE;
- virtual String validationMessage() const OVERRIDE;
+ virtual bool hasBadInput() const OVERRIDE FINAL;
+ virtual bool patternMismatch() const OVERRIDE FINAL;
+ virtual bool rangeUnderflow() const OVERRIDE FINAL;
+ virtual bool rangeOverflow() const OVERRIDE FINAL;
+ virtual bool stepMismatch() const OVERRIDE FINAL;
+ virtual bool tooLong() const OVERRIDE FINAL;
+ virtual bool typeMismatch() const OVERRIDE FINAL;
+ virtual bool valueMissing() const OVERRIDE FINAL;
+ virtual String validationMessage() const OVERRIDE FINAL;
// Returns the minimum value for type=date, number, or range. Don't call this for other types.
double minimum() const;
@@ -94,7 +94,6 @@ public:
bool isPasswordField() const;
bool isCheckbox() const;
bool isRangeControl() const;
- bool isColorControl() 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
@@ -106,7 +105,6 @@ public:
bool isFileUpload() const;
bool isImageButton() const;
bool isNumberField() const;
- bool isSubmitButton() const;
bool isTelephoneField() const;
bool isURLField() const;
bool isDateField() const;
@@ -115,12 +113,6 @@ public:
bool isTimeField() const;
bool isWeekField() const;
-#if ENABLE(INPUT_SPEECH)
- bool isSpeechEnabled() const;
-#endif
-
- HTMLElement* passwordGeneratorButtonElement() const;
-
bool checked() const { return m_isChecked; }
void setChecked(bool, TextFieldEventBehavior = DispatchNoEvent);
@@ -136,7 +128,7 @@ public:
void setType(const AtomicString&);
- String value() const;
+ virtual String value() const OVERRIDE;
void setValue(const String&, ExceptionState&, TextFieldEventBehavior = DispatchNoEvent);
void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
void setValueForUser(const String&);
@@ -149,15 +141,12 @@ public:
String localizeValue(const String&) const;
- // The value which is drawn by a renderer.
- String visibleValue() const;
-
const String& suggestedValue() const;
void setSuggestedValue(const String&);
void setEditingValue(const String&);
- double valueAsDate() const;
+ double valueAsDate(bool& isNull) const;
void setValueAsDate(double, ExceptionState&);
double valueAsNumber() const;
@@ -176,15 +165,16 @@ public:
void setSelectionRangeForBinding(int start, int end, ExceptionState&);
void setSelectionRangeForBinding(int start, int end, const String& direction, ExceptionState&);
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE FINAL;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+ virtual void updateFocusAppearance(bool restorePreviousSelection) OVERRIDE FINAL;
// 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);
+ virtual bool isActivatedSubmit() const OVERRIDE FINAL;
+ virtual void setActivatedSubmit(bool flag) OVERRIDE FINAL;
String altText() const;
@@ -195,7 +185,6 @@ public:
Vector<String> acceptMIMETypes();
Vector<String> acceptFileExtensions();
- const AtomicString& accept() const;
const AtomicString& alt() const;
void setSize(unsigned);
@@ -203,20 +192,19 @@ public:
KURL src() const;
- virtual int maxLength() const;
+ int maxLength() const;
void setMaxLength(int, ExceptionState&);
bool multiple() const;
FileList* files();
- void setFiles(PassRefPtr<FileList>);
+ void setFiles(PassRefPtrWillBeRawPtr<FileList>);
// Returns true if the given DragData has more than one dropped files.
bool receiveDroppedFiles(const DragData*);
String droppedFileSystemId();
- Icon* icon() const;
// These functions are used for rendering the input active during a
// drag-and-drop operation.
bool canReceiveDroppedFiles() const;
@@ -239,6 +227,9 @@ public:
// Functions for InputType classes.
void setValueInternal(const String&, TextFieldEventBehavior);
bool valueAttributeWasUpdatedAfterParsing() const { return m_valueAttributeWasUpdatedAfterParsing; }
+ void updateView();
+ bool needsToUpdateViewValue() const { return m_needsToUpdateViewValue; }
+ virtual void setInnerEditorValue(const String&) OVERRIDE;
void cacheSelectionInResponseToSetValue(int caretOffset) { cacheSelection(caretOffset, caretOffset, SelectionHasNoDirection); }
@@ -247,10 +238,6 @@ public:
String defaultToolTip() const;
-#if ENABLE(MEDIA_CAPTURE)
- bool capture() const;
-#endif
-
static const int maximumLength;
unsigned height() const;
@@ -258,20 +245,20 @@ public:
void setHeight(unsigned);
void setWidth(unsigned);
- virtual void blur() OVERRIDE;
+ virtual void blur() OVERRIDE FINAL;
void defaultBlur();
- virtual const AtomicString& name() const OVERRIDE;
+ virtual const AtomicString& name() const OVERRIDE FINAL;
void beginEditing();
void endEditing();
static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&);
- virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
- virtual bool matchesReadWritePseudoClass() const OVERRIDE;
- virtual void setRangeText(const String& replacement, ExceptionState&) OVERRIDE;
- virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&) OVERRIDE;
+ virtual bool matchesReadOnlyPseudoClass() const OVERRIDE FINAL;
+ virtual bool matchesReadWritePseudoClass() const OVERRIDE FINAL;
+ virtual void setRangeText(const String& replacement, ExceptionState&) OVERRIDE FINAL;
+ virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&) OVERRIDE FINAL;
bool hasImageLoader() const { return m_imageLoader; }
HTMLImageLoader* imageLoader();
@@ -280,105 +267,109 @@ public:
bool supportsInputModeAttribute() const;
+ void setShouldRevealPassword(bool value);
+ bool shouldRevealPassword() const { return m_shouldRevealPassword; }
+
protected:
HTMLInputElement(Document&, HTMLFormElement*, bool createdByParser);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
private:
enum AutoCompleteSetting { Uninitialized, On, Off };
- virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
- virtual void didAddShadowRoot(ShadowRoot&) OVERRIDE;
+ virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE FINAL;
+ virtual void willAddFirstAuthorShadowRoot() OVERRIDE FINAL;
- virtual void willChangeForm() OVERRIDE;
- virtual void didChangeForm() OVERRIDE;
+ virtual void willChangeForm() OVERRIDE FINAL;
+ virtual void didChangeForm() OVERRIDE FINAL;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
+ virtual void removedFrom(ContainerNode*) OVERRIDE FINAL;
+ virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE FINAL;
+ virtual void removeAllEventListeners() OVERRIDE FINAL;
- virtual bool hasCustomFocusLogic() const OVERRIDE;
- virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
- virtual bool isEnumeratable() const;
- virtual bool isInteractiveContent() const OVERRIDE;
- virtual bool supportLabels() const OVERRIDE;
- virtual void updateFocusAppearance(bool restorePreviousSelection);
- virtual bool shouldUseInputMethod();
+ virtual bool hasCustomFocusLogic() const OVERRIDE FINAL;
+ virtual bool isKeyboardFocusable() const OVERRIDE FINAL;
+ virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE FINAL;
+ virtual bool isEnumeratable() const OVERRIDE FINAL;
+ virtual bool isInteractiveContent() const OVERRIDE FINAL;
+ virtual bool supportLabels() const OVERRIDE FINAL;
+ virtual bool shouldUseInputMethod() OVERRIDE FINAL;
- virtual bool isTextFormControl() const { return isTextField(); }
+ virtual bool isTextFormControl() const OVERRIDE FINAL { return isTextField(); }
- virtual bool canTriggerImplicitSubmission() const { return isTextField(); }
+ virtual bool canTriggerImplicitSubmission() const OVERRIDE FINAL { return isTextField(); }
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE FINAL;
- virtual bool shouldSaveAndRestoreFormControlState() const OVERRIDE;
- virtual FormControlState saveFormControlState() const OVERRIDE;
- virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
+ virtual bool shouldSaveAndRestoreFormControlState() const OVERRIDE FINAL;
+ virtual FormControlState saveFormControlState() const OVERRIDE FINAL;
+ virtual void restoreFormControlState(const FormControlState&) OVERRIDE FINAL;
- virtual bool canStartSelection() const;
+ virtual bool canStartSelection() const OVERRIDE FINAL;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE FINAL;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual void finishParsingChildren();
-
- virtual void copyNonAttributePropertiesFromElement(const Element&);
+ virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE FINAL;
+ virtual void finishParsingChildren() OVERRIDE FINAL;
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual void copyNonAttributePropertiesFromElement(const Element&) OVERRIDE FINAL;
- virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
- virtual String resultForDialogSubmit() OVERRIDE;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
- virtual bool canBeSuccessfulSubmitButton() const OVERRIDE;
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE FINAL;
+ virtual String resultForDialogSubmit() OVERRIDE FINAL;
- virtual void resetImpl() OVERRIDE;
+ virtual bool canBeSuccessfulSubmitButton() const OVERRIDE FINAL;
- virtual void* preDispatchEventHandler(Event*);
- virtual void postDispatchEventHandler(Event*, void* dataFromPreDispatch);
+ virtual void resetImpl() OVERRIDE FINAL;
+ virtual bool supportsAutofocus() const OVERRIDE FINAL;
- virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool isInRange() const;
- virtual bool isOutOfRange() const;
+ virtual void* preDispatchEventHandler(Event*) OVERRIDE FINAL;
+ virtual void postDispatchEventHandler(Event*, void* dataFromPreDispatch) OVERRIDE FINAL;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE FINAL;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE FINAL;
+ virtual bool isInRange() const OVERRIDE FINAL;
+ virtual bool isOutOfRange() const OVERRIDE FINAL;
- bool supportsMaxLength() const { return isTextType(); }
bool isTextType() const;
bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
- virtual bool supportsPlaceholder() const;
- virtual void updatePlaceholderText();
- virtual bool isEmptyValue() const OVERRIDE { return innerTextValue().isEmpty(); }
- virtual bool isEmptySuggestedValue() const { return suggestedValue().isEmpty(); }
- virtual void handleFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
- virtual void handleBlurEvent();
+ virtual bool supportsPlaceholder() const OVERRIDE FINAL;
+ virtual void updatePlaceholderText() OVERRIDE FINAL;
+ virtual bool isEmptyValue() const OVERRIDE FINAL { return innerEditorValue().isEmpty(); }
+ virtual bool isEmptySuggestedValue() const OVERRIDE FINAL { return suggestedValue().isEmpty(); }
+ virtual void handleFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE FINAL;
+ virtual void handleBlurEvent() OVERRIDE FINAL;
- virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const;
- virtual bool recalcWillValidate() const;
- virtual void requiredAttributeChanged() OVERRIDE;
+ virtual bool isOptionalFormControl() const OVERRIDE FINAL { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const OVERRIDE FINAL;
+ virtual bool recalcWillValidate() const OVERRIDE FINAL;
+ virtual void requiredAttributeChanged() OVERRIDE FINAL;
void updateType();
- virtual void subtreeHasChanged();
+ virtual void subtreeHasChanged() OVERRIDE FINAL;
+ void setListAttributeTargetObserver(PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver>);
void resetListAttributeTargetObserver();
void parseMaxLengthAttribute(const AtomicString&);
void updateValueIfNeeded();
- bool canHaveSelection() const;
-
// Returns null if this isn't associated with any radio button group.
- CheckedRadioButtons* checkedRadioButtons() const;
+ RadioButtonGroupScope* radioButtonGroupScope() const;
void addToRadioButtonGroup();
void removeFromRadioButtonGroup();
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
#endif
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&) OVERRIDE;
+
AtomicString m_name;
String m_valueIfDirty;
String m_suggestedValue;
@@ -388,7 +379,6 @@ private:
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_hasNonEmptyList : 1;
@@ -397,16 +387,16 @@ private:
bool m_valueAttributeWasUpdatedAfterParsing : 1;
bool m_canReceiveDroppedFiles : 1;
bool m_hasTouchEventHandler : 1;
- RefPtr<InputType> m_inputType;
- RefPtr<InputTypeView> m_inputTypeView;
+ bool m_shouldRevealPassword : 1;
+ bool m_needsToUpdateViewValue : 1;
+ RefPtrWillBeMember<InputType> m_inputType;
+ RefPtrWillBeMember<InputTypeView> m_inputTypeView;
// The ImageLoader must be owned by this element because the loader code assumes
// that it lives as long as its owning element lives. If we move the loader into
// the ImageInput object we may delete the loader while this element lives on.
- OwnPtr<HTMLImageLoader> m_imageLoader;
- OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
+ OwnPtrWillBeMember<ListAttributeTargetObserver> m_listAttributeTargetObserver;
};
-DEFINE_NODE_TYPE_CASTS(HTMLInputElement, hasTagName(HTMLNames::inputTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl
index 6c2fa4e818d..8f44cfb2c30 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl
@@ -19,6 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#htmlinputelement
+
interface HTMLInputElement : HTMLElement {
[Reflect] attribute DOMString accept;
[Reflect] attribute DOMString align;
@@ -33,7 +35,7 @@ interface HTMLInputElement : HTMLElement {
// The 'files' attribute is intentionally not readonly.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22682
attribute FileList files;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString formAction;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString formAction;
[CustomElementCallbacks] attribute DOMString formEnctype;
[CustomElementCallbacks] attribute DOMString formMethod;
[Reflect] attribute boolean formNoValidate;
@@ -41,7 +43,7 @@ interface HTMLInputElement : HTMLElement {
[CustomElementCallbacks] attribute unsigned long height;
attribute boolean indeterminate;
[RuntimeEnabled=InputModeAttribute, Reflect] attribute DOMString inputMode;
- [RuntimeEnabled=DataListElement] readonly attribute HTMLElement list;
+ readonly attribute HTMLElement list;
[Reflect] attribute DOMString max;
[RaisesException=Setter, CustomElementCallbacks] attribute long maxLength;
[Reflect] attribute DOMString min;
@@ -52,15 +54,15 @@ interface HTMLInputElement : HTMLElement {
[Reflect] attribute boolean readOnly;
[Reflect] attribute boolean required;
[RaisesException=Setter, CustomElementCallbacks] attribute unsigned long size; // Changed string -> long -> unsigned long
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
[Reflect] attribute DOMString step;
[CustomElementCallbacks] attribute DOMString type; // readonly dropped as part of DOM level 2
[CustomElementCallbacks] attribute DOMString defaultValue;
[Reflect] attribute DOMString useMap;
// See the discussion in https://bugs.webkit.org/show_bug.cgi?id=100085
[TreatNullAs=NullString, RaisesException=Setter, CustomElementCallbacks] attribute DOMString value;
- [RaisesException=Setter, CustomElementCallbacks] attribute Date valueAsDate;
- [RaisesException=Setter, CustomElementCallbacks] attribute double valueAsNumber;
+ [RaisesException=Setter, CustomElementCallbacks] attribute Date? valueAsDate;
+ [RaisesException=Setter, CustomElementCallbacks] attribute unrestricted double valueAsNumber;
[RaisesException, CustomElementCallbacks] void stepUp(optional long n);
[RaisesException, CustomElementCallbacks] void stepDown(optional long n);
@@ -83,7 +85,7 @@ interface HTMLInputElement : HTMLElement {
[RaisesException] void setRangeText(DOMString replacement,
unsigned long start,
unsigned long end,
- [Default=NullString] optional DOMString selectionMode);
+ optional DOMString selectionMode = null);
[RaisesException, ImplementedAs=setSelectionRangeForBinding]
void setSelectionRange([Default=Undefined] optional long start,
@@ -91,11 +93,8 @@ interface HTMLInputElement : HTMLElement {
optional DOMString direction);
// Non-standard attributes
- [Reflect, RuntimeEnabled=DirectoryUpload] attribute boolean webkitdirectory;
- [Reflect] attribute boolean incremental;
- [Conditional=INPUT_SPEECH, Reflect, RuntimeEnabled=SpeechInput] attribute boolean webkitSpeech;
- [Conditional=INPUT_SPEECH, Reflect, RuntimeEnabled=SpeechInput] attribute boolean webkitGrammar;
- [Conditional=INPUT_SPEECH] attribute EventHandler onwebkitspeechchange;
+ [Reflect, MeasureAs=PrefixedDirectoryAttribute] attribute boolean webkitdirectory;
+ [Reflect, MeasureAs=IncrementalAttribute] attribute boolean incremental;
// See http://www.w3.org/TR/html-media-capture/
[Conditional=MEDIA_CAPTURE, Reflect] attribute boolean capture;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
index e6c80d009ae..231ee99672c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLKeygenElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
@@ -46,7 +46,13 @@ HTMLKeygenElement::HTMLKeygenElement(Document& document, HTMLFormElement* form)
: HTMLFormControlElementWithState(keygenTag, document, form)
{
ScriptWrappable::init(this);
- ensureUserAgentShadowRoot();
+}
+
+PassRefPtrWillBeRawPtr<HTMLKeygenElement> HTMLKeygenElement::create(Document& document, HTMLFormElement* form)
+{
+ RefPtrWillBeRawPtr<HTMLKeygenElement> keygen = adoptRefWillBeNoop(new HTMLKeygenElement(document, form));
+ keygen->ensureUserAgentShadowRoot();
+ return keygen.release();
}
void HTMLKeygenElement::didAddUserAgentShadowRoot(ShadowRoot& root)
@@ -57,10 +63,10 @@ void HTMLKeygenElement::didAddUserAgentShadowRoot(ShadowRoot& root)
getSupportedKeySizes(locale(), keys);
// Create a select element with one option element for each key size.
- RefPtr<HTMLSelectElement> select = HTMLSelectElement::create(document());
- select->setPseudo(keygenSelectPseudoId);
+ RefPtrWillBeRawPtr<HTMLSelectElement> select = HTMLSelectElement::create(document());
+ select->setShadowPseudoId(keygenSelectPseudoId);
for (size_t i = 0; i < keys.size(); ++i) {
- RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document());
+ RefPtrWillBeRawPtr<HTMLOptionElement> option = HTMLOptionElement::create(document());
option->appendChild(Text::create(document(), keys[i]));
select->appendChild(option);
}
@@ -112,4 +118,9 @@ bool HTMLKeygenElement::isInteractiveContent() const
return true;
}
+bool HTMLKeygenElement::supportsAutofocus() const
+{
+ return true;
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
index 292a78ea29d..7c4f783caa1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
@@ -32,10 +32,7 @@ class HTMLSelectElement;
class HTMLKeygenElement FINAL : public HTMLFormControlElementWithState {
public:
- static PassRefPtr<HTMLKeygenElement> create(Document& document, HTMLFormElement* form)
- {
- return adoptRef(new HTMLKeygenElement(document, form));
- }
+ static PassRefPtrWillBeRawPtr<HTMLKeygenElement> create(Document&, HTMLFormElement*);
virtual bool willValidate() const OVERRIDE { return false; }
@@ -54,6 +51,7 @@ private:
virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
virtual void resetImpl() OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl
index 59af63817b0..4484e2b7b11 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl
@@ -33,7 +33,7 @@ interface HTMLKeygenElement : HTMLElement {
[Reflect] attribute DOMString challenge;
[Reflect] attribute boolean disabled;
[ImplementedAs=formOwner] readonly attribute HTMLFormElement form;
- [Reflect] attribute DOMString keytype;
+ [Reflect, ReflectOnly="rsa", ReflectMissing="rsa"] attribute DOMString keytype;
[Reflect] attribute DOMString name;
readonly attribute DOMString type;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp
index aba20072981..c74defe7134 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp
@@ -23,25 +23,23 @@
#include "config.h"
#include "core/html/HTMLLIElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/rendering/RenderListItem.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLLIElement::HTMLLIElement(Document& document)
+inline HTMLLIElement::HTMLLIElement(Document& document)
: HTMLElement(liTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLIElement> HTMLLIElement::create(Document& document)
-{
- return adoptRef(new HTMLLIElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLLIElement)
bool HTMLLIElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -85,23 +83,23 @@ void HTMLLIElement::attach(const AttachContext& context)
if (renderer() && renderer()->isListItem()) {
RenderListItem* listItemRenderer = toRenderListItem(renderer());
+ ASSERT(!document().childNeedsDistributionRecalc());
+
// Find the enclosing list node.
Element* listNode = 0;
Element* current = this;
while (!listNode) {
- current = current->parentElement();
+ current = NodeRenderingTraversal::parentElement(current);
if (!current)
break;
- if (current->hasTagName(ulTag) || current->hasTagName(olTag))
+ if (isHTMLUListElement(*current) || isHTMLOListElement(*current))
listNode = current;
}
// If we are not in a list, tell the renderer so it can position us inside.
// We don't want to change our style to say "inside" since that would affect nested nodes.
- if (!listNode) {
+ if (!listNode)
listItemRenderer->setNotInList(true);
- listItemRenderer->updateMarkerLocation();
- }
parseValue(fastGetAttribute(valueAttr));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h
index a16f4b06f85..d71b76c73a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLLIElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLLIElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLLIElement);
private:
explicit HTMLLIElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
index 6e8fa3d5ea0..ffaa6316873 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
@@ -25,23 +25,25 @@
#include "config.h"
#include "core/html/HTMLLabelElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/editing/FrameSelection.h"
+#include "core/events/MouseEvent.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormAssociatedElement.h"
namespace WebCore {
using namespace HTMLNames;
-static bool supportsLabels(Element* element)
+static bool supportsLabels(const Element& element)
{
- if (!element || !element->isHTMLElement())
+ if (!element.isHTMLElement())
return false;
- if (!toHTMLElement(element)->isLabelable())
+ if (!toHTMLElement(element).isLabelable())
return false;
- return toLabelableElement(element)->supportLabels();
+ return toLabelableElement(element).supportLabels();
}
inline HTMLLabelElement::HTMLLabelElement(Document& document)
@@ -50,10 +52,7 @@ inline HTMLLabelElement::HTMLLabelElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLabelElement> HTMLLabelElement::create(Document& document)
-{
- return adoptRef(new HTMLLabelElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLLabelElement)
bool HTMLLabelElement::rendererIsFocusable() const
{
@@ -61,16 +60,15 @@ bool HTMLLabelElement::rendererIsFocusable() const
return that->isContentEditable();
}
-LabelableElement* HTMLLabelElement::control()
+LabelableElement* HTMLLabelElement::control() const
{
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".
- Element* element = this;
- while ((element = ElementTraversal::next(*element, this))) {
- if (!supportsLabels(element))
+ for (Element* element = ElementTraversal::next(*this, this); element; element = ElementTraversal::next(*element, this)) {
+ if (!supportsLabels(*element))
continue;
return toLabelableElement(element);
}
@@ -78,7 +76,7 @@ LabelableElement* HTMLLabelElement::control()
}
if (Element* element = treeScope().getElementById(controlId)) {
- if (supportsLabels(element))
+ if (supportsLabels(*element))
return toLabelableElement(element);
}
@@ -87,7 +85,7 @@ LabelableElement* HTMLLabelElement::control()
HTMLFormElement* HTMLLabelElement::formOwner() const
{
- return FormAssociatedElement::findAssociatedForm(this, 0);
+ return FormAssociatedElement::findAssociatedForm(this);
}
void HTMLLabelElement::setActive(bool down)
@@ -138,7 +136,19 @@ void HTMLLabelElement::defaultEventHandler(Event* evt)
static bool processingClick = false;
if (evt->type() == EventTypeNames::click && !processingClick) {
- RefPtr<HTMLElement> element = control();
+ // If the click is not simulated and the text of label element is
+ // selected, do not pass the event to control element.
+ // Note: a click event may be not a mouse event if created by
+ // document.createEvent().
+ if (evt->isMouseEvent() && !toMouseEvent(evt)->isSimulated()) {
+ if (LocalFrame* frame = document().frame()) {
+ if (frame->selection().selection().isRange())
+ return;
+ }
+ }
+
+
+ RefPtrWillBeRawPtr<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.
@@ -152,7 +162,7 @@ void HTMLLabelElement::defaultEventHandler(Event* evt)
document().updateLayoutIgnorePendingStylesheets();
if (element->isMouseFocusable())
- element->focus(true, FocusDirectionMouse);
+ element->focus(true, FocusTypeMouse);
// Click the corresponding control.
element->dispatchSimulatedClick(evt);
@@ -173,13 +183,13 @@ bool HTMLLabelElement::willRespondToMouseClickEvents()
return HTMLElement::willRespondToMouseClickEvents();
}
-void HTMLLabelElement::focus(bool, FocusDirection direction)
+void HTMLLabelElement::focus(bool, FocusType type)
{
// to match other browsers, always restore previous selection
if (HTMLElement* element = control())
- element->focus(true, direction);
+ element->focus(true, type);
if (isFocusable())
- HTMLElement::focus(true, direction);
+ HTMLElement::focus(true, type);
}
void HTMLLabelElement::accessKeyAction(bool sendMouseEvents)
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h
index 8ad7c6770ae..2e585d8e7ac 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h
@@ -31,9 +31,9 @@ namespace WebCore {
class HTMLLabelElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLLabelElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLLabelElement);
- LabelableElement* control();
+ LabelableElement* control() const;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
@@ -45,30 +45,18 @@ private:
virtual bool rendererIsFocusable() const OVERRIDE;
virtual bool isInteractiveContent() const OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
// Overridden to update the hover/active state of the corresponding control.
virtual void setActive(bool = true) OVERRIDE;
virtual void setHovered(bool = true) OVERRIDE;
// Overridden to either click() or focus() the corresponding control.
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual void focus(bool restorePreviousSelection, FocusDirection) OVERRIDE;
+ virtual void focus(bool restorePreviousSelection, FocusType) OVERRIDE;
};
-inline bool isHTMLLabelElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::labelTag);
-}
-
-inline bool isHTMLLabelElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::labelTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLLabelElement, hasTagName(HTMLNames::labelTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp
index f15aed3010b..d5d32b16d89 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/HTMLLegendElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFormControlElement.h"
@@ -41,39 +41,30 @@ inline HTMLLegendElement::HTMLLegendElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLegendElement> HTMLLegendElement::create(Document& document)
-{
- return adoptRef(new HTMLLegendElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLLegendElement)
HTMLFormControlElement* HTMLLegendElement::associatedControl()
{
// Check if there's a fieldset belonging to this legend.
Element* fieldset = parentElement();
- while (fieldset && !fieldset->hasTagName(fieldsetTag))
+ while (fieldset && !isHTMLFieldSetElement(*fieldset))
fieldset = fieldset->parentElement();
if (!fieldset)
return 0;
// Find first form element inside the fieldset that is not a legend element.
// FIXME: Should we consider tabindex?
- Element* element = fieldset;
- while ((element = ElementTraversal::next(*element, fieldset))) {
- if (element->isFormControlElement())
- return toHTMLFormControlElement(element);
- }
-
- return 0;
+ return Traversal<HTMLFormControlElement>::next(*fieldset, fieldset);
}
-void HTMLLegendElement::focus(bool, FocusDirection direction)
+void HTMLLegendElement::focus(bool, FocusType type)
{
if (isFocusable())
- Element::focus(true, direction);
+ Element::focus(true, type);
// To match other browsers' behavior, never restore previous selection.
if (HTMLFormControlElement* control = associatedControl())
- control->focus(false, direction);
+ control->focus(false, type);
}
void HTMLLegendElement::accessKeyAction(bool sendMouseEvents)
@@ -88,7 +79,7 @@ HTMLFormElement* HTMLLegendElement::form() const
// its parent, then the form attribute must return the same value as the
// form attribute on that fieldset element. Otherwise, it must return null.
ContainerNode* fieldset = parentNode();
- if (!fieldset || !fieldset->hasTagName(fieldsetTag))
+ if (!isHTMLFieldSetElement(fieldset))
return 0;
return toHTMLFieldSetElement(fieldset)->formOwner();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h
index 74290a8ea33..e456be8a7ee 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h
@@ -32,7 +32,7 @@ class HTMLFormControlElement;
class HTMLLegendElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLLegendElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLLegendElement);
HTMLFormElement* form() const;
@@ -42,12 +42,10 @@ private:
// Control in the legend's fieldset that gets focus and access key.
HTMLFormControlElement* associatedControl();
- virtual void accessKeyAction(bool sendMouseEvents);
- virtual void focus(bool restorePreviousSelection, FocusDirection) OVERRIDE;
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
+ virtual void focus(bool restorePreviousSelection, FocusType) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLLegendElement, hasTagName(HTMLNames::legendTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index eea0d9d3d27..f36b9200c18 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -25,61 +25,136 @@
#include "config.h"
#include "core/html/HTMLLinkElement.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
#include "core/events/Event.h"
#include "core/events/EventSender.h"
-#include "core/dom/StyleEngine.h"
#include "core/fetch/CSSStyleSheetResource.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/html/LinkImport.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/LinkManifest.h"
+#include "core/html/imports/LinkImport.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
+#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
using namespace HTMLNames;
+template <typename CharacterType>
+static void parseSizes(const CharacterType* value, unsigned length, Vector<IntSize>& iconSizes)
+{
+ enum State {
+ ParseStart,
+ ParseWidth,
+ ParseHeight
+ };
+ int width = 0;
+ unsigned start = 0;
+ unsigned i = 0;
+ State state = ParseStart;
+ bool invalid = false;
+ for (; i < length; ++i) {
+ if (state == ParseWidth) {
+ if (value[i] == 'x' || value[i] == 'X') {
+ if (i == start) {
+ invalid = true;
+ break;
+ }
+ width = charactersToInt(value + start, i - start);
+ start = i + 1;
+ state = ParseHeight;
+ } else if (value[i] < '0' || value[i] > '9') {
+ invalid = true;
+ break;
+ }
+ } else if (state == ParseHeight) {
+ if (value[i] == ' ') {
+ if (i == start) {
+ invalid = true;
+ break;
+ }
+ int height = charactersToInt(value + start, i - start);
+ iconSizes.append(IntSize(width, height));
+ start = i + 1;
+ state = ParseStart;
+ } else if (value[i] < '0' || value[i] > '9') {
+ invalid = true;
+ break;
+ }
+ } else if (state == ParseStart) {
+ if (value[i] >= '0' && value[i] <= '9') {
+ start = i;
+ state = ParseWidth;
+ } else if (value[i] != ' ') {
+ invalid = true;
+ break;
+ }
+ }
+ }
+ if (invalid || state == ParseWidth || (state == ParseHeight && start == i)) {
+ iconSizes.clear();
+ return;
+ }
+ if (state == ParseHeight && i > start) {
+ int height = charactersToInt(value + start, i - start);
+ iconSizes.append(IntSize(width, height));
+ }
+}
+
static LinkEventSender& linkLoadEventSender()
{
DEFINE_STATIC_LOCAL(LinkEventSender, sharedLoadEventSender, (EventTypeNames::load));
return sharedLoadEventSender;
}
+void HTMLLinkElement::parseSizesAttribute(const AtomicString& value, Vector<IntSize>& iconSizes)
+{
+ ASSERT(iconSizes.isEmpty());
+ if (value.isEmpty())
+ return;
+ if (value.is8Bit())
+ parseSizes(value.characters8(), value.length(), iconSizes);
+ else
+ parseSizes(value.characters16(), value.length(), iconSizes);
+}
+
inline HTMLLinkElement::HTMLLinkElement(Document& document, bool createdByParser)
: HTMLElement(linkTag, document)
, m_linkLoader(this)
, m_sizes(DOMSettableTokenList::create())
, m_createdByParser(createdByParser)
, m_isInShadowTree(false)
- , m_beforeLoadRecurseCount(0)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLinkElement> HTMLLinkElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLLinkElement> HTMLLinkElement::create(Document& document, bool createdByParser)
{
- return adoptRef(new HTMLLinkElement(document, createdByParser));
+ return adoptRefWillBeNoop(new HTMLLinkElement(document, createdByParser));
}
HTMLLinkElement::~HTMLLinkElement()
{
+#if !ENABLE(OILPAN)
m_link.clear();
if (inDocument())
document().styleEngine()->removeStyleSheetCandidateNode(this);
+#endif
linkLoadEventSender().cancelEvent(this);
}
@@ -96,6 +171,7 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
process();
} else if (name == sizesAttr) {
m_sizes->setValue(value);
+ parseSizesAttribute(value, m_iconSizes);
process();
} else if (name == mediaAttr) {
m_media = value.string().lower();
@@ -103,9 +179,7 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
} else if (name == disabledAttr) {
if (LinkStyle* link = linkStyle())
link->setDisabledState(!value.isNull());
- } else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else {
+ } else {
if (name == titleAttr) {
if (LinkStyle* link = linkStyle())
link->setSheetTitle(value);
@@ -117,25 +191,12 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
bool HTMLLinkElement::shouldLoadLink()
{
- bool continueLoad = true;
- RefPtr<Document> originalDocument(document());
- int recursionRank = ++m_beforeLoadRecurseCount;
- if (!dispatchBeforeLoadEvent(getNonEmptyURLAttribute(hrefAttr)))
- continueLoad = false;
-
- // A beforeload handler might have removed us from the document or changed the document.
- if (continueLoad && (!inDocument() || document() != originalDocument))
- continueLoad = false;
-
- // If the beforeload handler recurses into the link element by mutating it, we should only
- // let the latest (innermost) mutation occur.
- if (recursionRank != m_beforeLoadRecurseCount)
- continueLoad = false;
-
- if (recursionRank == 1)
- m_beforeLoadRecurseCount = 0;
+ return inDocument();
+}
- return continueLoad;
+bool HTMLLinkElement::loadLink(const String& type, const KURL& url)
+{
+ return m_linkLoader.loadLink(m_relAttribute, fastGetAttribute(HTMLNames::crossoriginAttr), type, url, document());
}
LinkResource* HTMLLinkElement::linkResourceToProcess()
@@ -147,11 +208,13 @@ LinkResource* HTMLLinkElement::linkResourceToProcess()
}
if (!m_link) {
- if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled())
+ if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled()) {
m_link = LinkImport::create(this);
- else {
- OwnPtr<LinkStyle> link = LinkStyle::create(this);
- if (fastHasAttribute(disabledAttr))
+ } else if (m_relAttribute.isManifest() && RuntimeEnabledFeatures::manifestEnabled()) {
+ m_link = LinkManifest::create(this);
+ } else {
+ OwnPtrWillBeRawPtr<LinkStyle> link = LinkStyle::create(this);
+ if (fastHasAttribute(disabledAttr) || m_relAttribute.isTransitionExitingStylesheet())
link->setDisabledState(true);
m_link = link.release();
}
@@ -187,6 +250,14 @@ void HTMLLinkElement::process()
link->process();
}
+void HTMLLinkElement::enableIfExitTransitionStyle()
+{
+ if (m_relAttribute.isTransitionExitingStylesheet()) {
+ if (LinkStyle* link = linkStyle())
+ link->setDisabledState(false);
+ }
+}
+
Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
@@ -200,6 +271,10 @@ Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode*
document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
process();
+
+ if (m_link)
+ m_link->ownerInserted();
+
return InsertionDone;
}
@@ -217,7 +292,7 @@ void HTMLLinkElement::removedFrom(ContainerNode* insertionPoint)
}
document().styleEngine()->removeStyleSheetCandidateNode(this);
- RefPtr<StyleSheet> removedSheet = sheet();
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = sheet();
if (m_link)
m_link->ownerRemoved();
@@ -309,6 +384,22 @@ bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLLinkElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLLinkElement::subResourceAttributeName() const
+{
+ // If the link element is not css, ignore it.
+ if (equalIgnoringCase(getAttribute(typeAttr), "text/css")) {
+ // FIXME: Add support for extracting links of sub-resources which
+ // are inside style-sheet such as @import, @font-face, url(), etc.
+ return hrefAttr;
+ }
+ return HTMLElement::subResourceAttributeName();
+}
+
KURL HTMLLinkElement::href() const
{
return document().completeURL(getAttribute(hrefAttr));
@@ -319,14 +410,14 @@ const AtomicString& HTMLLinkElement::rel() const
return getAttribute(relAttr);
}
-String HTMLLinkElement::target() const
+const AtomicString& HTMLLinkElement::type() const
{
- return getAttribute(targetAttr);
+ return getAttribute(typeAttr);
}
-const AtomicString& HTMLLinkElement::type() const
+bool HTMLLinkElement::async() const
{
- return getAttribute(typeAttr);
+ return fastHasAttribute(HTMLNames::asyncAttr);
}
IconType HTMLLinkElement::iconType() const
@@ -334,38 +425,26 @@ IconType HTMLLinkElement::iconType() const
return m_relAttribute.iconType();
}
-String HTMLLinkElement::iconSizes() const
+const Vector<IntSize>& HTMLLinkElement::iconSizes() const
{
- return m_sizes->toString();
+ return m_iconSizes;
}
-void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+DOMSettableTokenList* HTMLLinkElement::sizes() const
{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- // Favicons are handled by a special case in LegacyWebArchive::create()
- if (m_relAttribute.iconType() != InvalidIcon)
- return;
-
- if (!m_relAttribute.isStyleSheet())
- return;
-
- // Append the URL of this link element.
- addSubresourceURL(urls, href());
-
- // Walk the URLs linked by the linked-to stylesheet.
- if (CSSStyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet())
- styleSheet->contents()->addSubresourceStyleURLs(urls);
+ return m_sizes.get();
}
-DOMSettableTokenList* HTMLLinkElement::sizes() const
+void HTMLLinkElement::trace(Visitor* visitor)
{
- return m_sizes.get();
+ visitor->trace(m_link);
+ visitor->trace(m_sizes);
+ HTMLElement::trace(visitor);
}
-PassOwnPtr<LinkStyle> LinkStyle::create(HTMLLinkElement* owner)
+PassOwnPtrWillBeRawPtr<LinkStyle> LinkStyle::create(HTMLLinkElement* owner)
{
- return adoptPtr(new LinkStyle(owner));
+ return adoptPtrWillBeNoop(new LinkStyle(owner));
}
LinkStyle::LinkStyle(HTMLLinkElement* owner)
@@ -380,8 +459,10 @@ LinkStyle::LinkStyle(HTMLLinkElement* owner)
LinkStyle::~LinkStyle()
{
+#if !ENABLE(OILPAN)
if (m_sheet)
m_sheet->clearOwnerNode();
+#endif
}
Document& LinkStyle::document()
@@ -397,11 +478,11 @@ void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const
}
// Completing the sheet load may cause scripts to execute.
- RefPtr<Node> protector(m_owner);
+ RefPtrWillBeRawPtr<Node> protector(m_owner.get());
- CSSParserContext parserContext(m_owner->document(), baseURL, charset);
+ CSSParserContext parserContext(m_owner->document(), 0, baseURL, charset);
- if (RefPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
+ if (RefPtrWillBeRawPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
ASSERT(restoredSheet->isCacheable());
ASSERT(!restoredSheet->isLoading());
@@ -412,12 +493,11 @@ void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const
m_sheet->setTitle(m_owner->title());
m_loading = false;
- sheetLoaded();
- notifyLoadedSheetAndAllCriticalSubresources(false);
+ restoredSheet->checkLoaded();
return;
}
- RefPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
+ RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
if (m_sheet)
clearSheet();
@@ -465,7 +545,7 @@ void LinkStyle::clearSheet()
ASSERT(m_sheet);
ASSERT(m_sheet->ownerNode() == m_owner);
m_sheet->clearOwnerNode();
- m_sheet = 0;
+ m_sheet = nullptr;
}
bool LinkStyle::styleSheetIsLoading() const
@@ -488,7 +568,7 @@ void LinkStyle::addPendingSheet(PendingSheetType type)
m_owner->document().styleEngine()->addPendingSheet();
}
-void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notification)
+void LinkStyle::removePendingSheet()
{
PendingSheetType type = m_pendingSheetType;
m_pendingSheetType = None;
@@ -501,14 +581,11 @@ void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notificati
// Document::removePendingSheet() triggers the style selector recalc for blocking sheets.
// FIXME: We don't have enough knowledge at this point to know if we're adding or removing a sheet
// so we can't call addedStyleSheet() or removedStyleSheet().
- m_owner->document().styleResolverChanged(RecalcStyleImmediately);
+ m_owner->document().styleResolverChanged();
return;
}
- m_owner->document().styleEngine()->removePendingSheet(m_owner,
- notification == RemovePendingSheetNotifyImmediately
- ? StyleEngine::RemovePendingSheetNotifyImmediately
- : StyleEngine::RemovePendingSheetNotifyLater);
+ m_owner->document().styleEngine()->removePendingSheet(m_owner);
}
void LinkStyle::setDisabledState(bool disabled)
@@ -548,7 +625,7 @@ void LinkStyle::setDisabledState(bool disabled)
process();
} else {
// FIXME: We don't have enough knowledge here to know if we should call addedStyleSheet() or removedStyleSheet().
- m_owner->document().styleResolverChanged(RecalcStyleDeferred);
+ m_owner->document().styleResolverChanged();
}
}
}
@@ -566,14 +643,14 @@ void LinkStyle::process()
return;
if (!document().contentSecurityPolicy()->allowImageFromSource(builder.url()))
return;
- if (document().frame())
+ if (document().frame() && document().frame()->loader().client())
document().frame()->loader().client()->dispatchDidChangeIcons(m_owner->relAttribute().iconType());
}
if (!m_owner->loadLink(type, builder.url()))
return;
- if ((m_disabledState != Disabled) && m_owner->relAttribute().isStyleSheet()
+ if ((m_disabledState != Disabled) && (m_owner->relAttribute().isStyleSheet() || m_owner->relAttribute().isTransitionExitingStylesheet())
&& shouldLoadResource() && builder.url().isValid()) {
if (resource()) {
@@ -584,15 +661,17 @@ void LinkStyle::process()
if (!m_owner->shouldLoadLink())
return;
- Frame* frame = loadingFrame();
m_loading = true;
bool mediaQueryMatches = true;
if (!m_owner->media().isEmpty()) {
- RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(document());
- RefPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
- MediaQueryEvaluator evaluator(frame->view()->mediaType(), frame, documentStyle.get());
- mediaQueryMatches = evaluator.eval(media.get());
+ LocalFrame* frame = loadingFrame();
+ if (Document* document = loadingFrame()->document()) {
+ RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*document);
+ RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
+ MediaQueryEvaluator evaluator(frame->view()->mediaType(), frame);
+ mediaQueryMatches = evaluator.eval(media.get());
+ }
}
// Don't hold up render tree construction and script execution on stylesheets
@@ -602,6 +681,9 @@ void LinkStyle::process()
// Load stylesheets that are not needed for the rendering immediately with low priority.
FetchRequest request = builder.build(blocking);
+ AtomicString crossOriginMode = m_owner->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull())
+ request.setCrossOriginAccessControl(document().securityOrigin(), crossOriginMode);
setResource(document().fetcher()->fetchCSSStyleSheet(request));
if (!resource()) {
@@ -611,7 +693,7 @@ void LinkStyle::process()
}
} else if (m_sheet) {
// we no longer contain a stylesheet, e.g. perhaps rel or type was changed
- RefPtr<StyleSheet> removedSheet = m_sheet;
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
clearSheet();
document().removedStyleSheet(removedSheet.get());
}
@@ -629,7 +711,13 @@ void LinkStyle::ownerRemoved()
clearSheet();
if (styleSheetIsLoading())
- removePendingSheet(RemovePendingSheetNotifyLater);
+ removePendingSheet();
+}
+
+void LinkStyle::trace(Visitor* visitor)
+{
+ visitor->trace(m_sheet);
+ LinkResource::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h
index 28b01dff582..e9ac4431e35 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h
@@ -56,9 +56,9 @@ typedef EventSender<HTMLLinkElement> LinkEventSender;
// sticking current way so far.
//
class LinkStyle FINAL : public LinkResource, ResourceOwner<StyleSheetResource> {
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<LinkStyle> create(HTMLLinkElement* owner);
+ static PassOwnPtrWillBeRawPtr<LinkStyle> create(HTMLLinkElement* owner);
explicit LinkStyle(HTMLLinkElement* owner);
virtual ~LinkStyle();
@@ -67,6 +67,7 @@ public:
virtual void process() OVERRIDE;
virtual void ownerRemoved() OVERRIDE;
virtual bool hasLoaded() const OVERRIDE { return m_loadedSheet; }
+ virtual void trace(Visitor*) OVERRIDE;
void startLoadingDynamicSheet();
void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred);
@@ -84,7 +85,7 @@ public:
CSSStyleSheet* sheet() const { return m_sheet.get(); }
private:
- // From ResourceClient
+ // From StyleSheetResourceClient
virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*) OVERRIDE;
enum DisabledState {
@@ -99,17 +100,12 @@ private:
Blocking
};
- enum RemovePendingSheetNotificationType {
- RemovePendingSheetNotifyImmediately,
- RemovePendingSheetNotifyLater
- };
-
void clearSheet();
void addPendingSheet(PendingSheetType);
- void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+ void removePendingSheet();
Document& document();
- RefPtr<CSSStyleSheet> m_sheet;
+ RefPtrWillBeMember<CSSStyleSheet> m_sheet;
DisabledState m_disabledState;
PendingSheetType m_pendingSheetType;
bool m_loading;
@@ -120,7 +116,7 @@ private:
class HTMLLinkElement FINAL : public HTMLElement, public LinkLoaderClient {
public:
- static PassRefPtr<HTMLLinkElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLLinkElement> create(Document&, bool createdByParser);
virtual ~HTMLLinkElement();
KURL href() const;
@@ -129,35 +125,46 @@ public:
String typeValue() const { return m_type; }
const LinkRelAttribute& relAttribute() const { return m_relAttribute; }
- virtual String target() const;
-
const AtomicString& type() const;
IconType iconType() const;
- // the icon size string as parsed from the HTML attribute
- String iconSizes() const;
+ // the icon sizes as parsed from the HTML attribute
+ const Vector<IntSize>& iconSizes() const;
+
+ bool async() const;
CSSStyleSheet* sheet() const { return linkStyle() ? linkStyle()->sheet() : 0; }
Document* import() const;
bool styleSheetIsLoading() const;
+ bool isImport() const { return linkImport(); }
bool isDisabled() const { return linkStyle() && linkStyle()->isDisabled(); }
bool isEnabledViaScript() const { return linkStyle() && linkStyle()->isEnabledViaScript(); }
+ void enableIfExitTransitionStyle();
+
DOMSettableTokenList* sizes() const;
void dispatchPendingEvent(LinkEventSender*);
void scheduleEvent();
+ void dispatchEventImmediately();
static void dispatchPendingLoadEvents();
// From LinkLoaderClient
virtual bool shouldLoadLink() OVERRIDE;
// For LinkStyle
- bool loadLink(const String& type, const KURL& url) { return m_linkLoader.loadLink(m_relAttribute, type, url, document()); }
+ bool loadLink(const String& type, const KURL&);
bool isAlternate() const { return linkStyle()->isUnset() && m_relAttribute.isAlternate(); }
bool shouldProcessStyle() { return linkResourceToProcess() && linkStyle(); }
+ bool isCreatedByParser() const { return m_createdByParser; }
+
+ // Parse the icon size attribute into |iconSizes|, make this method public
+ // visible for testing purpose.
+ static void parseSizesAttribute(const AtomicString& value, Vector<IntSize>& iconSizes);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
@@ -173,11 +180,12 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
virtual bool sheetLoaded() OVERRIDE;
virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) OVERRIDE;
virtual void startLoadingDynamicSheet() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const OVERRIDE;
- virtual void finishParsingChildren();
+ virtual void finishParsingChildren() OVERRIDE;
// From LinkLoaderClient
virtual void linkLoaded() OVERRIDE;
@@ -190,21 +198,19 @@ private:
private:
HTMLLinkElement(Document&, bool createdByParser);
- OwnPtr<LinkResource> m_link;
+ OwnPtrWillBeMember<LinkResource> m_link;
LinkLoader m_linkLoader;
String m_type;
String m_media;
- RefPtr<DOMSettableTokenList> m_sizes;
+ RefPtrWillBeMember<DOMSettableTokenList> m_sizes;
+ Vector<IntSize> m_iconSizes;
LinkRelAttribute m_relAttribute;
bool m_createdByParser;
bool m_isInShadowTree;
- int m_beforeLoadRecurseCount;
};
-DEFINE_NODE_TYPE_CASTS(HTMLLinkElement, hasTagName(HTMLNames::linkTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
index 73c2426ce04..3ba1aff4c50 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
@@ -22,7 +22,8 @@
interface HTMLLinkElement : HTMLElement {
[Reflect] attribute boolean disabled;
[Reflect] attribute DOMString charset;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString href;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString href;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
[Reflect] attribute DOMString hreflang;
[Reflect] attribute DOMString media;
[Reflect] attribute DOMString rel;
@@ -35,4 +36,6 @@ interface HTMLLinkElement : HTMLElement {
readonly attribute StyleSheet sheet;
[RuntimeEnabled=HTMLImports] readonly attribute Document import;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp
new file mode 100644
index 00000000000..62cce281a90
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp
@@ -0,0 +1,77 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLLinkElement.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class HTMLLinkElementSizesAttributeTest : public testing::Test {
+};
+
+TEST(HTMLLinkElementSizesAttributeTest, parseSizes)
+{
+ AtomicString sizesAttribute = "32x33";
+ Vector<IntSize> sizes;
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(1U, sizes.size());
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+
+ UChar attribute[] = {'3', '2', 'x', '3', '3', 0};
+ sizesAttribute = attribute;
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(1U, sizes.size());
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+
+
+ sizesAttribute = " 32x33 16X17 128x129 ";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(3U, sizes.size());
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+ EXPECT_EQ(16, sizes[1].width());
+ EXPECT_EQ(17, sizes[1].height());
+ EXPECT_EQ(128, sizes[2].width());
+ EXPECT_EQ(129, sizes[2].height());
+
+ sizesAttribute = "any";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 32";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 32x";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 x32";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 any";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33, 64x64";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp
index d1f055a2fc6..27a525c1b33 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/html/HTMLMapElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLAreaElement.h"
@@ -30,22 +30,17 @@
#include "core/html/HTMLImageElement.h"
#include "core/rendering/HitTestResult.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
-HTMLMapElement::HTMLMapElement(Document& document)
+inline HTMLMapElement::HTMLMapElement(Document& document)
: HTMLElement(mapTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMapElement> HTMLMapElement::create(Document& document)
-{
- return adoptRef(new HTMLMapElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLMapElement)
HTMLMapElement::~HTMLMapElement()
{
@@ -54,15 +49,12 @@ HTMLMapElement::~HTMLMapElement()
bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size, HitTestResult& result)
{
HTMLAreaElement* defaultArea = 0;
- Element* element = this;
- while ((element = ElementTraversal::next(*element, this))) {
- if (isHTMLAreaElement(element)) {
- HTMLAreaElement* areaElt = toHTMLAreaElement(element);
- if (areaElt->isDefault()) {
- if (!defaultArea)
- defaultArea = areaElt;
- } else if (areaElt->mapMouseEvent(location, size, result))
- return true;
+ for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*this); area; area = Traversal<HTMLAreaElement>::next(*area, this)) {
+ if (area->isDefault()) {
+ if (!defaultArea)
+ defaultArea = area;
+ } else if (area->mapMouseEvent(location, size, result)) {
+ return true;
}
}
@@ -75,17 +67,16 @@ bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size,
HTMLImageElement* HTMLMapElement::imageElement()
{
- RefPtr<HTMLCollection> images = document().images();
- for (unsigned i = 0; Node* curr = images->item(i); i++) {
- if (!curr->hasTagName(imgTag))
- continue;
+ RefPtrWillBeRawPtr<HTMLCollection> images = document().images();
+ for (unsigned i = 0; Element* curr = images->item(i); ++i) {
+ ASSERT(isHTMLImageElement(curr));
// The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
// which has to be stripped off.
- HTMLImageElement* imageElement = toHTMLImageElement(curr);
- String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1);
+ HTMLImageElement& imageElement = toHTMLImageElement(*curr);
+ String useMapName = imageElement.getAttribute(usemapAttr).string().substring(1);
if (equalIgnoringCase(useMapName, m_name))
- return imageElement;
+ return &imageElement;
}
return 0;
@@ -108,7 +99,7 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
String mapName = value;
if (mapName[0] == '#')
mapName = mapName.substring(1);
- m_name = document().isHTMLDocument() ? mapName.lower() : mapName;
+ m_name = AtomicString(document().isHTMLDocument() ? mapName.lower() : mapName);
if (inDocument())
treeScope().addImageMap(this);
@@ -118,7 +109,7 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
HTMLElement::parseAttribute(name, value);
}
-PassRefPtr<HTMLCollection> HTMLMapElement::areas()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLMapElement::areas()
{
return ensureCachedHTMLCollection(MapAreas);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h
index cdd5c7654a8..36ca426bc0b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h
@@ -32,7 +32,7 @@ class HTMLImageElement;
class HTMLMapElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLMapElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLMapElement);
virtual ~HTMLMapElement();
const AtomicString& getName() const { return m_name; }
@@ -40,7 +40,7 @@ public:
bool mapMouseEvent(LayoutPoint location, const LayoutSize&, HitTestResult&);
HTMLImageElement* imageElement();
- PassRefPtr<HTMLCollection> areas();
+ PassRefPtrWillBeRawPtr<HTMLCollection> areas();
private:
explicit HTMLMapElement(Document&);
@@ -53,8 +53,6 @@ private:
AtomicString m_name;
};
-DEFINE_NODE_TYPE_CASTS(HTMLMapElement, hasTagName(HTMLNames::mapTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
index 882cb06c454..491755fbf41 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
@@ -23,10 +23,10 @@
#include "config.h"
#include "core/html/HTMLMarqueeElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/rendering/RenderMarquee.h"
@@ -41,9 +41,9 @@ inline HTMLMarqueeElement::HTMLMarqueeElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(Document& document)
{
- RefPtr<HTMLMarqueeElement> marqueeElement(adoptRef(new HTMLMarqueeElement(document)));
+ RefPtrWillBeRawPtr<HTMLMarqueeElement> marqueeElement(adoptRefWillBeNoop(new HTMLMarqueeElement(document)));
marqueeElement->suspendIfNeeded();
return marqueeElement.release();
}
@@ -57,6 +57,12 @@ int HTMLMarqueeElement::minimumDelay() const
return 0;
}
+void HTMLMarqueeElement::didMoveToNewDocument(Document& oldDocument)
+{
+ ActiveDOMObject::didMoveToNewExecutionContext(&document());
+ HTMLElement::didMoveToNewDocument(oldDocument);
+}
+
bool HTMLMarqueeElement::isPresentationAttribute(const QualifiedName& name) const
{
if (name == widthAttr || name == heightAttr || name == bgcolorAttr || name == vspaceAttr || name == hspaceAttr || name == scrollamountAttr || name == scrolldelayAttr || name == loopAttr || name == behaviorAttr || name == directionAttr)
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h
index 90add468471..129ed22392d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h
@@ -25,6 +25,7 @@
#include "core/dom/ActiveDOMObject.h"
#include "core/html/HTMLElement.h"
+#include "platform/Timer.h"
namespace WebCore {
@@ -33,14 +34,14 @@ class RenderMarquee;
class HTMLMarqueeElement FINAL : public HTMLElement, private ActiveDOMObject {
public:
- static PassRefPtr<HTMLMarqueeElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLMarqueeElement> create(Document&);
int minimumDelay() const;
// DOM Functions
void start();
- void stop();
+ virtual void stop() OVERRIDE;
int scrollAmount() const;
void setScrollAmount(int, ExceptionState&);
@@ -56,20 +57,20 @@ public:
private:
explicit HTMLMarqueeElement(Document&);
+ virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
+
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
// ActiveDOMObject
- virtual void suspend();
- virtual void resume();
+ virtual void suspend() OVERRIDE;
+ virtual void resume() OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE FINAL;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
RenderMarquee* renderMarquee() const;
};
-DEFINE_NODE_TYPE_CASTS(HTMLMarqueeElement, hasTagName(HTMLNames::marqueeTag));
-
} // namespace WebCore
#endif // HTMLMarqueeElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index c43d49009f1..ed492e58133 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -27,55 +27,52 @@
#include "core/html/HTMLMediaElement.h"
#include <limits>
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
-#include "core/css/MediaQueryEvaluator.h"
#include "core/dom/Attribute.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLMediaSource.h"
#include "core/html/HTMLSourceElement.h"
#include "core/html/HTMLTrackElement.h"
#include "core/html/MediaController.h"
#include "core/html/MediaError.h"
#include "core/html/MediaFragmentURIParser.h"
-#include "core/html/MediaKeyError.h"
-#include "core/html/MediaKeyEvent.h"
#include "core/html/TimeRanges.h"
#include "core/html/shadow/MediaControls.h"
+#include "core/html/track/AudioTrack.h"
+#include "core/html/track/AudioTrackList.h"
#include "core/html/track/InbandTextTrack.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/TextTrackList.h"
+#include "core/html/track/VideoTrack.h"
+#include "core/html/track/VideoTrackList.h"
#include "core/loader/FrameLoader.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderVideo.h"
#include "core/rendering/RenderView.h"
-// FIXME: Remove dependency on modules/encryptedmedia (http://crbug.com/242754).
-#include "modules/encryptedmedia/MediaKeyNeededEvent.h"
-#include "modules/encryptedmedia/MediaKeys.h"
-#include "modules/mediastream/MediaStreamRegistry.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/ContentType.h"
#include "platform/Language.h"
#include "platform/Logging.h"
#include "platform/MIMETypeFromURL.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/NotImplemented.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebContentDecryptionModule.h"
#include "public/platform/WebInbandTextTrack.h"
#include "wtf/CurrentTime.h"
#include "wtf/MathExtras.h"
@@ -85,12 +82,13 @@
#if ENABLE(WEB_AUDIO)
#include "platform/audio/AudioSourceProvider.h"
-#include "modules/webaudio/MediaElementAudioSourceNode.h"
+#include "platform/audio/AudioSourceProviderClient.h"
#endif
-using namespace std;
using blink::WebInbandTextTrack;
+using blink::WebMediaPlayer;
using blink::WebMimeRegistry;
+using blink::WebMediaPlayerClient;
namespace WebCore {
@@ -126,19 +124,19 @@ static const char* boolString(bool val)
static const char mediaSourceBlobProtocol[] = "blob";
using namespace HTMLNames;
-using namespace std;
-typedef HashMap<Document*, HashSet<HTMLMediaElement*> > DocumentElementSetMap;
+typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<HTMLMediaElement> > WeakMediaElementSet;
+typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Document>, WeakMediaElementSet> DocumentElementSetMap;
static DocumentElementSetMap& documentToElementSetMap()
{
- DEFINE_STATIC_LOCAL(DocumentElementSetMap, map, ());
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<DocumentElementSetMap>, map, (adoptPtrWillBeNoop(new DocumentElementSetMap())));
+ return *map;
}
static void addElementToDocumentMap(HTMLMediaElement* element, Document* document)
{
DocumentElementSetMap& map = documentToElementSetMap();
- HashSet<HTMLMediaElement*> set = map.take(document);
+ WeakMediaElementSet set = map.take(document);
set.add(element);
map.add(document, set);
}
@@ -146,33 +144,14 @@ static void addElementToDocumentMap(HTMLMediaElement* element, Document* documen
static void removeElementFromDocumentMap(HTMLMediaElement* element, Document* document)
{
DocumentElementSetMap& map = documentToElementSetMap();
- HashSet<HTMLMediaElement*> set = map.take(document);
+ WeakMediaElementSet set = map.take(document);
set.remove(element);
if (!set.isEmpty())
map.add(document, set);
}
-static void throwExceptionForMediaKeyException(MediaPlayer::MediaKeyException exception, ExceptionState& exceptionState)
-{
- switch (exception) {
- case MediaPlayer::NoError:
- return;
- case MediaPlayer::InvalidPlayerState:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- case MediaPlayer::KeySystemNotSupported:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- case MediaPlayer::InvalidAccess:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return;
- }
-
- ASSERT_NOT_REACHED();
- return;
-}
-
class TrackDisplayUpdateScope {
+ STACK_ALLOCATED();
public:
TrackDisplayUpdateScope(HTMLMediaElement* mediaElement)
{
@@ -186,9 +165,55 @@ public:
}
private:
- HTMLMediaElement* m_mediaElement;
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
};
+static const AtomicString& AudioKindToString(WebMediaPlayerClient::AudioTrackKind kind)
+{
+ switch (kind) {
+ case WebMediaPlayerClient::AudioTrackKindNone:
+ return emptyAtom;
+ case WebMediaPlayerClient::AudioTrackKindAlternative:
+ return AudioTrack::alternativeKeyword();
+ case WebMediaPlayerClient::AudioTrackKindDescriptions:
+ return AudioTrack::descriptionsKeyword();
+ case WebMediaPlayerClient::AudioTrackKindMain:
+ return AudioTrack::mainKeyword();
+ case WebMediaPlayerClient::AudioTrackKindMainDescriptions:
+ return AudioTrack::mainDescriptionsKeyword();
+ case WebMediaPlayerClient::AudioTrackKindTranslation:
+ return AudioTrack::translationKeyword();
+ case WebMediaPlayerClient::AudioTrackKindCommentary:
+ return AudioTrack::commentaryKeyword();
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
+static const AtomicString& VideoKindToString(WebMediaPlayerClient::VideoTrackKind kind)
+{
+ switch (kind) {
+ case WebMediaPlayerClient::VideoTrackKindNone:
+ return emptyAtom;
+ case WebMediaPlayerClient::VideoTrackKindAlternative:
+ return VideoTrack::alternativeKeyword();
+ case WebMediaPlayerClient::VideoTrackKindCaptions:
+ return VideoTrack::captionsKeyword();
+ case WebMediaPlayerClient::VideoTrackKindMain:
+ return VideoTrack::mainKeyword();
+ case WebMediaPlayerClient::VideoTrackKindSign:
+ return VideoTrack::signKeyword();
+ case WebMediaPlayerClient::VideoTrackKindSubtitles:
+ return VideoTrack::subtitlesKeyword();
+ case WebMediaPlayerClient::VideoTrackKindCommentary:
+ return VideoTrack::commentaryKeyword();
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
static bool canLoadURL(const KURL& url, const ContentType& contentType, const String& keySystem)
{
DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
@@ -241,12 +266,26 @@ WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType&
return blink::Platform::current()->mimeRegistry()->supportsMediaMIMEType(type, typeCodecs, system);
}
-HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
+URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0;
+
+void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry)
+{
+ ASSERT(!s_mediaStreamRegistry);
+ s_mediaStreamRegistry = registry;
+}
+
+bool HTMLMediaElement::isMediaStreamURL(const String& url)
+{
+ return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false;
+}
+
+HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
, ActiveDOMObject(&document)
, m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
+ , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired)
, m_playedTimeRanges()
, m_asyncEventQueue(GenericEventQueue::create(this))
, m_playbackRate(1.0f)
@@ -256,14 +295,14 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_readyStateMaximum(HAVE_NOTHING)
, m_volume(1.0f)
, m_lastSeekTime(0)
- , m_previousProgressTime(numeric_limits<double>::max())
- , m_duration(numeric_limits<double>::quiet_NaN())
+ , m_previousProgressTime(std::numeric_limits<double>::max())
+ , m_duration(std::numeric_limits<double>::quiet_NaN())
, m_lastTimeUpdateEventWallTime(0)
- , m_lastTimeUpdateEventMovieTime(numeric_limits<double>::max())
+ , m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max())
, m_loadState(WaitingForSource)
+ , m_deferredLoadState(NotDeferred)
+ , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired)
, m_webLayer(0)
- , m_opaque(false)
- , m_restrictions(RequirePageConsentToLoadMediaRestriction)
, m_preload(MediaPlayer::Auto)
, m_displayMode(Unknown)
, m_cachedTime(MediaPlayer::invalidTime())
@@ -272,6 +311,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_fragmentStartTime(MediaPlayer::invalidTime())
, m_fragmentEndTime(MediaPlayer::invalidTime())
, m_pendingActionFlags(0)
+ , m_userGestureRequiredForPlay(false)
, m_playing(false)
, m_shouldDelayLoadEvent(false)
, m_haveFiredLoadedData(false)
@@ -284,18 +324,21 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_sentEndEvent(false)
, m_pausedInternal(false)
, m_closedCaptionsVisible(false)
- , m_loadInitiatedByUserGesture(false)
, m_completelyLoaded(false)
, m_havePreparedToPlay(false)
- , m_parsingInProgress(createdByParser)
, m_tracksAreReady(true)
, m_haveVisibleTextTrack(false)
, m_processingPreferenceChange(false)
+#if ENABLE(OILPAN)
+ , m_isFinalizing(false)
+#endif
, m_lastTextTrackUpdateTime(-1)
- , m_textTracks(0)
+ , m_audioTracks(AudioTrackList::create(*this))
+ , m_videoTracks(VideoTrackList::create(*this))
+ , m_textTracks(nullptr)
, m_ignoreTrackDisplayUpdate(0)
#if ENABLE(WEB_AUDIO)
- , m_audioSourceNode(0)
+ , m_audioSourceNode(nullptr)
#endif
{
ASSERT(RuntimeEnabledFeatures::mediaEnabled());
@@ -303,45 +346,54 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement");
ScriptWrappable::init(this);
- if (document.settings()) {
- if (document.settings()->mediaPlaybackRequiresUserGesture()) {
- addBehaviorRestriction(RequireUserGestureForRateChangeRestriction);
- addBehaviorRestriction(RequireUserGestureForLoadRestriction);
- }
- if (document.settings()->mediaFullscreenRequiresUserGesture()) {
- addBehaviorRestriction(RequireUserGestureForFullscreenRestriction);
- }
- }
+ if (document.settings() && document.settings()->mediaPlaybackRequiresUserGesture())
+ m_userGestureRequiredForPlay = true;
setHasCustomStyleCallbacks();
addElementToDocumentMap(this, &document);
-
}
HTMLMediaElement::~HTMLMediaElement()
{
WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement");
+#if ENABLE(OILPAN)
+ // If the HTMLMediaElement dies with the document we are not
+ // allowed to touch the document to adjust delay load event counts
+ // because the document could have been already
+ // destructed. However, if the HTMLMediaElement dies with the
+ // document there is no need to change the delayed load counts
+ // because no load event will fire anyway. If the document is
+ // still alive we do have to decrement the load delay counts. We
+ // determine if the document is alive via the ActiveDOMObject
+ // which is a context lifecycle observer. If the Document has been
+ // destructed ActiveDOMObject::executionContext() returns 0.
+ if (ActiveDOMObject::executionContext())
+ setShouldDelayLoadEvent(false);
+#else
+ // HTMLMediaElement and m_asyncEventQueue always become unreachable
+ // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in
+ // the same GC. We don't need to close it explicitly in Oilpan.
m_asyncEventQueue->close();
setShouldDelayLoadEvent(false);
+
if (m_textTracks)
m_textTracks->clearOwner();
- if (m_textTracks) {
- for (unsigned i = 0; i < m_textTracks->length(); ++i)
- m_textTracks->item(i)->clearClient();
- }
+ m_audioTracks->shutdown();
+ m_videoTracks->shutdown();
if (m_mediaController) {
m_mediaController->removeMediaElement(this);
- m_mediaController = 0;
+ m_mediaController = nullptr;
}
+#endif
closeMediaSource();
- setMediaKeys(0);
-
+#if !ENABLE(OILPAN)
removeElementFromDocumentMap(this, &document());
+#endif
// Destroying the player may cause a resource load to be canceled,
// which could result in userCancelledLoad() being called back.
@@ -350,6 +402,10 @@ HTMLMediaElement::~HTMLMediaElement()
// See http://crbug.com/233654 for more details.
m_completelyLoaded = true;
+ // With Oilpan load events on the Document are always delayed during
+ // sweeping so we don't need to explicitly increment and decrement
+ // load event delay counts.
+#if !ENABLE(OILPAN)
// Destroying the player may cause a resource load to be canceled,
// which could result in Document::dispatchWindowLoadEvent() being
// called via ResourceFetch::didLoadResource() then
@@ -357,10 +413,33 @@ HTMLMediaElement::~HTMLMediaElement()
// object destruction, we use Document::incrementLoadEventDelayCount().
// See http://crbug.com/275223 for more details.
document().incrementLoadEventDelayCount();
+#endif
+
+#if ENABLE(OILPAN)
+ // Oilpan: the player must be released, but the player object
+ // cannot safely access this player client any longer as parts of
+ // it may have been finalized already (like the media element's
+ // supplementable table.) Handled for now by entering an
+ // is-finalizing state, which is explicitly checked for if the
+ // player tries to access the media element during shutdown.
+ //
+ // FIXME: Oilpan: move the media player to the heap instead and
+ // avoid having to finalize it from here; this whole #if block
+ // could then be removed (along with the state bit it depends on.)
+ // crbug.com/378229
+ m_isFinalizing = true;
+#endif
- clearMediaPlayerAndAudioSourceProviderClient();
+ // The m_audioSourceNode is either dead already or it is dying together with
+ // this HTMLMediaElement which it strongly keeps alive.
+#if ENABLE(WEB_AUDIO) && !ENABLE(OILPAN)
+ ASSERT(!m_audioSourceNode);
+#endif
+ clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
+#if !ENABLE(OILPAN)
document().decrementLoadEventDelayCount();
+#endif
}
void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
@@ -382,9 +461,9 @@ void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
addElementToDocumentMap(this, &document());
// FIXME: This is a temporary fix to prevent this object from causing the
- // MediaPlayer to dereference Frame and FrameLoader pointers from the
+ // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the
// previous document. A proper fix would provide a mechanism to allow this
- // object to refresh the MediaPlayer's Frame and FrameLoader references on
+ // object to refresh the MediaPlayer's LocalFrame and FrameLoader references on
// document changes so that playback can be resumed properly.
userCancelledLoad();
@@ -392,14 +471,10 @@ void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
// and there is no risk of dispatching a load event from within the destructor.
oldDocument.decrementLoadEventDelayCount();
+ ActiveDOMObject::didMoveToNewExecutionContext(&document());
HTMLElement::didMoveToNewDocument(oldDocument);
}
-bool HTMLMediaElement::hasCustomFocusLogic() const
-{
- return true;
-}
-
bool HTMLMediaElement::supportsFocus() const
{
if (ownerDocument()->isMediaDocument())
@@ -422,9 +497,9 @@ void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
clearMediaPlayer(LoadMediaResource);
scheduleDelayedAction(LoadMediaResource);
}
- } else if (name == controlsAttr)
+ } else if (name == controlsAttr) {
configureMediaControls();
- else if (name == preloadAttr) {
+ } else if (name == preloadAttr) {
if (equalIgnoringCase(value, "none"))
m_preload = MediaPlayer::None;
else if (equalIgnoringCase(value, "metadata"))
@@ -437,30 +512,21 @@ void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
// The attribute must be ignored if the autoplay attribute is present
if (!autoplay() && m_player)
- m_player->setPreload(m_preload);
+ setPlayerPreload();
- } else if (name == mediagroupAttr)
+ } else if (name == mediagroupAttr && RuntimeEnabledFeatures::mediaControllerEnabled()) {
setMediaGroup(value);
- else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else
+ } else {
HTMLElement::parseAttribute(name, value);
+ }
}
void HTMLMediaElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
- m_parsingInProgress = false;
-
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(trackTag)) {
- scheduleDelayedAction(LoadTextTrackResource);
- break;
- }
- }
+ if (Traversal<HTMLTrackElement>::firstChild(*this))
+ scheduleDelayedAction(LoadTextTrackResource);
}
bool HTMLMediaElement::rendererIsNeeded(const RenderStyle& style)
@@ -473,11 +539,6 @@ RenderObject* HTMLMediaElement::createRenderer(RenderStyle*)
return new RenderMedia(this);
}
-bool HTMLMediaElement::childShouldCreateRenderer(const Node& child) const
-{
- return hasMediaControls() && HTMLElement::childShouldCreateRenderer(child);
-}
-
Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint)
{
WTF_LOG(Media, "HTMLMediaElement::insertedInto");
@@ -490,8 +551,12 @@ Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode*
scheduleDelayedAction(LoadMediaResource);
}
+ return InsertionShouldCallDidNotifySubtreeInsertions;
+}
+
+void HTMLMediaElement::didNotifySubtreeInsertionsToDocument()
+{
configureMediaControls();
- return InsertionDone;
}
void HTMLMediaElement::removedFrom(ContainerNode* insertionPoint)
@@ -499,7 +564,7 @@ void HTMLMediaElement::removedFrom(ContainerNode* insertionPoint)
WTF_LOG(Media, "HTMLMediaElement::removedFrom");
m_active = false;
- if (insertionPoint->inDocument()) {
+ if (insertionPoint->inDocument() && insertionPoint->document().isActive()) {
configureMediaControls();
if (m_networkState > NETWORK_EMPTY)
pause();
@@ -531,33 +596,36 @@ void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType)
m_pendingActionFlags |= LoadMediaResource;
}
- if (RuntimeEnabledFeatures::videoTrackEnabled() && (actionType & LoadTextTrackResource))
+ if (actionType & LoadTextTrackResource)
m_pendingActionFlags |= LoadTextTrackResource;
if (!m_loadTimer.isActive())
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void HTMLMediaElement::scheduleNextSourceChild()
{
// Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
m_pendingActionFlags |= LoadMediaResource;
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
{
+ scheduleEvent(Event::createCancelable(eventName));
+}
+
+void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event)
+{
#if LOG_MEDIA_EVENTS
- WTF_LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
+ WTF_LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", event->type().ascii().data());
#endif
- m_asyncEventQueue->enqueueEvent(Event::createCancelable(eventName));
+ m_asyncEventQueue->enqueueEvent(event);
}
void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
{
- RefPtr<HTMLMediaElement> protect(this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
-
- if (RuntimeEnabledFeatures::videoTrackEnabled() && (m_pendingActionFlags & LoadTextTrackResource))
+ if (m_pendingActionFlags & LoadTextTrackResource)
configureTextTracks();
if (m_pendingActionFlags & LoadMediaResource) {
@@ -570,7 +638,7 @@ void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
m_pendingActionFlags = 0;
}
-PassRefPtr<MediaError> HTMLMediaElement::error() const
+PassRefPtrWillBeRawPtr<MediaError> HTMLMediaElement::error() const
{
return m_error;
}
@@ -585,8 +653,11 @@ HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
return m_networkState;
}
-String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySystem, const KURL& url) const
+String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySystem) const
{
+ if (!keySystem.isNull())
+ UseCounter::count(document(), UseCounter::CanPlayTypeKeySystem);
+
WebMimeRegistry::SupportsType support = supportsType(ContentType(mimeType), keySystem);
String canPlay;
@@ -604,26 +675,18 @@ String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySy
break;
}
- WTF_LOG(Media, "HTMLMediaElement::canPlayType(%s, %s, %s) -> %s", mimeType.utf8().data(), keySystem.utf8().data(), url.elidedString().utf8().data(), canPlay.utf8().data());
+ WTF_LOG(Media, "HTMLMediaElement::canPlayType(%s, %s) -> %s", mimeType.utf8().data(), keySystem.utf8().data(), canPlay.utf8().data());
return canPlay;
}
void HTMLMediaElement::load()
{
- RefPtr<HTMLMediaElement> protect(this); // loadInternal may result in a 'beforeload' event, which can make arbitrary DOM mutations.
-
WTF_LOG(Media, "HTMLMediaElement::load()");
- if (document().settings() && !document().settings()->mediaEnabled())
- return;
-
- if (userGestureRequiredForLoad() && !UserGestureIndicator::processingUserGesture())
- return;
+ if (UserGestureIndicator::processingUserGesture())
+ m_userGestureRequiredForPlay = false;
- m_loadInitiatedByUserGesture = UserGestureIndicator::processingUserGesture();
- if (m_loadInitiatedByUserGesture)
- removeBehaviorsRestrictionsAfterFirstUserGesture();
prepareForLoad();
loadInternal();
prepareToPlay();
@@ -636,6 +699,9 @@ void HTMLMediaElement::prepareForLoad()
// Perform the cleanup required for the resource load algorithm to run.
stopPeriodicTimers();
m_loadTimer.stop();
+ cancelDeferredLoad();
+ // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here.
+ m_pendingActionFlags &= ~LoadMediaResource;
m_sentEndEvent = false;
m_sentStalledEvent = false;
m_haveFiredLoadedData = false;
@@ -645,7 +711,7 @@ void HTMLMediaElement::prepareForLoad()
// 1 - Abort any already-running instance of the resource selection algorithm for this element.
m_loadState = WaitingForSource;
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
// 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.
@@ -656,30 +722,53 @@ void HTMLMediaElement::prepareForLoad()
if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE)
scheduleEvent(EventTypeNames::abort);
- closeMediaSource();
-
createMediaPlayer();
// 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
if (m_networkState != NETWORK_EMPTY) {
+ // 4.1 - Queue a task to fire a simple event named emptied at the media element.
+ scheduleEvent(EventTypeNames::emptied);
+
+ // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
m_networkState = NETWORK_EMPTY;
+
+ // 4.3 - Forget the media element's media-resource-specific tracks.
+ forgetResourceSpecificTracks();
+
+ // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that state.
m_readyState = HAVE_NOTHING;
m_readyStateMaximum = HAVE_NOTHING;
- refreshCachedTime();
+
+ // 4.5 - If the paused attribute is false, then set it to true.
m_paused = true;
+
+ // 4.6 - If seeking is true, set it to false.
m_seeking = false;
+
+ // 4.7 - Set the current playback position to 0.
+ // Set the official playback position to 0.
+ // If this changed the official playback position, then queue a task to fire a simple event named timeupdate at the media element.
+ // FIXME: Add support for firing this event.
+
+ // 4.8 - Set the initial playback position to 0.
+ // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call
+ // above.
+ refreshCachedTime();
invalidateCachedTime();
- scheduleEvent(EventTypeNames::emptied);
+
+ // 4.9 - Set the timeline offset to Not-a-Number (NaN).
+ // 4.10 - Update the duration attribute to Not-a-Number (NaN).
+
+
updateMediaController();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(0);
+ updateActiveTextTrackCues(0);
}
// 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_error = nullptr;
m_autoplaying = true;
// 7 - Invoke the media element's resource selection algorithm.
@@ -693,8 +782,11 @@ void HTMLMediaElement::prepareForLoad()
// 2 - Asynchronously await a stable state.
m_playedTimeRanges = TimeRanges::create();
+
+ // FIXME: Investigate whether these can be moved into m_networkState != NETWORK_EMPTY block above
+ // so they are closer to the relevant spec steps.
m_lastSeekTime = 0;
- m_duration = numeric_limits<double>::quiet_NaN();
+ m_duration = std::numeric_limits<double>::quiet_NaN();
// 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
@@ -706,26 +798,14 @@ void HTMLMediaElement::prepareForLoad()
void HTMLMediaElement::loadInternal()
{
- // Some of the code paths below this function dispatch the BeforeLoad event. This ASSERT helps
- // us catch those bugs more quickly without needing all the branches to align to actually
- // trigger the event.
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- // Once the page has allowed an element to load media, it is free to load at will. This allows a
- // playlist that starts in a foreground tab to continue automatically if the tab is subsequently
- // put in the the background.
- removeBehaviorRestriction(RequirePageConsentToLoadMediaRestriction);
-
// HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the
// disabled state when the element's resource selection algorithm last started".
- if (RuntimeEnabledFeatures::videoTrackEnabled()) {
- m_textTracksWhenResourceSelectionBegan.clear();
- if (m_textTracks) {
- for (unsigned i = 0; i < m_textTracks->length(); ++i) {
- TextTrack* track = m_textTracks->item(i);
- if (track->mode() != TextTrack::disabledKeyword())
- m_textTracksWhenResourceSelectionBegan.append(track);
- }
+ m_textTracksWhenResourceSelectionBegan.clear();
+ if (m_textTracks) {
+ for (unsigned i = 0; i < m_textTracks->length(); ++i) {
+ TextTrack* track = m_textTracks->item(i);
+ if (track->mode() != TextTrack::disabledKeyword())
+ m_textTracksWhenResourceSelectionBegan.append(track);
}
}
@@ -741,19 +821,13 @@ void HTMLMediaElement::selectMediaResource()
// 3 - If the media element has a src attribute, then let mode be attribute.
Mode mode = attribute;
if (!fastHasAttribute(srcAttr)) {
- Node* node;
- for (node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(sourceTag))
- break;
- }
-
// Otherwise, if the media element does not have a src attribute but has a source
// element child, then let mode be children and let candidate be the first such
// source element child in tree order.
- if (node) {
+ if (HTMLSourceElement* element = Traversal<HTMLSourceElement>::firstChild(*this)) {
mode = children;
- m_nextChildNodeToConsider = node;
- m_currentSourceNode = 0;
+ m_nextChildNodeToConsider = element;
+ m_currentSourceNode = nullptr;
} else {
// Otherwise the media element has neither a src attribute nor a source element
// child: set the networkState to NETWORK_EMPTY, and abort these steps; the
@@ -787,7 +861,7 @@ void HTMLMediaElement::selectMediaResource()
return;
}
- if (!isSafeToLoadURL(mediaURL, Complain) || !dispatchBeforeLoadEvent(mediaURL.string())) {
+ if (!isSafeToLoadURL(mediaURL, Complain)) {
mediaLoadingFailed(MediaPlayer::FormatError);
return;
}
@@ -828,7 +902,7 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
WTF_LOG(Media, "HTMLMediaElement::loadResource(%s, %s, %s)", urlForLoggingMedia(url).utf8().data(), contentType.raw().utf8().data(), keySystem.utf8().data());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame) {
mediaLoadingFailed(MediaPlayer::FormatError);
return;
@@ -843,16 +917,13 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
WTF_LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLoggingMedia(m_currentSrc).utf8().data());
- if (MediaStreamRegistry::registry().lookupMediaStreamDescriptor(url.string()))
- removeBehaviorRestriction(RequireUserGestureForRateChangeRestriction);
-
startProgressEventTimer();
// Reset display mode to force a recalculation of what to show because we are resetting the player.
setDisplayMode(Unknown);
if (!autoplay())
- m_player->setPreload(m_preload);
+ setPlayerPreload();
if (fastHasAttribute(mutedAttr))
m_muted = true;
@@ -860,20 +931,34 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
ASSERT(!m_mediaSource);
- if (url.protocolIs(mediaSourceBlobProtocol))
- m_mediaSource = HTMLMediaSource::lookup(url.string());
+ bool attemptLoad = true;
- if (m_mediaSource) {
- if (m_mediaSource->attachToElement(this)) {
- m_player->load(url, m_mediaSource);
+ if (url.protocolIs(mediaSourceBlobProtocol)) {
+ if (isMediaStreamURL(url.string())) {
+ m_userGestureRequiredForPlay = false;
} else {
- // Forget our reference to the MediaSource, so we leave it alone
- // while processing remainder of load failure.
- m_mediaSource = 0;
- mediaLoadingFailed(MediaPlayer::FormatError);
+ m_mediaSource = HTMLMediaSource::lookup(url.string());
+
+ if (m_mediaSource) {
+ if (!m_mediaSource->attachToElement(this)) {
+ // Forget our reference to the MediaSource, so we leave it alone
+ // while processing remainder of load failure.
+ m_mediaSource = nullptr;
+ attemptLoad = false;
+ }
+ }
+ }
+ }
+
+ if (attemptLoad && canLoadURL(url, contentType, keySystem)) {
+ ASSERT(!webMediaPlayer());
+
+ if (!m_havePreparedToPlay && !autoplay() && m_preload == MediaPlayer::None) {
+ WTF_LOG(Media, "HTMLMediaElement::loadResource : Delaying load because preload == 'none'");
+ deferLoad();
+ } else {
+ startPlayerLoad();
}
- } else if (canLoadURL(url, contentType, keySystem)) {
- m_player->load(url);
} else {
mediaLoadingFailed(MediaPlayer::FormatError);
}
@@ -886,6 +971,118 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
renderer()->updateFromElement();
}
+void HTMLMediaElement::startPlayerLoad()
+{
+ // Filter out user:pass as those two URL components aren't
+ // considered for media resource fetches (including for the CORS
+ // use-credentials mode.) That behavior aligns with Gecko, with IE
+ // being more restrictive and not allowing fetches to such URLs.
+ //
+ // Spec reference: http://whatwg.org/c/#concept-media-load-resource
+ //
+ // FIXME: when the HTML spec switches to specifying resource
+ // fetches in terms of Fetch (http://fetch.spec.whatwg.org), and
+ // along with that potentially also specifying a setting for its
+ // 'authentication flag' to control how user:pass embedded in a
+ // media resource URL should be treated, then update the handling
+ // here to match.
+ KURL requestURL = m_currentSrc;
+ if (!requestURL.user().isEmpty())
+ requestURL.setUser(String());
+ if (!requestURL.pass().isEmpty())
+ requestURL.setPass(String());
+
+ m_player->load(loadType(), requestURL, corsMode());
+}
+
+void HTMLMediaElement::setPlayerPreload()
+{
+ m_player->setPreload(m_preload);
+
+ if (loadIsDeferred() && m_preload != MediaPlayer::None)
+ startDeferredLoad();
+}
+
+bool HTMLMediaElement::loadIsDeferred() const
+{
+ return m_deferredLoadState != NotDeferred;
+}
+
+void HTMLMediaElement::deferLoad()
+{
+ // This implements the "optional" step 3 from the resource fetch algorithm.
+ ASSERT(!m_deferredLoadTimer.isActive());
+ ASSERT(m_deferredLoadState == NotDeferred);
+ // 1. Set the networkState to NETWORK_IDLE.
+ // 2. Queue a task to fire a simple event named suspend at the element.
+ changeNetworkStateFromLoadingToIdle();
+ // 3. Queue a task to set the element's delaying-the-load-event
+ // flag to false. This stops delaying the load event.
+ m_deferredLoadTimer.startOneShot(0, FROM_HERE);
+ // 4. Wait for the task to be run.
+ m_deferredLoadState = WaitingForStopDelayingLoadEventTask;
+ // Continued in executeDeferredLoad().
+}
+
+void HTMLMediaElement::cancelDeferredLoad()
+{
+ m_deferredLoadTimer.stop();
+ m_deferredLoadState = NotDeferred;
+}
+
+void HTMLMediaElement::executeDeferredLoad()
+{
+ ASSERT(m_deferredLoadState >= WaitingForTrigger);
+
+ // resource fetch algorithm step 3 - continued from deferLoad().
+
+ // 5. Wait for an implementation-defined event (e.g. the user requesting that the media element begin playback).
+ // This is assumed to be whatever 'event' ended up calling this method.
+ cancelDeferredLoad();
+ // 6. 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);
+ // 7. Set the networkState to NETWORK_LOADING.
+ m_networkState = NETWORK_LOADING;
+
+ startProgressEventTimer();
+
+ startPlayerLoad();
+}
+
+void HTMLMediaElement::startDeferredLoad()
+{
+ if (m_deferredLoadState == WaitingForTrigger) {
+ executeDeferredLoad();
+ return;
+ }
+ ASSERT(m_deferredLoadState == WaitingForStopDelayingLoadEventTask);
+ m_deferredLoadState = ExecuteOnStopDelayingLoadEventTask;
+}
+
+void HTMLMediaElement::deferredLoadTimerFired(Timer<HTMLMediaElement>*)
+{
+ setShouldDelayLoadEvent(false);
+
+ if (m_deferredLoadState == ExecuteOnStopDelayingLoadEventTask) {
+ executeDeferredLoad();
+ return;
+ }
+ ASSERT(m_deferredLoadState == WaitingForStopDelayingLoadEventTask);
+ m_deferredLoadState = WaitingForTrigger;
+}
+
+WebMediaPlayer::LoadType HTMLMediaElement::loadType() const
+{
+ if (m_mediaSource)
+ return WebMediaPlayer::LoadTypeMediaSource;
+
+ if (isMediaStreamURL(m_currentSrc.string()))
+ return WebMediaPlayer::LoadTypeMediaStream;
+
+ return WebMediaPlayer::LoadTypeURL;
+}
+
static bool trackIndexCompare(TextTrack* a,
TextTrack* b)
{
@@ -923,8 +1120,6 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
if (ignoreTrackDisplayUpdateRequests())
return;
- WTF_LOG(Media, "HTMLMediaElement::updateActiveTextTrackCues");
-
// 1 - Let current cues be a list of cues, initialized to contain all the
// cues of all the hidden, showing, or showing by default text tracks of the
// media element (not the disabled ones) whose start times are less than or
@@ -965,7 +1160,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
double cueEndTime = potentiallySkippedCues[i].high();
// Consider cues that may have been missed since the last seek time.
- if (cueStartTime > max(m_lastSeekTime, lastTime) && cueEndTime < movieTime)
+ if (cueStartTime > std::max(m_lastSeekTime, lastTime) && cueEndTime < movieTime)
missedCues.append(potentiallySkippedCues[i]);
}
}
@@ -1079,7 +1274,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
affectedTracks.append(eventTasks[i].second->track());
// 13 - Queue each task in events, in list order.
- RefPtr<Event> event;
+ RefPtrWillBeRawPtr<Event> event = nullptr;
// Each event in eventTasks may be either an enterEvent or an exitEvent,
// depending on the time that is associated with the event. This
@@ -1111,7 +1306,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
// 15 - For each text track in affected tracks, in the list order, queue a
// task to fire a simple event named cuechange at the TextTrack object, and, ...
for (size_t i = 0; i < affectedTracks.size(); ++i) {
- RefPtr<Event> event = Event::create(EventTypeNames::cuechange);
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechange);
event->setTarget(affectedTracks[i]);
m_asyncEventQueue->enqueueEvent(event.release());
@@ -1119,7 +1314,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
// ... if the text track has a corresponding track element, to then fire a
// simple event named cuechange at the track element as well.
if (affectedTracks[i]->trackType() == TextTrack::TrackElement) {
- RefPtr<Event> event = Event::create(EventTypeNames::cuechange);
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechange);
HTMLTrackElement* trackElement = static_cast<LoadableTextTrack*>(affectedTracks[i])->trackElement();
ASSERT(trackElement);
event->setTarget(trackElement);
@@ -1163,9 +1358,9 @@ bool HTMLMediaElement::textTracksAreReady() const
void HTMLMediaElement::textTrackReadyStateChanged(TextTrack* track)
{
- if (m_player && m_textTracksWhenResourceSelectionBegan.contains(track)) {
+ if (webMediaPlayer()&& m_textTracksWhenResourceSelectionBegan.contains(track)) {
if (track->readinessState() != TextTrack::Loading)
- setReadyState(m_player->readyState());
+ setReadyState(static_cast<ReadyState>(webMediaPlayer()->readyState()));
} else {
// The track readiness state might have changed as a result of the user
// clicking the captions button. In this case, a check whether all the
@@ -1184,10 +1379,7 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
// or showing by default for the first time, the user agent must immediately and synchronously
// run the following algorithm ...
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (!node->hasTagName(trackTag))
- continue;
- HTMLTrackElement* trackElement = toHTMLTrackElement(node);
+ for (HTMLTrackElement* trackElement = Traversal<HTMLTrackElement>::firstChild(*this); trackElement; trackElement = Traversal<HTMLTrackElement>::nextSibling(*trackElement)) {
if (trackElement->track() != track)
continue;
@@ -1203,8 +1395,9 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
}
break;
}
- } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword())
+ } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword()) {
textTrackAddCues(track, track->cues());
+ }
configureTextTrackDisplay(AssumeVisibleChange);
@@ -1251,14 +1444,14 @@ void HTMLMediaElement::textTrackRemoveCues(TextTrack*, const TextTrackCueList* c
textTrackRemoveCue(cues->item(i)->track(), cues->item(i));
}
-void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
+void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtrWillBeRawPtr<TextTrackCue> cue)
{
if (track->mode() == TextTrack::disabledKeyword())
return;
// Negative duration cues need be treated in the interval tree as
// zero-length cues.
- double endTime = max(cue->startTime(), cue->endTime());
+ double endTime = std::max(cue->startTime(), cue->endTime());
CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
if (!m_cueTree.contains(interval))
@@ -1266,11 +1459,11 @@ void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue
updateActiveTextTrackCues(currentTime());
}
-void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue> cue)
+void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue> cue)
{
// Negative duration cues need to be treated in the interval tree as
// zero-length cues.
- double endTime = max(cue->startTime(), cue->endTime());
+ double endTime = std::max(cue->startTime(), cue->endTime());
CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
m_cueTree.remove(interval);
@@ -1299,7 +1492,7 @@ bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidURLAction actionI
return false;
}
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame || !document().securityOrigin()->canDisplay(url)) {
if (actionIfInvalid == Complain)
FrameLoader::reportLocalLoadFailed(frame, url.elidedString());
@@ -1322,7 +1515,7 @@ void HTMLMediaElement::startProgressEventTimer()
m_previousProgressTime = WTF::currentTime();
// 350ms is not magic, it is in the spec!
- m_progressEventTimer.startRepeating(0.350);
+ m_progressEventTimer.startRepeating(0.350, FROM_HERE);
}
void HTMLMediaElement::waitForSourceChange()
@@ -1350,7 +1543,7 @@ void HTMLMediaElement::noneSupported()
stopPeriodicTimers();
m_loadState = WaitingForSource;
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
// 4.8.10.5
// 6 - Reaching this step indicates that the media resource failed to load or that the given
@@ -1361,6 +1554,7 @@ void HTMLMediaElement::noneSupported()
m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
// 6.2 - Forget the media element's media-resource-specific text tracks.
+ forgetResourceSpecificTracks();
// 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
m_networkState = NETWORK_NO_SOURCE;
@@ -1382,7 +1576,7 @@ void HTMLMediaElement::noneSupported()
renderer()->updateFromElement();
}
-void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
+void HTMLMediaElement::mediaEngineError(PassRefPtrWillBeRawPtr<MediaError> err)
{
WTF_LOG(Media, "HTMLMediaElement::mediaEngineError(%d)", static_cast<int>(err->code()));
@@ -1408,7 +1602,7 @@ void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
setShouldDelayLoadEvent(false);
// 6 - Abort the overall resource selection algorithm.
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
}
void HTMLMediaElement::cancelPendingEventsAndCallbacks()
@@ -1416,10 +1610,8 @@ void HTMLMediaElement::cancelPendingEventsAndCallbacks()
WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
m_asyncEventQueue->cancelAllEvents();
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(sourceTag))
- toHTMLSourceElement(node)->cancelPendingErrorEvent();
- }
+ for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*this); source; source = Traversal<HTMLSourceElement>::nextSibling(*source))
+ source->cancelPendingErrorEvent();
}
void HTMLMediaElement::mediaPlayerNetworkStateChanged()
@@ -1435,11 +1627,18 @@ void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
// <source> children, schedule the next one
if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
+ // resource selection algorithm
+ // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM manipulation task source, to fire a simple event named error at the candidate element.
if (m_currentSourceNode)
m_currentSourceNode->scheduleErrorEvent();
else
WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
+ // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended.
+
+ // 9.Otherwise.11 - Forget the media element's media-resource-specific tracks.
+ forgetResourceSpecificTracks();
+
if (havePotentialSourceChild()) {
WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
scheduleNextSourceChild();
@@ -1459,10 +1658,8 @@ void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
noneSupported();
updateDisplayState();
- if (hasMediaControls()) {
+ if (hasMediaControls())
mediaControls()->reset();
- mediaControls()->reportedError();
- }
}
void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
@@ -1500,30 +1697,27 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
changeNetworkStateFromLoadingToIdle();
m_completelyLoaded = true;
}
-
- if (hasMediaControls())
- mediaControls()->updateStatusDisplay();
}
void HTMLMediaElement::changeNetworkStateFromLoadingToIdle()
{
+ ASSERT(m_player);
m_progressEventTimer.stop();
- if (hasMediaControls() && m_player->didLoadingProgress())
- mediaControls()->bufferingProgressed();
// Schedule one last progress event so we guarantee that at least one is fired
// for files that load very quickly.
- scheduleEvent(EventTypeNames::progress);
+ if (m_player->didLoadingProgress())
+ scheduleEvent(EventTypeNames::progress);
scheduleEvent(EventTypeNames::suspend);
m_networkState = NETWORK_IDLE;
}
void HTMLMediaElement::mediaPlayerReadyStateChanged()
{
- setReadyState(m_player->readyState());
+ setReadyState(static_cast<ReadyState>(webMediaPlayer()->readyState()));
}
-void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
+void HTMLMediaElement::setReadyState(ReadyState state)
{
WTF_LOG(Media, "HTMLMediaElement::setReadyState(%d) - current state is %d,", static_cast<int>(state), static_cast<int>(m_readyState));
@@ -1531,9 +1725,9 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
bool wasPotentiallyPlaying = potentiallyPlaying();
ReadyState oldState = m_readyState;
- ReadyState newState = static_cast<ReadyState>(state);
+ ReadyState newState = state;
- bool tracksAreReady = !RuntimeEnabledFeatures::videoTrackEnabled() || textTracksAreReady();
+ bool tracksAreReady = textTracksAreReady();
if (newState == oldState && m_tracksAreReady == tracksAreReady)
return;
@@ -1576,11 +1770,20 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
}
if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
+ createPlaceholderTracksIfNecessary();
+
prepareMediaFragmentURI();
+
+ selectInitialTracksIfNecessary();
+
+ m_duration = duration();
scheduleEvent(EventTypeNames::durationchange);
+
+ if (isHTMLVideoElement(*this))
+ scheduleEvent(EventTypeNames::resize);
scheduleEvent(EventTypeNames::loadedmetadata);
if (hasMediaControls())
- mediaControls()->loadedMetadata();
+ mediaControls()->reset();
if (renderer())
renderer()->updateFromElement();
}
@@ -1604,154 +1807,33 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
}
if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && tracksAreReady) {
- if (oldState <= HAVE_CURRENT_DATA)
+ if (oldState <= HAVE_CURRENT_DATA) {
scheduleEvent(EventTypeNames::canplay);
+ if (isPotentiallyPlaying)
+ scheduleEvent(EventTypeNames::playing);
+ }
- scheduleEvent(EventTypeNames::canplaythrough);
-
- if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
- scheduleEvent(EventTypeNames::playing);
-
- if (m_autoplaying && m_paused && autoplay() && !document().isSandboxed(SandboxAutomaticFeatures) && !userGestureRequiredForRateChange()) {
+ if (m_autoplaying && m_paused && autoplay() && !document().isSandboxed(SandboxAutomaticFeatures) && !m_userGestureRequiredForPlay) {
m_paused = false;
invalidateCachedTime();
scheduleEvent(EventTypeNames::play);
scheduleEvent(EventTypeNames::playing);
}
+ scheduleEvent(EventTypeNames::canplaythrough);
+
shouldUpdateDisplayState = true;
}
if (shouldUpdateDisplayState) {
updateDisplayState();
- if (hasMediaControls()) {
+ if (hasMediaControls())
mediaControls()->refreshClosedCaptionsButtonVisibility();
- mediaControls()->updateStatusDisplay();
- }
}
updatePlayState();
updateMediaController();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(currentTime());
-}
-
-void HTMLMediaElement::mediaPlayerKeyAdded(const String& keySystem, const String& sessionId)
-{
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyadded, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-void HTMLMediaElement::mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
-{
- MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
- switch (errorCode) {
- case MediaPlayerClient::UnknownError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
- break;
- case MediaPlayerClient::ClientError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
- break;
- case MediaPlayerClient::ServiceError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_SERVICE;
- break;
- case MediaPlayerClient::OutputError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_OUTPUT;
- break;
- case MediaPlayerClient::HardwareChangeError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_HARDWARECHANGE;
- break;
- case MediaPlayerClient::DomainError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_DOMAIN;
- break;
- }
-
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.errorCode = MediaKeyError::create(mediaKeyErrorCode);
- initializer.systemCode = systemCode;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyerror, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-void HTMLMediaElement::mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL)
-{
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.message = Uint8Array::create(message, messageLength);
- initializer.defaultURL = defaultURL;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeymessage, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-bool HTMLMediaElement::mediaPlayerKeyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
-{
- if (!hasEventListeners(EventTypeNames::webkitneedkey)) {
- m_error = MediaError::create(MediaError::MEDIA_ERR_ENCRYPTED);
- scheduleEvent(EventTypeNames::error);
- return false;
- }
-
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.initData = Uint8Array::create(initData, initDataLength);
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitneedkey, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
- return true;
-}
-
-bool HTMLMediaElement::mediaPlayerKeyNeeded(Uint8Array* initData)
-{
- if (!hasEventListeners("webkitneedkey")) {
- m_error = MediaError::create(MediaError::MEDIA_ERR_ENCRYPTED);
- scheduleEvent(EventTypeNames::error);
- return false;
- }
-
- MediaKeyNeededEventInit initializer;
- initializer.initData = initData;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyNeededEvent::create(EventTypeNames::webkitneedkey, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-
- return true;
-}
-
-void HTMLMediaElement::setMediaKeys(MediaKeys* mediaKeys)
-{
- if (m_mediaKeys == mediaKeys)
- return;
-
- if (m_mediaKeys)
- m_mediaKeys->setMediaElement(0);
- m_mediaKeys = mediaKeys;
- if (m_mediaKeys)
- m_mediaKeys->setMediaElement(this);
+ updateActiveTextTrackCues(currentTime());
}
void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
@@ -1769,8 +1851,6 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
m_sentStalledEvent = false;
if (renderer())
renderer()->updateFromElement();
- if (hasMediaControls())
- mediaControls()->bufferingProgressed();
} else if (timedelta > 3.0 && !m_sentStalledEvent) {
scheduleEvent(EventTypeNames::stalled);
m_sentStalledEvent = true;
@@ -1797,7 +1877,9 @@ void HTMLMediaElement::prepareToPlay()
if (m_havePreparedToPlay)
return;
m_havePreparedToPlay = true;
- m_player->prepareToPlay();
+
+ if (loadIsDeferred())
+ startDeferredLoad();
}
void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
@@ -1808,7 +1890,7 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
// 1 - If the media element's readyState is HAVE_NOTHING, then raise an InvalidStateError exception.
if (m_readyState == HAVE_NOTHING || !m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "The element's readyState is HAVE_NOTHING.");
return;
}
@@ -1827,14 +1909,15 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
// 3 - Set the seeking IDL attribute to true.
// The flag will be cleared when the engine tells us the time has actually changed.
+ bool previousSeekStillPending = m_seeking;
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());
+ time = std::min(time, duration());
// 6 - If the new playback position is less than the earliest possible position, let it be that position instead.
- time = max(time, 0.0);
+ time = std::max(time, 0.0);
// 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
@@ -1859,14 +1942,11 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
// cancel poster display.
bool noSeekRequired = !seekableRanges->length() || (time == now && displayMode() != Poster);
- // Always notify the media engine of a seek if the source is not closed. This ensures that the source is
- // always in a flushed state when the 'seeking' event fires.
- if (m_mediaSource && m_mediaSource->isClosed())
- noSeekRequired = false;
-
if (noSeekRequired) {
if (time == now) {
scheduleEvent(EventTypeNames::seeking);
+ if (previousSeekStillPending)
+ return;
// FIXME: There must be a stable state before timeupdate+seeked are dispatched and seeking
// is reset to false. See http://crbug.com/266631
scheduleTimeupdateEvent(false);
@@ -1918,7 +1998,7 @@ HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
bool HTMLMediaElement::hasAudio() const
{
- return m_player ? m_player->hasAudio() : false;
+ return webMediaPlayer() && webMediaPlayer()->hasAudio();
}
bool HTMLMediaElement::seeking() const
@@ -1977,7 +2057,7 @@ double HTMLMediaElement::currentTime() const
void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionState)
{
if (m_mediaController) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "The element is slaved to a MediaController.");
return;
}
seek(time, exceptionState);
@@ -1986,12 +2066,12 @@ void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat
double HTMLMediaElement::duration() const
{
if (!m_player || m_readyState < HAVE_METADATA)
- return numeric_limits<double>::quiet_NaN();
+ return std::numeric_limits<double>::quiet_NaN();
// FIXME: Refactor so m_duration is kept current (in both MSE and
// non-MSE cases) once we have transitioned from HAVE_NOTHING ->
// HAVE_METADATA. Currently, m_duration may be out of date for at least MSE
- // case because MediaSourceBase and SourceBuffer do not notify the element
+ // case because MediaSource and SourceBuffer do not notify the element
// directly upon duration changes caused by endOfStream, remove, or append
// operations; rather the notification is triggered by the WebMediaPlayer
// implementation observing that the underlying engine has updated duration
@@ -2016,10 +2096,11 @@ double HTMLMediaElement::defaultPlaybackRate() const
void HTMLMediaElement::setDefaultPlaybackRate(double rate)
{
- if (m_defaultPlaybackRate != rate) {
- m_defaultPlaybackRate = rate;
- scheduleEvent(EventTypeNames::ratechange);
- }
+ if (m_defaultPlaybackRate == rate)
+ return;
+
+ m_defaultPlaybackRate = rate;
+ scheduleEvent(EventTypeNames::ratechange);
}
double HTMLMediaElement::playbackRate() const
@@ -2037,13 +2118,22 @@ void HTMLMediaElement::setPlaybackRate(double rate)
scheduleEvent(EventTypeNames::ratechange);
}
- if (m_player && potentiallyPlaying() && m_player->rate() != rate && !m_mediaController)
- m_player->setRate(rate);
+ updatePlaybackRate();
+}
+
+double HTMLMediaElement::effectivePlaybackRate() const
+{
+ return m_mediaController ? m_mediaController->playbackRate() : m_playbackRate;
+}
+
+HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::directionOfPlayback() const
+{
+ return m_playbackRate >= 0 ? Forward : Backward;
}
void HTMLMediaElement::updatePlaybackRate()
{
- double effectiveRate = m_mediaController ? m_mediaController->playbackRate() : m_playbackRate;
+ double effectiveRate = effectivePlaybackRate();
if (m_player && potentiallyPlaying() && m_player->rate() != effectiveRate)
m_player->setRate(effectiveRate);
}
@@ -2053,7 +2143,7 @@ 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;
+ return endedPlayback() && directionOfPlayback() == Forward;
}
bool HTMLMediaElement::autoplay() const
@@ -2079,7 +2169,7 @@ String HTMLMediaElement::preload() const
return String();
}
-void HTMLMediaElement::setPreload(const String& preload)
+void HTMLMediaElement::setPreload(const AtomicString& preload)
{
WTF_LOG(Media, "HTMLMediaElement::setPreload(%s)", preload.utf8().data());
setAttribute(preloadAttr, preload);
@@ -2089,10 +2179,10 @@ void HTMLMediaElement::play()
{
WTF_LOG(Media, "HTMLMediaElement::play()");
- if (userGestureRequiredForRateChange() && !UserGestureIndicator::processingUserGesture())
+ if (m_userGestureRequiredForPlay && !UserGestureIndicator::processingUserGesture())
return;
if (UserGestureIndicator::processingUserGesture())
- removeBehaviorsRestrictionsAfterFirstUserGesture();
+ m_userGestureRequiredForPlay = false;
playInternal();
}
@@ -2131,18 +2221,6 @@ void HTMLMediaElement::pause()
{
WTF_LOG(Media, "HTMLMediaElement::pause()");
- if (userGestureRequiredForRateChange() && !UserGestureIndicator::processingUserGesture())
- return;
-
- pauseInternal();
-}
-
-
-void HTMLMediaElement::pauseInternal()
-{
- WTF_LOG(Media, "HTMLMediaElement::pauseInternal");
-
- // 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY)
scheduleDelayedAction(LoadMediaResource);
@@ -2163,89 +2241,7 @@ void HTMLMediaElement::closeMediaSource()
return;
m_mediaSource->close();
- m_mediaSource = 0;
-}
-
-void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState& exceptionState)
-{
- if (keySystem.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- const unsigned char* initDataPointer = 0;
- unsigned initDataLength = 0;
- if (initData) {
- initDataPointer = initData->data();
- initDataLength = initData->length();
- }
-
- MediaPlayer::MediaKeyException result = m_player->generateKeyRequest(keySystem, initDataPointer, initDataLength);
- throwExceptionForMediaKeyException(result, exceptionState);
-}
-
-void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, ExceptionState& exceptionState)
-{
- webkitGenerateKeyRequest(keySystem, Uint8Array::create(0), exceptionState);
-}
-
-void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState& exceptionState)
-{
- if (keySystem.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!key) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!key->length()) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- if (!m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- const unsigned char* initDataPointer = 0;
- unsigned initDataLength = 0;
- if (initData) {
- initDataPointer = initData->data();
- initDataLength = initData->length();
- }
-
- MediaPlayer::MediaKeyException result = m_player->addKey(keySystem, key->data(), key->length(), initDataPointer, initDataLength, sessionId);
- throwExceptionForMediaKeyException(result, exceptionState);
-}
-
-void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState& exceptionState)
-{
- webkitAddKey(keySystem, key, Uint8Array::create(0), String(), exceptionState);
-}
-
-void HTMLMediaElement::webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState& exceptionState)
-{
- if (keySystem.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- MediaPlayer::MediaKeyException result = m_player->cancelKeyRequest(keySystem, sessionId);
- throwExceptionForMediaKeyException(result, exceptionState);
+ m_mediaSource = nullptr;
}
bool HTMLMediaElement::loop() const
@@ -2261,7 +2257,7 @@ void HTMLMediaElement::setLoop(bool b)
bool HTMLMediaElement::controls() const
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
// always show controls when scripting is disabled
if (frame && !frame->script().canExecuteScripts(NotAboutToExecuteScript))
@@ -2289,16 +2285,17 @@ void HTMLMediaElement::setVolume(double vol, ExceptionState& exceptionState)
{
WTF_LOG(Media, "HTMLMediaElement::setVolume(%f)", vol);
+ if (m_volume == vol)
+ return;
+
if (vol < 0.0f || vol > 1.0f) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", vol, 0.0, ExceptionMessages::InclusiveBound, 1.0, ExceptionMessages::InclusiveBound));
return;
}
- if (m_volume != vol) {
- m_volume = vol;
- updateVolume();
- scheduleEvent(EventTypeNames::volumechange);
- }
+ m_volume = vol;
+ updateVolume();
+ scheduleEvent(EventTypeNames::volumechange);
}
bool HTMLMediaElement::muted() const
@@ -2310,55 +2307,14 @@ void HTMLMediaElement::setMuted(bool muted)
{
WTF_LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
- if (m_muted != muted) {
- m_muted = muted;
- if (m_player) {
- m_player->setMuted(m_muted);
- if (hasMediaControls())
- mediaControls()->changedMute();
- }
- scheduleEvent(EventTypeNames::volumechange);
- }
-}
-
-void HTMLMediaElement::togglePlayState()
-{
- WTF_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()) {
- updatePlaybackRate();
- playInternal();
- } else
- pauseInternal();
-}
-
-void HTMLMediaElement::beginScrubbing()
-{
- WTF_LOG(Media, "HTMLMediaElement::beginScrubbing - paused() is %s", boolString(paused()));
+ if (m_muted == muted)
+ return;
- 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();
- } 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);
- }
- }
-}
+ m_muted = muted;
-void HTMLMediaElement::endScrubbing()
-{
- WTF_LOG(Media, "HTMLMediaElement::endScrubbing - m_pausedInternal is %s", boolString(m_pausedInternal));
+ updateVolume();
- if (m_pausedInternal)
- setPausedInternal(false);
+ scheduleEvent(EventTypeNames::volumechange);
}
// The spec says to fire periodic timeupdate events (those sent while playing) every
@@ -2371,32 +2327,32 @@ void HTMLMediaElement::startPlaybackProgressTimer()
return;
m_previousProgressTime = WTF::currentTime();
- m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
+ m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HERE);
}
void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
{
ASSERT(m_player);
- if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fragmentEndTime && m_playbackRate > 0) {
+ if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fragmentEndTime && directionOfPlayback() == Forward) {
m_fragmentEndTime = MediaPlayer::invalidTime();
if (!m_mediaController && !m_paused) {
+ UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFragmentEnd);
// changes paused to true and fires a simple event named pause at the media element.
- pauseInternal();
+ pause();
}
}
if (!m_seeking)
scheduleTimeupdateEvent(true);
- if (!m_playbackRate)
+ if (!effectivePlaybackRate())
return;
if (!m_paused && hasMediaControls())
mediaControls()->playbackProgressed();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(currentTime());
+ updateActiveTextTrackCues(currentTime());
}
void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
@@ -2418,38 +2374,139 @@ void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
}
}
-bool HTMLMediaElement::canPlay() const
+bool HTMLMediaElement::togglePlayStateWillPlay() const
{
- return paused() || ended() || m_readyState < HAVE_METADATA;
+ if (m_mediaController)
+ return m_mediaController->paused() || m_mediaController->isRestrained();
+ return paused();
}
-double HTMLMediaElement::percentLoaded() const
+void HTMLMediaElement::togglePlayState()
{
- if (!m_player)
+ if (m_mediaController) {
+ if (m_mediaController->isRestrained())
+ m_mediaController->play();
+ else if (m_mediaController->paused())
+ m_mediaController->unpause();
+ else
+ m_mediaController->pause();
+ } else {
+ if (paused())
+ play();
+ else
+ pause();
+ }
+}
+
+AudioTrackList& HTMLMediaElement::audioTracks()
+{
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+ return *m_audioTracks;
+}
+
+void HTMLMediaElement::audioTrackChanged()
+{
+ WTF_LOG(Media, "HTMLMediaElement::audioTrackChanged()");
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+
+ audioTracks().scheduleChangeEvent();
+
+ // FIXME: Add call on m_mediaSource to notify it of track changes once the SourceBuffer.audioTracks attribute is added.
+
+ if (!m_audioTracksTimer.isActive())
+ m_audioTracksTimer.startOneShot(0, FROM_HERE);
+}
+
+void HTMLMediaElement::audioTracksTimerFired(Timer<HTMLMediaElement>*)
+{
+ Vector<WebMediaPlayer::TrackId> enabledTrackIds;
+ for (unsigned i = 0; i < audioTracks().length(); ++i) {
+ AudioTrack* track = audioTracks().anonymousIndexedGetter(i);
+ if (track->enabled())
+ enabledTrackIds.append(track->trackId());
+ }
+
+ webMediaPlayer()->enabledAudioTracksChanged(enabledTrackIds);
+}
+
+WebMediaPlayer::TrackId HTMLMediaElement::addAudioTrack(const String& id, blink::WebMediaPlayerClient::AudioTrackKind kind, const AtomicString& label, const AtomicString& language, bool enabled)
+{
+ AtomicString kindString = AudioKindToString(kind);
+ WTF_LOG(Media, "HTMLMediaElement::addAudioTrack('%s', '%s', '%s', '%s', %d)",
+ id.ascii().data(), kindString.ascii().data(), label.ascii().data(), language.ascii().data(), enabled);
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
return 0;
- double duration = m_player->duration();
- if (!duration || std::isinf(duration))
+ RefPtrWillBeRawPtr<AudioTrack> audioTrack = AudioTrack::create(id, kindString, label, language, enabled);
+ audioTracks().add(audioTrack);
+
+ return audioTrack->trackId();
+}
+
+void HTMLMediaElement::removeAudioTrack(WebMediaPlayer::TrackId trackId)
+{
+ WTF_LOG(Media, "HTMLMediaElement::removeAudioTrack()");
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
+ return;
+
+ audioTracks().remove(trackId);
+}
+
+VideoTrackList& HTMLMediaElement::videoTracks()
+{
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+ return *m_videoTracks;
+}
+
+void HTMLMediaElement::selectedVideoTrackChanged(WebMediaPlayer::TrackId* selectedTrackId)
+{
+ WTF_LOG(Media, "HTMLMediaElement::selectedVideoTrackChanged()");
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+
+ if (selectedTrackId)
+ videoTracks().trackSelected(*selectedTrackId);
+
+ // FIXME: Add call on m_mediaSource to notify it of track changes once the SourceBuffer.videoTracks attribute is added.
+
+ webMediaPlayer()->selectedVideoTrackChanged(selectedTrackId);
+}
+
+WebMediaPlayer::TrackId HTMLMediaElement::addVideoTrack(const String& id, blink::WebMediaPlayerClient::VideoTrackKind kind, const AtomicString& label, const AtomicString& language, bool selected)
+{
+ AtomicString kindString = VideoKindToString(kind);
+ WTF_LOG(Media, "HTMLMediaElement::addVideoTrack('%s', '%s', '%s', '%s', %d)",
+ id.ascii().data(), kindString.ascii().data(), label.ascii().data(), language.ascii().data(), selected);
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
return 0;
- double buffered = 0;
- RefPtr<TimeRanges> timeRanges = m_player->buffered();
- for (unsigned i = 0; i < timeRanges->length(); ++i) {
- double start = timeRanges->start(i, IGNORE_EXCEPTION);
- double end = timeRanges->end(i, IGNORE_EXCEPTION);
- buffered += end - start;
- }
- return buffered / duration;
+ // If another track was selected (potentially by the user), leave it selected.
+ if (selected && videoTracks().selectedIndex() != -1)
+ selected = false;
+
+ RefPtrWillBeRawPtr<VideoTrack> videoTrack = VideoTrack::create(id, kindString, label, language, selected);
+ videoTracks().add(videoTrack);
+
+ return videoTrack->trackId();
}
-void HTMLMediaElement::mediaPlayerDidAddTrack(WebInbandTextTrack* webTrack)
+void HTMLMediaElement::removeVideoTrack(WebMediaPlayer::TrackId trackId)
{
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
+ WTF_LOG(Media, "HTMLMediaElement::removeVideoTrack()");
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
return;
+ videoTracks().remove(trackId);
+}
+
+void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack)
+{
// 4.8.10.12.2 Sourcing in-band text tracks
// 1. Associate the relevant data with a new text track and its corresponding new TextTrack object.
- RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), this, webTrack);
+ RefPtrWillBeRawPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), webTrack);
// 2. Set the new text track's kind, label, and language based on the semantics of the relevant data,
// as defined by the relevant specification. If there is no label in that data, then the label must
@@ -2474,24 +2531,21 @@ void HTMLMediaElement::mediaPlayerDidAddTrack(WebInbandTextTrack* webTrack)
// 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent
// interface, with the track attribute initialized to the text track's TextTrack object, at the media element's
// textTracks attribute's TextTrackList object.
- addTrack(textTrack.get());
+ addTextTrack(textTrack.get());
}
-void HTMLMediaElement::mediaPlayerDidRemoveTrack(WebInbandTextTrack* webTrack)
+void HTMLMediaElement::mediaPlayerDidRemoveTextTrack(WebInbandTextTrack* webTrack)
{
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
-
if (!m_textTracks)
return;
// This cast is safe because we created the InbandTextTrack with the WebInbandTextTrack
- // passed to mediaPlayerDidAddTrack.
- RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack->client());
+ // passed to mediaPlayerDidAddTextTrack.
+ RefPtrWillBeRawPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack->client());
if (!textTrack)
return;
- removeTrack(textTrack.get());
+ removeTextTrack(textTrack.get());
}
void HTMLMediaElement::closeCaptionTracksChanged()
@@ -2500,49 +2554,47 @@ void HTMLMediaElement::closeCaptionTracksChanged()
mediaControls()->closedCaptionTracksChanged();
}
-void HTMLMediaElement::addTrack(TextTrack* track)
+void HTMLMediaElement::addTextTrack(TextTrack* track)
{
textTracks()->append(track);
closeCaptionTracksChanged();
}
-void HTMLMediaElement::removeTrack(TextTrack* track)
+void HTMLMediaElement::removeTextTrack(TextTrack* track)
{
TrackDisplayUpdateScope scope(this);
- TextTrackCueList* cues = track->cues();
- if (cues)
- textTrackRemoveCues(track, cues);
m_textTracks->remove(track);
closeCaptionTracksChanged();
}
-void HTMLMediaElement::removeAllInbandTracks()
+void HTMLMediaElement::forgetResourceSpecificTracks()
{
- if (!m_textTracks)
- return;
+ // Implements the "forget the media element's media-resource-specific tracks" algorithm.
+ // The order is explicitly specified as text, then audio, and finally video. Also
+ // 'removetrack' events should not be fired.
+ if (m_textTracks) {
+ TrackDisplayUpdateScope scope(this);
+ m_textTracks->removeAllInbandTracks();
+ closeCaptionTracksChanged();
+ }
- TrackDisplayUpdateScope scope(this);
- for (int i = m_textTracks->length() - 1; i >= 0; --i) {
- TextTrack* track = m_textTracks->item(i);
+ m_audioTracks->removeAll();
+ m_videoTracks->removeAll();
- if (track->trackType() == TextTrack::InBand)
- removeTrack(track);
- }
+ m_audioTracksTimer.stop();
}
-PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const String& label, const String& language, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, const AtomicString& label, const AtomicString& language, ExceptionState& exceptionState)
{
- ASSERT(RuntimeEnabledFeatures::videoTrackEnabled());
-
// 4.8.10.12.4 Text track API
// The addTextTrack(kind, label, language) method of media elements, when invoked, must run the following steps:
// 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps
if (!TextTrack::isValidKindKeyword(kind)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return 0;
+ exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid.");
+ return nullptr;
}
// 2. If the label argument was omitted, let label be the empty string.
@@ -2551,13 +2603,13 @@ PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const S
// 5. Create a new text track corresponding to the new object, and set its text track kind to kind, its text
// track label to label, its text track language to language...
- RefPtr<TextTrack> textTrack = TextTrack::create(document(), this, kind, label, language);
+ RefPtrWillBeRawPtr<TextTrack> textTrack = TextTrack::create(document(), kind, label, language);
// Note, due to side effects when changing track parameters, we have to
// first append the track to the text track list.
// 6. Add the new text track to the media element's list of text tracks.
- addTrack(textTrack.get());
+ addTextTrack(textTrack.get());
// ... its text track readiness state to the text track loaded state ...
textTrack->setReadinessState(TextTrack::Loaded);
@@ -2570,55 +2622,41 @@ PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const S
TextTrackList* HTMLMediaElement::textTracks()
{
- ASSERT(RuntimeEnabledFeatures::videoTrackEnabled());
-
if (!m_textTracks)
m_textTracks = TextTrackList::create(this);
return m_textTracks.get();
}
-void HTMLMediaElement::didAddTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::didAddTrackElement(HTMLTrackElement* trackElement)
{
- ASSERT(trackElement->hasTagName(trackTag));
-
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
-
// 4.8.10.12.3 Sourcing out-of-band text tracks
// When a track element's parent element changes and the new parent is a media element,
// then the user agent must add the track element's corresponding text track to the
// media element's list of text tracks ... [continues in TextTrackList::append]
- RefPtr<TextTrack> textTrack = trackElement->track();
+ RefPtrWillBeRawPtr<TextTrack> textTrack = trackElement->track();
if (!textTrack)
return;
- addTrack(textTrack.get());
+ addTextTrack(textTrack.get());
// Do not schedule the track loading until parsing finishes so we don't start before all tracks
// in the markup have been added.
- if (!m_parsingInProgress)
+ if (isFinishedParsingChildren())
scheduleDelayedAction(LoadTextTrackResource);
if (hasMediaControls())
mediaControls()->closedCaptionTracksChanged();
}
-void HTMLMediaElement::didRemoveTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement)
{
- ASSERT(trackElement->hasTagName(trackTag));
-
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
-
#if !LOG_DISABLED
- if (trackElement->hasTagName(trackTag)) {
- KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
- WTF_LOG(Media, "HTMLMediaElement::didRemoveTrack - 'src' is %s", urlForLoggingMedia(url).utf8().data());
- }
+ KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
+ WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement - 'src' is %s", urlForLoggingMedia(url).utf8().data());
#endif
- RefPtr<TextTrack> textTrack = trackElement->track();
+ RefPtrWillBeRawPtr<TextTrack> textTrack = trackElement->track();
if (!textTrack)
return;
@@ -2631,7 +2669,7 @@ void HTMLMediaElement::didRemoveTrack(HTMLTrackElement* trackElement)
// When a track element's parent element changes and the old parent was a media element,
// then the user agent must remove the track element's corresponding text track from the
// media element's list of text tracks.
- removeTrack(textTrack.get());
+ removeTextTrack(textTrack.get());
size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get());
if (index != kNotFound)
@@ -2643,32 +2681,20 @@ static int textTrackLanguageSelectionScore(const TextTrack& track)
if (track.language().isEmpty())
return 0;
- Vector<String> languages = userPreferredLanguages();
+ Vector<AtomicString> languages = userPreferredLanguages();
size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track.language(), languages);
if (languageMatchIndex >= languages.size())
return 0;
- // Matching a track language is more important than matching track type, so this multiplier must be
- // greater than the maximum value returned by textTrackSelectionScore.
- return (languages.size() - languageMatchIndex) * 10;
+ return languages.size() - languageMatchIndex;
}
-static int textTrackSelectionScore(const TextTrack& track, Settings* settings)
+static int textTrackSelectionScore(const TextTrack& track)
{
- int trackScore = 0;
-
- if (!settings)
- return trackScore;
-
if (track.kind() != TextTrack::captionsKeyword() && track.kind() != TextTrack::subtitlesKeyword())
- return trackScore;
-
- if (track.kind() == TextTrack::subtitlesKeyword() && settings->shouldDisplaySubtitles())
- trackScore = 1;
- else if (track.kind() == TextTrack::captionsKeyword() && settings->shouldDisplayCaptions())
- trackScore = 1;
+ return 0;
- return trackScore + textTrackLanguageSelectionScore(track);
+ return textTrackLanguageSelectionScore(track);
}
void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
@@ -2677,21 +2703,19 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
WTF_LOG(Media, "HTMLMediaElement::configureTextTrackGroup(%d)", group.kind);
- Settings* settings = document().settings();
-
// First, find the track in the group that should be enabled (if any).
- Vector<RefPtr<TextTrack> > currentlyEnabledTracks;
- RefPtr<TextTrack> trackToEnable;
- RefPtr<TextTrack> defaultTrack;
- RefPtr<TextTrack> fallbackTrack;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > currentlyEnabledTracks;
+ RefPtrWillBeRawPtr<TextTrack> trackToEnable = nullptr;
+ RefPtrWillBeRawPtr<TextTrack> defaultTrack = nullptr;
+ RefPtrWillBeRawPtr<TextTrack> fallbackTrack = nullptr;
int highestTrackScore = 0;
for (size_t i = 0; i < group.tracks.size(); ++i) {
- RefPtr<TextTrack> textTrack = group.tracks[i];
+ RefPtrWillBeRawPtr<TextTrack> textTrack = group.tracks[i];
if (m_processingPreferenceChange && textTrack->mode() == TextTrack::showingKeyword())
currentlyEnabledTracks.append(textTrack);
- int trackScore = textTrackSelectionScore(*textTrack, settings);
+ int trackScore = textTrackSelectionScore(*textTrack);
if (trackScore) {
// * If the text track kind is { [subtitles or captions] [descriptions] } and the user has indicated an interest in having a
// track with this text track kind, text track language, and text track label enabled, and there is no
@@ -2732,7 +2756,7 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
if (currentlyEnabledTracks.size()) {
for (size_t i = 0; i < currentlyEnabledTracks.size(); ++i) {
- RefPtr<TextTrack> textTrack = currentlyEnabledTracks[i];
+ RefPtrWillBeRawPtr<TextTrack> textTrack = currentlyEnabledTracks[i];
if (textTrack != trackToEnable)
textTrack->setMode(TextTrack::disabledKeyword());
}
@@ -2754,7 +2778,7 @@ void HTMLMediaElement::configureTextTracks()
return;
for (size_t i = 0; i < m_textTracks->length(); ++i) {
- RefPtr<TextTrack> textTrack = m_textTracks->item(i);
+ RefPtrWillBeRawPtr<TextTrack> textTrack = m_textTracks->item(i);
if (!textTrack)
continue;
@@ -2809,8 +2833,8 @@ bool HTMLMediaElement::havePotentialSourceChild()
{
// Stash the current <source> node and next nodes so we can restore them after checking
// to see there is another potential.
- RefPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNode;
- RefPtr<Node> nextNode = m_nextChildNodeToConsider;
+ RefPtrWillBeRawPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNode;
+ RefPtrWillBeRawPtr<Node> nextNode = m_nextChildNodeToConsider;
KURL nextURL = selectNextSourceChild(0, 0, DoNothing);
@@ -2844,7 +2868,6 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
String system;
bool lookingForStartNode = m_nextChildNodeToConsider;
bool canUseSourceElement = false;
- bool okToLoadSourceURL;
NodeVector potentialSourceNodes;
getChildNodes(*this, potentialSourceNodes);
@@ -2855,12 +2878,11 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
continue;
lookingForStartNode = false;
- if (!node->hasTagName(sourceTag))
+ if (!isHTMLSourceElement(*node))
continue;
if (node->parentNode() != this)
continue;
- UseCounter::count(document(), UseCounter::SourceElementCandidate);
source = toHTMLSourceElement(node);
// If candidate does not have a src attribute, or if its src attribute's value is the empty string ... jump down to the failed step below
@@ -2872,19 +2894,6 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
if (mediaURL.isEmpty())
goto check_again;
- if (source->fastHasAttribute(mediaAttr)) {
- MediaQueryEvaluator screenEval("screen", document().frame(), renderer() ? renderer()->style() : 0);
- RefPtr<MediaQuerySet> media = MediaQuerySet::create(source->media());
-#if !LOG_DISABLED
- if (shouldLog)
- WTF_LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'media' is %s", source->media().string().utf8().data());
-#endif
- if (!screenEval.eval(media.get())) {
- UseCounter::count(document(), UseCounter::SourceElementNonMatchingMedia);
- goto check_again;
- }
- }
-
type = source->type();
// FIXME(82965): Add support for keySystem in <source> and set system from source.
if (type.isEmpty() && mediaURL.protocolIsData())
@@ -2899,16 +2908,7 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
}
// Is it safe to load this url?
- okToLoadSourceURL = isSafeToLoadURL(mediaURL, actionIfInvalid) && dispatchBeforeLoadEvent(mediaURL.string());
-
- // A 'beforeload' event handler can mutate the DOM, so check to see if the source element is still a child node.
- if (node->parentNode() != this) {
- WTF_LOG(Media, "HTMLMediaElement::selectNextSourceChild : 'beforeload' removed current element");
- source = 0;
- goto check_again;
- }
-
- if (!okToLoadSourceURL)
+ if (!isSafeToLoadURL(mediaURL, actionIfInvalid))
goto check_again;
// Making it this far means the <source> looks reasonable.
@@ -2927,8 +2927,8 @@ check_again:
m_currentSourceNode = source;
m_nextChildNodeToConsider = source->nextSibling();
} else {
- m_currentSourceNode = 0;
- m_nextChildNodeToConsider = 0;
+ m_currentSourceNode = nullptr;
+ m_nextChildNodeToConsider = nullptr;
}
#if !LOG_DISABLED
@@ -2943,10 +2943,8 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p)", source);
#if !LOG_DISABLED
- if (source->hasTagName(sourceTag)) {
- KURL url = source->getNonEmptyURLAttribute(srcAttr);
- WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
- }
+ KURL url = source->getNonEmptyURLAttribute(srcAttr);
+ WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
#endif
// We should only consider a <source> element when there is not src attribute at all.
@@ -2991,10 +2989,8 @@ void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p)", source);
#if !LOG_DISABLED
- if (source->hasTagName(sourceTag)) {
- KURL url = source->getNonEmptyURLAttribute(srcAttr);
- WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
- }
+ KURL url = source->getNonEmptyURLAttribute(srcAttr);
+ WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
#endif
if (source != m_currentSourceNode && source != m_nextChildNodeToConsider)
@@ -3008,7 +3004,7 @@ void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
// 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;
+ m_currentSourceNode = nullptr;
WTF_LOG(Media, "HTMLMediaElement::sourceRemoved - m_currentSourceNode set to 0");
}
}
@@ -3017,8 +3013,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged");
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(currentTime());
+ updateActiveTextTrackCues(currentTime());
invalidateCachedTime();
@@ -3036,7 +3031,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
// When the current playback position reaches the end of the media resource when the direction of
// playback is forwards, then the user agent must follow these steps:
- if (!std::isnan(dur) && dur && now >= dur && m_playbackRate > 0) {
+ if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forward) {
// If the media element has a loop attribute specified and does not have a current media controller,
if (loop() && !m_mediaController) {
m_sentEndEvent = false;
@@ -3070,17 +3065,22 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
void HTMLMediaElement::mediaPlayerDurationChanged()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged");
- durationChanged(duration());
+ // FIXME: Change MediaPlayerClient & WebMediaPlayer to convey
+ // the currentTime when the duration change occured. The current
+ // WebMediaPlayer implementations always clamp currentTime() to
+ // duration() so the requestSeek condition here is always false.
+ durationChanged(duration(), currentTime() > duration());
}
-void HTMLMediaElement::durationChanged(double duration)
+void HTMLMediaElement::durationChanged(double duration, bool requestSeek)
{
- WTF_LOG(Media, "HTMLMediaElement::durationChanged(%f)", duration);
+ WTF_LOG(Media, "HTMLMediaElement::durationChanged(%f, %d)", duration, requestSeek);
// Abort if duration unchanged.
if (m_duration == duration)
return;
+ WTF_LOG(Media, "HTMLMediaElement::durationChanged : %f -> %f", m_duration, duration);
m_duration = duration;
scheduleEvent(EventTypeNames::durationchange);
@@ -3089,7 +3089,7 @@ void HTMLMediaElement::durationChanged(double duration)
if (renderer())
renderer()->updateFromElement();
- if (currentTime() > duration)
+ if (requestSeek)
seek(duration, IGNORE_EXCEPTION);
}
@@ -3101,7 +3101,7 @@ void HTMLMediaElement::mediaPlayerPlaybackStateChanged()
return;
if (m_player->paused())
- pauseInternal();
+ pause();
else
playInternal();
}
@@ -3109,6 +3109,11 @@ void HTMLMediaElement::mediaPlayerPlaybackStateChanged()
void HTMLMediaElement::mediaPlayerRequestFullscreen()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerRequestFullscreen");
+
+ // The player is responsible for only invoking this callback in response to
+ // user interaction or when it is technically required to play the video.
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
+
enterFullscreen();
}
@@ -3130,14 +3135,15 @@ void HTMLMediaElement::mediaPlayerRepaint()
updateDisplayState();
if (renderer())
- renderer()->repaint();
+ renderer()->paintInvalidationForWholeRenderer();
}
void HTMLMediaElement::mediaPlayerSizeChanged()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged");
- if (m_readyState > HAVE_NOTHING)
+ ASSERT(hasVideo()); // "resize" makes no sense absent video.
+ if (m_readyState > HAVE_NOTHING && isHTMLVideoElement(*this))
scheduleEvent(EventTypeNames::resize);
if (renderer())
@@ -3190,7 +3196,7 @@ bool HTMLMediaElement::potentiallyPlaying() const
bool HTMLMediaElement::couldPlayIfEnoughData() const
{
- return !paused() && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction();
+ return !paused() && !endedPlayback() && !stoppedDueToErrors();
}
bool HTMLMediaElement::endedPlayback() const
@@ -3210,15 +3216,13 @@ bool HTMLMediaElement::endedPlayback() const
// of playback is forwards, Either the media element does not have a loop attribute specified,
// or the media element has a current media controller.
double now = currentTime();
- if (m_playbackRate > 0)
+ if (directionOfPlayback() == Forward)
return dur > 0 && now >= dur && (!loop() || m_mediaController);
// or the current playback position is the earliest possible position and the direction
// of playback is backwards
- if (m_playbackRate < 0)
- return now <= 0;
-
- return false;
+ ASSERT(directionOfPlayback() == Backward);
+ return now <= 0;
}
bool HTMLMediaElement::stoppedDueToErrors() const
@@ -3232,17 +3236,17 @@ bool HTMLMediaElement::stoppedDueToErrors() const
return false;
}
-bool HTMLMediaElement::pausedForUserInteraction() const
+void HTMLMediaElement::updateVolume()
{
-// return !paused() && m_readyState >= HAVE_FUTURE_DATA && [UA requires a decitions from the user]
- return false;
+ if (webMediaPlayer())
+ webMediaPlayer()->setVolume(playerVolume());
+
+ if (hasMediaControls())
+ mediaControls()->updateVolume();
}
-void HTMLMediaElement::updateVolume()
+double HTMLMediaElement::playerVolume() const
{
- if (!m_player)
- return;
-
double volumeMultiplier = 1;
bool shouldMute = m_muted;
@@ -3251,11 +3255,7 @@ void HTMLMediaElement::updateVolume()
shouldMute = m_mediaController->muted();
}
- m_player->setMuted(shouldMute);
- m_player->setVolume(m_volume * volumeMultiplier);
-
- if (hasMediaControls())
- mediaControls()->changedVolume();
+ return shouldMute ? 0 : m_volume * volumeMultiplier;
}
void HTMLMediaElement::updatePlayState()
@@ -3286,8 +3286,8 @@ void HTMLMediaElement::updatePlayState()
if (playerPaused) {
// Set rate, muted before calling play in case they were set before the media engine was setup.
// The media engine should just stash the rate and muted values since it isn't already playing.
- m_player->setRate(m_playbackRate);
- m_player->setMuted(m_muted);
+ m_player->setRate(effectivePlaybackRate());
+ updateVolume();
m_player->play();
}
@@ -3368,40 +3368,42 @@ void HTMLMediaElement::userCancelledLoad()
setShouldDelayLoadEvent(false);
// 6 - Abort the overall resource selection algorithm.
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
// Reset m_readyState since m_player is gone.
m_readyState = HAVE_NOTHING;
updateMediaController();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(0);
+ updateActiveTextTrackCues(0);
}
-void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClient()
+void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLocking()
{
#if ENABLE(WEB_AUDIO)
- if (m_audioSourceNode)
- m_audioSourceNode->lock();
-
if (audioSourceProvider())
audioSourceProvider()->setClient(0);
#endif
-
m_player.clear();
-
-#if ENABLE(WEB_AUDIO)
- if (m_audioSourceNode)
- m_audioSourceNode->unlock();
-#endif
}
void HTMLMediaElement::clearMediaPlayer(int flags)
{
- removeAllInbandTracks();
+ forgetResourceSpecificTracks();
closeMediaSource();
- clearMediaPlayerAndAudioSourceProviderClient();
+ cancelDeferredLoad();
+
+#if ENABLE(WEB_AUDIO)
+ if (m_audioSourceNode)
+ m_audioSourceNode->lock();
+#endif
+
+ clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
+
+#if ENABLE(WEB_AUDIO)
+ if (m_audioSourceNode)
+ m_audioSourceNode->unlock();
+#endif
stopPeriodicTimers();
m_loadTimer.stop();
@@ -3440,8 +3442,12 @@ bool HTMLMediaElement::hasPendingActivity() const
void HTMLMediaElement::contextDestroyed()
{
+ // With Oilpan the ExecutionContext is weakly referenced from the media
+ // controller and so it will clear itself on destruction.
+#if !ENABLE(OILPAN)
if (m_mediaController)
m_mediaController->clearExecutionContext();
+#endif
ActiveDOMObject::contextDestroyed();
}
@@ -3454,32 +3460,30 @@ void HTMLMediaElement::enterFullscreen()
{
WTF_LOG(Media, "HTMLMediaElement::enterFullscreen");
- if (document().settings() && document().settings()->fullScreenEnabled())
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
}
void HTMLMediaElement::exitFullscreen()
{
WTF_LOG(Media, "HTMLMediaElement::exitFullscreen");
- if (document().settings() && document().settings()->fullScreenEnabled() && isFullscreen())
- FullscreenElementStack::from(&document())->webkitCancelFullScreen();
+ FullscreenElementStack::from(document()).webkitCancelFullScreen();
}
void HTMLMediaElement::didBecomeFullscreenElement()
{
if (hasMediaControls())
mediaControls()->enteredFullscreen();
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isVideo())
- document().renderView()->compositor()->setCompositingLayersNeedRebuild(true);
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isHTMLVideoElement(*this))
+ document().renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
}
void HTMLMediaElement::willStopBeingFullscreenElement()
{
if (hasMediaControls())
mediaControls()->exitedFullscreen();
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isVideo())
- document().renderView()->compositor()->setCompositingLayersNeedRebuild(true);
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isHTMLVideoElement(*this))
+ document().renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
}
blink::WebLayer* HTMLMediaElement::platformLayer() const
@@ -3489,7 +3493,7 @@ blink::WebLayer* HTMLMediaElement::platformLayer() const
bool HTMLMediaElement::hasClosedCaptions() const
{
- if (RuntimeEnabledFeatures::videoTrackEnabled() && m_textTracks) {
+ if (m_textTracks) {
for (unsigned i = 0; i < m_textTracks->length(); ++i) {
if (m_textTracks->item(i)->readinessState() == TextTrack::FailedToLoad)
continue;
@@ -3526,27 +3530,25 @@ void HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible)
m_closedCaptionsVisible = closedCaptionVisible;
- if (RuntimeEnabledFeatures::videoTrackEnabled()) {
- m_processingPreferenceChange = true;
- markCaptionAndSubtitleTracksAsUnconfigured();
- m_processingPreferenceChange = false;
+ m_processingPreferenceChange = true;
+ markCaptionAndSubtitleTracksAsUnconfigured();
+ m_processingPreferenceChange = false;
- updateTextTrackDisplay();
- }
+ updateTextTrackDisplay();
}
unsigned HTMLMediaElement::webkitAudioDecodedByteCount() const
{
- if (!m_player)
+ if (!webMediaPlayer())
return 0;
- return m_player->audioDecodedByteCount();
+ return webMediaPlayer()->audioDecodedByteCount();
}
unsigned HTMLMediaElement::webkitVideoDecodedByteCount() const
{
- if (!m_player)
+ if (!webMediaPlayer())
return 0;
- return m_player->videoDecodedByteCount();
+ return webMediaPlayer()->videoDecodedByteCount();
}
bool HTMLMediaElement::isURLAttribute(const Attribute& attribute) const
@@ -3590,11 +3592,10 @@ bool HTMLMediaElement::createMediaControls()
if (hasMediaControls())
return true;
- RefPtr<MediaControls> mediaControls = MediaControls::create(document());
+ RefPtrWillBeRawPtr<MediaControls> mediaControls = MediaControls::create(*this);
if (!mediaControls)
return false;
- mediaControls->setMediaController(m_mediaController ? m_mediaController.get() : static_cast<MediaControllerInterface*>(this));
mediaControls->reset();
if (isFullscreen())
mediaControls->enteredFullscreen();
@@ -3618,6 +3619,7 @@ void HTMLMediaElement::configureMediaControls()
if (!hasMediaControls() && !createMediaControls())
return;
+ mediaControls()->reset();
mediaControls()->show();
}
@@ -3652,10 +3654,8 @@ void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu
mediaControls()->changedClosedCaptionsVisibility();
- if (RuntimeEnabledFeatures::videoTrackEnabled()) {
- updateActiveTextTrackCues(currentTime());
- updateTextTrackDisplay();
- }
+ updateActiveTextTrackCues(currentTime());
+ updateTextTrackDisplay();
}
void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
@@ -3669,7 +3669,7 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
// captions and non-default tracks should be displayed based on language
// preferences if the user has turned captions on).
for (unsigned i = 0; i < m_textTracks->length(); ++i) {
- RefPtr<TextTrack> textTrack = m_textTracks->item(i);
+ RefPtrWillBeRawPtr<TextTrack> textTrack = m_textTracks->item(i);
String kind = textTrack->kind();
if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword())
@@ -3678,7 +3678,6 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
configureTextTracks();
}
-
void* HTMLMediaElement::preDispatchEventHandler(Event* event)
{
if (event && event->type() == EventTypeNames::webkitfullscreenchange)
@@ -3694,14 +3693,13 @@ void HTMLMediaElement::createMediaPlayer()
m_audioSourceNode->lock();
#endif
- if (m_mediaSource)
- closeMediaSource();
+ closeMediaSource();
m_player = MediaPlayer::create(this);
#if ENABLE(WEB_AUDIO)
if (m_audioSourceNode) {
- // When creating the player, make sure its AudioSourceProvider knows about the MediaElementAudioSourceNode.
+ // When creating the player, make sure its AudioSourceProvider knows about the client.
if (audioSourceProvider())
audioSourceProvider()->setClient(m_audioSourceNode);
@@ -3711,7 +3709,7 @@ void HTMLMediaElement::createMediaPlayer()
}
#if ENABLE(WEB_AUDIO)
-void HTMLMediaElement::setAudioSourceNode(MediaElementAudioSourceNode* sourceNode)
+void HTMLMediaElement::setAudioSourceNode(AudioSourceProviderClient* sourceNode)
{
m_audioSourceNode = sourceNode;
@@ -3745,7 +3743,7 @@ void HTMLMediaElement::setMediaGroup(const AtomicString& group)
// attribute is set, changed, or removed, the user agent must run the following steps:
// 1. Let m [this] be the media element in question.
// 2. Let m have no current media controller, if it currently has one.
- setControllerInternal(0);
+ setControllerInternal(nullptr);
// 3. If m's mediagroup attribute is being removed, then abort these steps.
if (group.isNull() || group.isEmpty())
@@ -3753,8 +3751,8 @@ void HTMLMediaElement::setMediaGroup(const AtomicString& group)
// 4. If there is another media element whose Document is the same as m's Document (even if one or both
// of these elements are not actually in the Document),
- HashSet<HTMLMediaElement*> elements = documentToElementSetMap().get(&document());
- for (HashSet<HTMLMediaElement*>::iterator i = elements.begin(); i != elements.end(); ++i) {
+ WeakMediaElementSet elements = documentToElementSetMap().get(&document());
+ for (WeakMediaElementSet::iterator i = elements.begin(); i != elements.end(); ++i) {
if (*i == this)
continue;
@@ -3776,7 +3774,7 @@ MediaController* HTMLMediaElement::controller() const
return m_mediaController.get();
}
-void HTMLMediaElement::setController(PassRefPtr<MediaController> controller)
+void HTMLMediaElement::setController(PassRefPtrWillBeRawPtr<MediaController> controller)
{
// 4.8.10.11.2 Media controllers: controller attribute.
// On setting, it must first remove the element's mediagroup attribute, if any,
@@ -3785,7 +3783,7 @@ void HTMLMediaElement::setController(PassRefPtr<MediaController> controller)
setControllerInternal(controller);
}
-void HTMLMediaElement::setControllerInternal(PassRefPtr<MediaController> controller)
+void HTMLMediaElement::setControllerInternal(PassRefPtrWillBeRawPtr<MediaController> controller)
{
if (m_mediaController)
m_mediaController->removeMediaElement(this);
@@ -3794,9 +3792,6 @@ void HTMLMediaElement::setControllerInternal(PassRefPtr<MediaController> control
if (m_mediaController)
m_mediaController->addMediaElement(this);
-
- if (hasMediaControls())
- mediaControls()->setMediaController(m_mediaController ? m_mediaController.get() : static_cast<MediaControllerInterface*>(this));
}
void HTMLMediaElement::updateMediaController()
@@ -3809,11 +3804,11 @@ bool HTMLMediaElement::isBlocked() const
{
// A media element is a blocked media element if its readyState attribute is in the
// HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA state,
+ // or if the element has paused for user interaction or paused for in-band content.
if (m_readyState <= HAVE_CURRENT_DATA)
return true;
- // or if the element has paused for user interaction.
- return pausedForUserInteraction();
+ return false;
}
bool HTMLMediaElement::isBlockedOnMediaController() const
@@ -3857,6 +3852,8 @@ void HTMLMediaElement::prepareMediaFragmentURI()
} else
m_fragmentEndTime = MediaPlayer::invalidTime();
+ // FIXME: Add support for selecting tracks by ID with the Media Fragments track dimension.
+
if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE_FUTURE_DATA)
prepareToPlay();
}
@@ -3865,22 +3862,19 @@ void HTMLMediaElement::applyMediaFragmentURI()
{
if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
m_sentEndEvent = false;
+ UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragmentStart);
seek(m_fragmentStartTime, IGNORE_EXCEPTION);
}
}
-MediaPlayerClient::CORSMode HTMLMediaElement::mediaPlayerCORSMode() const
+WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const
{
- if (!fastHasAttribute(crossoriginAttr))
- return Unspecified;
- if (equalIgnoringCase(fastGetAttribute(crossoriginAttr), "use-credentials"))
- return UseCredentials;
- return Anonymous;
-}
-
-void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
-{
- m_restrictions = NoRestrictions;
+ const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr);
+ if (crossOriginMode.isNull())
+ return WebMediaPlayer::CORSModeUnspecified;
+ if (equalIgnoringCase(crossOriginMode, "use-credentials"))
+ return WebMediaPlayer::CORSModeUseCredentials;
+ return WebMediaPlayer::CORSModeAnonymous;
}
void HTMLMediaElement::mediaPlayerSetWebLayer(blink::WebLayer* webLayer)
@@ -3890,22 +3884,19 @@ void HTMLMediaElement::mediaPlayerSetWebLayer(blink::WebLayer* webLayer)
// If either of the layers is null we need to enable or disable compositing. This is done by triggering a style recalc.
if (!m_webLayer || !webLayer)
- scheduleLayerUpdate();
+ setNeedsCompositingUpdate();
if (m_webLayer)
GraphicsLayer::unregisterContentsLayer(m_webLayer);
m_webLayer = webLayer;
if (m_webLayer) {
- m_webLayer->setOpaque(m_opaque);
GraphicsLayer::registerContentsLayer(m_webLayer);
}
}
-void HTMLMediaElement::mediaPlayerSetOpaque(bool opaque)
+void HTMLMediaElement::mediaPlayerMediaSourceOpened(blink::WebMediaSource* webMediaSource)
{
- m_opaque = opaque;
- if (m_webLayer)
- m_webLayer->setOpaque(m_opaque);
+ m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource));
}
bool HTMLMediaElement::isInteractiveContent() const
@@ -3913,4 +3904,67 @@ bool HTMLMediaElement::isInteractiveContent() const
return fastHasAttribute(controlsAttr);
}
+void HTMLMediaElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == EventTypeNames::focusin) {
+ if (hasMediaControls())
+ mediaControls()->mediaElementFocused();
+ }
+ HTMLElement::defaultEventHandler(event);
+}
+
+void HTMLMediaElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_asyncEventQueue);
+ visitor->trace(m_error);
+ visitor->trace(m_currentSourceNode);
+ visitor->trace(m_nextChildNodeToConsider);
+ visitor->trace(m_audioTracks);
+ visitor->trace(m_videoTracks);
+ visitor->trace(m_textTracks);
+ visitor->trace(m_textTracksWhenResourceSelectionBegan);
+ visitor->trace(m_mediaController);
+#if ENABLE(WEB_AUDIO)
+ visitor->registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakMembers>(this);
+#endif
+ WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor);
+ HTMLElement::trace(visitor);
+}
+
+void HTMLMediaElement::createPlaceholderTracksIfNecessary()
+{
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
+ return;
+
+ // Create a placeholder audio track if the player says it has audio but it didn't explicitly announce the tracks.
+ if (hasAudio() && !audioTracks().length())
+ addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, "Audio Track", "", true);
+
+ // Create a placeholder video track if the player says it has video but it didn't explicitly announce the tracks.
+ if (webMediaPlayer() && webMediaPlayer()->hasVideo() && !videoTracks().length())
+ addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, "Video Track", "", true);
+}
+
+void HTMLMediaElement::selectInitialTracksIfNecessary()
+{
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
+ return;
+
+ // Enable the first audio track if an audio track hasn't been enabled yet.
+ if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack())
+ audioTracks().anonymousIndexedGetter(0)->setEnabled(true);
+
+ // Select the first video track if a video track hasn't been selected yet.
+ if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1)
+ videoTracks().anonymousIndexedGetter(0)->setSelected(true);
+}
+
+#if ENABLE(WEB_AUDIO)
+void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
+{
+ if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider())
+ audioSourceProvider()->setClient(0);
+}
+#endif
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index 18374c781bb..5b2756e307c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -29,15 +29,16 @@
#include "core/dom/ActiveDOMObject.h"
#include "core/events/GenericEventQueue.h"
#include "core/html/HTMLElement.h"
-#include "core/html/MediaControllerInterface.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/TextTrackCue.h"
#include "core/html/track/vtt/VTTCue.h"
#include "platform/PODIntervalTree.h"
#include "platform/graphics/media/MediaPlayer.h"
+#include "public/platform/WebMediaPlayerClient.h"
#include "public/platform/WebMimeRegistry.h"
namespace blink {
+class WebContentDecryptionModule;
class WebInbandTextTrack;
class WebLayer;
}
@@ -46,8 +47,9 @@ namespace WebCore {
#if ENABLE(WEB_AUDIO)
class AudioSourceProvider;
-class MediaElementAudioSourceNode;
+class AudioSourceProviderClient;
#endif
+class AudioTrackList;
class ContentType;
class Event;
class ExceptionState;
@@ -57,10 +59,11 @@ class KURL;
class MediaController;
class MediaControls;
class MediaError;
-class MediaKeys;
class HTMLMediaSource;
class TextTrackList;
class TimeRanges;
+class URLRegistry;
+class VideoTrackList;
typedef PODIntervalTree<double, TextTrackCue*> CueIntervalTree;
typedef CueIntervalTree::IntervalType CueInterval;
@@ -70,20 +73,27 @@ typedef Vector<CueInterval> CueList;
// 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, public ActiveDOMObject, public MediaControllerInterface
- , private TextTrackClient
+class HTMLMediaElement : public HTMLElement, public WillBeHeapSupplementable<HTMLMediaElement>, public MediaPlayerClient, public ActiveDOMObject
{
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElement);
public:
static blink::WebMimeRegistry::SupportsType supportsType(const ContentType&, const String& keySystem = String());
- MediaPlayer* player() const { return m_player.get(); }
+ static void setMediaStreamRegistry(URLRegistry*);
+ static bool isMediaStreamURL(const String& url);
- virtual bool isVideo() const = 0;
- virtual bool hasVideo() const OVERRIDE { return false; }
- virtual bool hasAudio() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+#if ENABLE(WEB_AUDIO)
+ void clearWeakMembers(Visitor*);
+#endif
+
+ // Do not use player().
+ // FIXME: Replace all uses with webMediaPlayer() and remove this API.
+ MediaPlayer* player() const { return m_player.get(); }
+ blink::WebMediaPlayer* webMediaPlayer() const { return m_player ? m_player->webMediaPlayer() : 0; }
- // Eventually overloaded in HTMLVideoElement
- virtual bool supportsFullscreen() const OVERRIDE { return false; };
+ virtual bool hasVideo() const { return false; }
+ bool hasAudio() const;
bool supportsSave() const;
@@ -99,7 +109,7 @@ public:
bool isActive() const { return m_active; }
// error state
- PassRefPtr<MediaError> error() const;
+ PassRefPtrWillBeRawPtr<MediaError> error() const;
// network state
void setSrc(const AtomicString&);
@@ -109,13 +119,14 @@ public:
NetworkState networkState() const;
String preload() const;
- void setPreload(const String&);
+ void setPreload(const AtomicString&);
PassRefPtr<TimeRanges> buffered() const;
void load();
- String canPlayType(const String& mimeType, const String& keySystem = String(), const KURL& = KURL()) const;
+ String canPlayType(const String& mimeType, const String& keySystem = String()) const;
// ready state
+ enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
ReadyState readyState() const;
bool seeking() const;
@@ -144,22 +155,7 @@ public:
// media source extensions
void closeMediaSource();
- void durationChanged(double duration);
-
- // encrypted media extensions
- void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState&);
- void webkitGenerateKeyRequest(const String& keySystem, ExceptionState&);
- void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState&);
- void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState&);
- void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState&);
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
-
- MediaKeys* mediaKeys() const { return m_mediaKeys.get(); }
- void setMediaKeys(MediaKeys*);
+ void durationChanged(double duration, bool requestSeek);
// controls
bool controls() const;
@@ -169,47 +165,61 @@ public:
bool muted() const;
void setMuted(bool);
+ // play/pause toggling that uses the media controller if present. togglePlayStateWillPlay() is
+ // true if togglePlayState() will call play() or unpause() on the media element or controller.
+ bool togglePlayStateWillPlay() const;
void togglePlayState();
- void beginScrubbing();
- void endScrubbing();
- bool canPlay() const;
+ AudioTrackList& audioTracks();
+ void audioTrackChanged();
- double percentLoaded() const;
+ VideoTrackList& videoTracks();
+ void selectedVideoTrackChanged(blink::WebMediaPlayer::TrackId*);
- PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionState&);
- PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, ExceptionState& exceptionState) { return addTextTrack(kind, label, emptyString(), exceptionState); }
- PassRefPtr<TextTrack> addTextTrack(const String& kind, ExceptionState& exceptionState) { return addTextTrack(kind, emptyString(), emptyString(), exceptionState); }
+ PassRefPtrWillBeRawPtr<TextTrack> addTextTrack(const AtomicString& kind, const AtomicString& label, const AtomicString& language, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TextTrack> addTextTrack(const AtomicString& kind, const AtomicString& label, ExceptionState& exceptionState) { return addTextTrack(kind, label, emptyAtom, exceptionState); }
+ PassRefPtrWillBeRawPtr<TextTrack> addTextTrack(const AtomicString& kind, ExceptionState& exceptionState) { return addTextTrack(kind, emptyAtom, emptyAtom, exceptionState); }
TextTrackList* textTracks();
CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
- void addTrack(TextTrack*);
- void removeTrack(TextTrack*);
- void removeAllInbandTracks();
+ void addTextTrack(TextTrack*);
+ void removeTextTrack(TextTrack*);
void closeCaptionTracksChanged();
void notifyMediaPlayerOfTextTrackChanges();
- void didAddTrack(HTMLTrackElement*);
- void didRemoveTrack(HTMLTrackElement*);
+ // Implements the "forget the media element's media-resource-specific tracks" algorithm in the HTML5 spec.
+ void forgetResourceSpecificTracks();
+
+ void didAddTrackElement(HTMLTrackElement*);
+ void didRemoveTrackElement(HTMLTrackElement*);
+
+ blink::WebMediaPlayer::TrackId addAudioTrack(const String& id, blink::WebMediaPlayerClient::AudioTrackKind, const AtomicString& label, const AtomicString& language, bool enabled);
+ void removeAudioTrack(blink::WebMediaPlayer::TrackId);
+ blink::WebMediaPlayer::TrackId addVideoTrack(const String& id, blink::WebMediaPlayerClient::VideoTrackKind, const AtomicString& label, const AtomicString& language, bool selected);
+ void removeVideoTrack(blink::WebMediaPlayer::TrackId);
- virtual void mediaPlayerDidAddTrack(blink::WebInbandTextTrack*) OVERRIDE;
- virtual void mediaPlayerDidRemoveTrack(blink::WebInbandTextTrack*) OVERRIDE;
+ virtual void mediaPlayerDidAddTextTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
+ virtual void mediaPlayerDidRemoveTextTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
+ // FIXME: Remove this when WebMediaPlayerClientImpl::loadInternal does not depend on it.
+ virtual KURL mediaPlayerPosterURL() OVERRIDE { return KURL(); }
- struct TrackGroup {
+ class TrackGroup {
+ STACK_ALLOCATED();
+ public:
enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
- TrackGroup(GroupKind kind)
- : visibleTrack(0)
- , defaultTrack(0)
+ explicit TrackGroup(GroupKind kind)
+ : visibleTrack(nullptr)
+ , defaultTrack(nullptr)
, kind(kind)
, hasSrcLang(false)
{
}
- Vector<RefPtr<TextTrack> > tracks;
- RefPtr<TextTrack> visibleTrack;
- RefPtr<TextTrack> defaultTrack;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > tracks;
+ RefPtrWillBeMember<TextTrack> visibleTrack;
+ RefPtrWillBeMember<TextTrack> defaultTrack;
GroupKind kind;
bool hasSrcLang;
};
@@ -227,20 +237,19 @@ public:
void updateTextTrackDisplay();
void textTrackReadyStateChanged(TextTrack*);
- // TextTrackClient
- virtual void textTrackKindChanged(TextTrack*) OVERRIDE;
- virtual void textTrackModeChanged(TextTrack*) OVERRIDE;
- virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
- virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
+ void textTrackKindChanged(TextTrack*);
+ void textTrackModeChanged(TextTrack*);
+ void textTrackAddCues(TextTrack*, const TextTrackCueList*);
+ void textTrackRemoveCues(TextTrack*, const TextTrackCueList*);
+ void textTrackAddCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue>);
+ void textTrackRemoveCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue>);
// EventTarget function.
// Both Node (via HTMLElement) and ActiveDOMObject define this method, which
// causes an ambiguity error at compile time. This class's constructor
// ensures that both implementations return document, so return the result
// of one of them here.
- virtual ExecutionContext* executionContext() const OVERRIDE { return HTMLElement::executionContext(); }
+ using HTMLElement::executionContext;
bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
@@ -260,12 +269,12 @@ public:
bool isPlaying() const { return m_playing; }
// ActiveDOMObject functions.
- virtual bool hasPendingActivity() const OVERRIDE;
- virtual void contextDestroyed() OVERRIDE;
+ virtual bool hasPendingActivity() const OVERRIDE FINAL;
+ virtual void contextDestroyed() OVERRIDE FINAL;
#if ENABLE(WEB_AUDIO)
- MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
- void setAudioSourceNode(MediaElementAudioSourceNode*);
+ AudioSourceProviderClient* audioSourceNode() { return m_audioSourceNode; }
+ void setAudioSourceNode(AudioSourceProviderClient*);
AudioSourceProvider* audioSourceProvider();
#endif
@@ -274,44 +283,34 @@ public:
bool isSafeToLoadURL(const KURL&, InvalidURLAction);
MediaController* controller() const;
- void setController(PassRefPtr<MediaController>); // Resets the MediaGroup and sets the MediaController.
+ void setController(PassRefPtrWillBeRawPtr<MediaController>); // Resets the MediaGroup and sets the MediaController.
+
+ void scheduleEvent(PassRefPtrWillBeRawPtr<Event>);
+
+ // Current volume that should be used by the webMediaPlayer(). This method takes muted state
+ // and m_mediaController multipliers into account.
+ double playerVolume() const;
+
+#if ENABLE(OILPAN)
+ bool isFinalizing() const { return m_isFinalizing; }
+#endif
protected:
- HTMLMediaElement(const QualifiedName&, Document&, bool);
+ HTMLMediaElement(const QualifiedName&, Document&);
virtual ~HTMLMediaElement();
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void finishParsingChildren() OVERRIDE;
+ virtual void finishParsingChildren() OVERRIDE FINAL;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
- enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
+ enum DisplayMode { Unknown, Poster, PosterWaitingForVideo, Video };
DisplayMode displayMode() const { return m_displayMode; }
virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
- virtual bool isMediaElement() const OVERRIDE { return true; }
-
- void setControllerInternal(PassRefPtr<MediaController>);
-
- // Restrictions to change default behaviors.
- enum BehaviorRestrictionFlags {
- NoRestrictions = 0,
- RequireUserGestureForLoadRestriction = 1 << 0,
- RequireUserGestureForRateChangeRestriction = 1 << 1,
- RequireUserGestureForFullscreenRestriction = 1 << 2,
- RequirePageConsentToLoadMediaRestriction = 1 << 3,
- };
- typedef unsigned BehaviorRestrictions;
-
- bool userGestureRequiredForLoad() const { return m_restrictions & RequireUserGestureForLoadRestriction; }
- bool userGestureRequiredForRateChange() const { return m_restrictions & RequireUserGestureForRateChangeRestriction; }
- bool userGestureRequiredForFullscreen() const { return m_restrictions & RequireUserGestureForFullscreenRestriction; }
- bool pageConsentRequiredForLoad() const { return m_restrictions & RequirePageConsentToLoadMediaRestriction; }
-
- void addBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions |= restriction; }
- void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
+ void setControllerInternal(PassRefPtrWillBeRawPtr<MediaController>);
bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0; }
void beginIgnoringTrackDisplayUpdateRequests();
@@ -320,51 +319,42 @@ protected:
private:
void createMediaPlayer();
- virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return true; }
- virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
+ virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE FINAL { return true; }
+ virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; }
- virtual bool hasCustomFocusLogic() const OVERRIDE;
- virtual bool supportsFocus() const OVERRIDE;
- virtual bool isMouseFocusable() const OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE FINAL;
+ virtual bool isMouseFocusable() const OVERRIDE FINAL;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
- virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE FINAL;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
+ virtual void removedFrom(ContainerNode*) OVERRIDE FINAL;
+ virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE FINAL;
- virtual void didBecomeFullscreenElement() OVERRIDE;
- virtual void willStopBeingFullscreenElement() OVERRIDE;
- virtual bool isInteractiveContent() const OVERRIDE;
+ virtual void didBecomeFullscreenElement() OVERRIDE FINAL;
+ virtual void willStopBeingFullscreenElement() OVERRIDE FINAL;
+ virtual bool isInteractiveContent() const OVERRIDE FINAL;
+ virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
// ActiveDOMObject functions.
- virtual void stop() OVERRIDE;
+ virtual void stop() OVERRIDE FINAL;
virtual void updateDisplayState() { }
- void setReadyState(MediaPlayer::ReadyState);
+ void setReadyState(ReadyState);
void setNetworkState(MediaPlayer::NetworkState);
- virtual void mediaPlayerNetworkStateChanged() OVERRIDE;
- virtual void mediaPlayerReadyStateChanged() OVERRIDE;
- virtual void mediaPlayerTimeChanged() OVERRIDE;
- virtual void mediaPlayerDurationChanged() OVERRIDE;
- virtual void mediaPlayerPlaybackStateChanged() OVERRIDE;
- virtual void mediaPlayerRequestFullscreen() OVERRIDE;
- virtual void mediaPlayerRequestSeek(double) OVERRIDE;
- virtual void mediaPlayerRepaint() OVERRIDE;
- virtual void mediaPlayerSizeChanged() OVERRIDE;
-
- virtual void mediaPlayerKeyAdded(const String& keySystem, const String& sessionId) OVERRIDE;
- virtual void mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) OVERRIDE;
- virtual void mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL) OVERRIDE;
- virtual bool mediaPlayerKeyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) OVERRIDE;
- virtual bool mediaPlayerKeyNeeded(Uint8Array*) OVERRIDE;
-
- virtual CORSMode mediaPlayerCORSMode() const OVERRIDE;
-
- virtual void mediaPlayerSetWebLayer(blink::WebLayer*) OVERRIDE;
- virtual void mediaPlayerSetOpaque(bool) OVERRIDE;
+ virtual void mediaPlayerNetworkStateChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerReadyStateChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerTimeChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerDurationChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerPlaybackStateChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerRequestFullscreen() OVERRIDE FINAL;
+ virtual void mediaPlayerRequestSeek(double) OVERRIDE FINAL;
+ virtual void mediaPlayerRepaint() OVERRIDE FINAL;
+ virtual void mediaPlayerSizeChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerSetWebLayer(blink::WebLayer*) OVERRIDE FINAL;
+ virtual void mediaPlayerMediaSourceOpened(blink::WebMediaSource*) OVERRIDE FINAL;
void loadTimerFired(Timer<HTMLMediaElement>*);
void progressEventTimerFired(Timer<HTMLMediaElement>*);
@@ -379,19 +369,24 @@ private:
void addPlayedRange(double start, double end);
void scheduleTimeupdateEvent(bool periodicEvent);
- void scheduleEvent(const AtomicString& eventName);
+ void scheduleEvent(const AtomicString& eventName); // FIXME: Rename to scheduleNamedEvent for clarity.
// loading
+ void prepareForLoad();
+ void loadInternal();
void selectMediaResource();
void loadResource(const KURL&, ContentType&, const String& keySystem);
+ void startPlayerLoad();
+ void setPlayerPreload();
+ blink::WebMediaPlayer::LoadType loadType() const;
void scheduleNextSourceChild();
void loadNextSourceChild();
void userCancelledLoad();
void clearMediaPlayer(int flags);
- void clearMediaPlayerAndAudioSourceProviderClient();
+ void clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
bool havePotentialSourceChild();
void noneSupported();
- void mediaEngineError(PassRefPtr<MediaError> err);
+ void mediaEngineError(PassRefPtrWillBeRawPtr<MediaError>);
void cancelPendingEventsAndCallbacks();
void waitForSourceChange();
void prepareToPlay();
@@ -400,17 +395,22 @@ private:
void mediaLoadingFailed(MediaPlayer::NetworkState);
+ // deferred loading (preload=none)
+ bool loadIsDeferred() const;
+ void deferLoad();
+ void cancelDeferredLoad();
+ void startDeferredLoad();
+ void executeDeferredLoad();
+ void deferredLoadTimerFired(Timer<HTMLMediaElement>*);
+
void updateActiveTextTrackCues(double);
HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
void markCaptionAndSubtitleTracksAsUnconfigured();
- // These "internal" functions do not check user gesture restrictions.
- void loadInternal();
+ // This does not check user gesture restrictions.
void playInternal();
- void pauseInternal();
- void prepareForLoad();
void allowVideoRendering();
void updateVolume();
@@ -418,14 +418,11 @@ private:
bool potentiallyPlaying() const;
bool endedPlayback() const;
bool stoppedDueToErrors() const;
- bool pausedForUserInteraction() const;
bool couldPlayIfEnoughData() const;
// Pauses playback without changing any states or generating events
void setPausedInternal(bool);
- void setPlaybackRateInternal(double);
-
void setShouldDelayLoadEvent(bool);
void invalidateCachedTime();
void refreshCachedTime() const;
@@ -437,25 +434,44 @@ private:
void prepareMediaFragmentURI();
void applyMediaFragmentURI();
- virtual void* preDispatchEventHandler(Event*) OVERRIDE;
+ virtual void* preDispatchEventHandler(Event*) OVERRIDE FINAL;
void changeNetworkStateFromLoadingToIdle();
- void removeBehaviorsRestrictionsAfterFirstUserGesture();
-
const AtomicString& mediaGroup() const;
void setMediaGroup(const AtomicString&);
void updateMediaController();
bool isBlocked() const;
bool isBlockedOnMediaController() const;
- bool hasCurrentSrc() const { return !m_currentSrc.isEmpty(); }
bool isAutoplaying() const { return m_autoplaying; }
+ blink::WebMediaPlayer::CORSMode corsMode() const;
+
+ // Returns the "direction of playback" value as specified in the HTML5 spec.
+ enum DirectionOfPlayback { Backward, Forward };
+ DirectionOfPlayback directionOfPlayback() const;
+
+ // Returns the "effective playback rate" value as specified in the HTML5 spec.
+ double effectivePlaybackRate() const;
+
+ // Creates placeholder AudioTrack and/or VideoTrack objects when WebMemediaPlayer objects
+ // advertise they have audio and/or video, but don't explicitly signal them via
+ // addAudioTrack() and addVideoTrack().
+ // FIXME: Remove this once all WebMediaPlayer implementations properly report their track info.
+ void createPlaceholderTracksIfNecessary();
+
+ // Sets the selected/enabled tracks if they aren't set before we initially
+ // transition to HAVE_METADATA.
+ void selectInitialTracksIfNecessary();
+
+ void audioTracksTimerFired(Timer<HTMLMediaElement>*);
+
Timer<HTMLMediaElement> m_loadTimer;
Timer<HTMLMediaElement> m_progressEventTimer;
Timer<HTMLMediaElement> m_playbackProgressTimer;
+ Timer<HTMLMediaElement> m_audioTracksTimer;
RefPtr<TimeRanges> m_playedTimeRanges;
- OwnPtr<GenericEventQueue> m_asyncEventQueue;
+ OwnPtrWillBeMember<GenericEventQueue> m_asyncEventQueue;
double m_playbackRate;
double m_defaultPlaybackRate;
@@ -464,12 +480,11 @@ private:
ReadyState m_readyStateMaximum;
KURL m_currentSrc;
- RefPtr<MediaError> m_error;
+ RefPtrWillBeMember<MediaError> m_error;
double m_volume;
double m_lastSeekTime;
- unsigned m_previousProgress;
double m_previousProgressTime;
// Cached duration to suppress duplicate events if duration unchanged.
@@ -484,14 +499,27 @@ private:
// Loading state.
enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
LoadState m_loadState;
- RefPtr<HTMLSourceElement> m_currentSourceNode;
- RefPtr<Node> m_nextChildNodeToConsider;
+ RefPtrWillBeMember<HTMLSourceElement> m_currentSourceNode;
+ RefPtrWillBeMember<Node> m_nextChildNodeToConsider;
+
+ // "Deferred loading" state (for preload=none).
+ enum DeferredLoadState {
+ // The load is not deferred.
+ NotDeferred,
+ // The load is deferred, and waiting for the task to set the
+ // delaying-the-load-event flag (to false).
+ WaitingForStopDelayingLoadEventTask,
+ // The load is the deferred, and waiting for a triggering event.
+ WaitingForTrigger,
+ // The load is deferred, and waiting for the task to set the
+ // delaying-the-load-event flag, after which the load will be executed.
+ ExecuteOnStopDelayingLoadEventTask
+ };
+ DeferredLoadState m_deferredLoadState;
+ Timer<HTMLMediaElement> m_deferredLoadTimer;
OwnPtr<MediaPlayer> m_player;
blink::WebLayer* m_webLayer;
- bool m_opaque;
-
- BehaviorRestrictions m_restrictions;
MediaPlayer::Preload m_preload;
@@ -510,6 +538,7 @@ private:
PendingActionFlags m_pendingActionFlags;
// FIXME: MediaElement has way too many state bits.
+ bool m_userGestureRequiredForPlay : 1;
bool m_playing : 1;
bool m_shouldDelayLoadEvent : 1;
bool m_haveFiredLoadedData : 1;
@@ -529,18 +558,22 @@ private:
bool m_closedCaptionsVisible : 1;
- bool m_loadInitiatedByUserGesture : 1;
bool m_completelyLoaded : 1;
bool m_havePreparedToPlay : 1;
- bool m_parsingInProgress : 1;
+ bool m_delayingLoadForPreloadNone : 1;
bool m_tracksAreReady : 1;
bool m_haveVisibleTextTrack : 1;
bool m_processingPreferenceChange : 1;
+#if ENABLE(OILPAN)
+ bool m_isFinalizing : 1;
+#endif
double m_lastTextTrackUpdateTime;
- RefPtr<TextTrackList> m_textTracks;
- Vector<RefPtr<TextTrack> > m_textTracksWhenResourceSelectionBegan;
+ RefPtrWillBeMember<AudioTrackList> m_audioTracks;
+ RefPtrWillBeMember<VideoTrackList> m_videoTracks;
+ RefPtrWillBeMember<TextTrackList> m_textTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_textTracksWhenResourceSelectionBegan;
CueIntervalTree m_cueTree;
@@ -549,17 +582,17 @@ private:
#if ENABLE(WEB_AUDIO)
// This is a weak reference, since m_audioSourceNode holds a reference to us.
- // The value is set just after the MediaElementAudioSourceNode is created.
- // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
- MediaElementAudioSourceNode* m_audioSourceNode;
+ // FIXME: Oilpan: Consider making this a strongly traced pointer with oilpan where strong cycles are not a problem.
+ RawPtrWillBeWeakMember<AudioSourceProviderClient> m_audioSourceNode;
#endif
friend class MediaController;
- RefPtr<MediaController> m_mediaController;
+ RefPtrWillBeMember<MediaController> m_mediaController;
+ friend class Internals;
friend class TrackDisplayUpdateScope;
- RefPtr<MediaKeys> m_mediaKeys;
+ static URLRegistry* s_mediaStreamRegistry;
};
#ifndef NDEBUG
@@ -581,17 +614,17 @@ struct ValueToString<TextTrackCue*> {
};
#endif
-inline bool isHTMLMediaElement(Node* node)
+inline bool isHTMLMediaElement(const Element& element)
{
- return node && node->isElementNode() && toElement(node)->isMediaElement();
+ return isHTMLAudioElement(element) || isHTMLVideoElement(element);
}
-inline bool isHTMLMediaElement(const Node& node)
+inline bool isHTMLMediaElement(const HTMLElement& element)
{
- return node.isElementNode() && toElement(node).isMediaElement();
+ return isHTMLAudioElement(element) || isHTMLVideoElement(element);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl
index a4dbf6fdf6d..3d87a591ba3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl
@@ -24,17 +24,18 @@
*/
[
+ ActiveDOMObject,
RuntimeEnabled=Media,
- ActiveDOMObject
+ TypeChecking=Unrestricted,
] interface HTMLMediaElement : HTMLElement {
// error state
- readonly attribute MediaError error;
+ [TypeChecking=Interface|Nullable] readonly attribute MediaError? error;
// network state
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
- [URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] readonly attribute DOMString currentSrc;
- [Reflect] attribute DOMString crossOrigin;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
+ [URL, LogActivity=SetterOnly] readonly attribute DOMString currentSrc;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
@@ -45,7 +46,7 @@
readonly attribute TimeRanges buffered;
void load();
- DOMString canPlayType([Default=Undefined] optional DOMString type, [Default=Undefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString keySystem);
+ DOMString canPlayType(DOMString type, [Default=Undefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString keySystem);
// ready state
const unsigned short HAVE_NOTHING = 0;
@@ -58,7 +59,7 @@
// playback state
[RaisesException=Setter] attribute double currentTime;
- readonly attribute double duration;
+ readonly attribute unrestricted double duration;
readonly attribute boolean paused;
attribute double defaultPlaybackRate;
attribute double playbackRate;
@@ -71,8 +72,8 @@
void pause();
// media controller
- [Reflect] attribute DOMString mediaGroup;
- [StrictTypeChecking] attribute MediaController controller;
+ [RuntimeEnabled=MediaController, Reflect] attribute DOMString mediaGroup;
+ [RuntimeEnabled=MediaController, TypeChecking=Interface|Nullable] attribute MediaController? controller;
// controls
attribute boolean controls;
@@ -81,8 +82,10 @@
[Reflect=muted] attribute boolean defaultMuted;
// tracks
- [RuntimeEnabled=VideoTrack] readonly attribute TextTrackList textTracks;
- [RuntimeEnabled=VideoTrack, RaisesException] TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
+ [RuntimeEnabled=AudioVideoTracks] readonly attribute AudioTrackList audioTracks;
+ [RuntimeEnabled=AudioVideoTracks] readonly attribute VideoTrackList videoTracks;
+ readonly attribute TextTrackList textTracks;
+ [RaisesException] TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
// WebKit extensions
@@ -90,15 +93,5 @@
[MeasureAs=PrefixedAudioDecodedByteCount] readonly attribute unsigned long webkitAudioDecodedByteCount;
[MeasureAs=PrefixedVideoDecodedByteCount] readonly attribute unsigned long webkitVideoDecodedByteCount;
- // FIXME: add DeprecateAs=PrefixedMediaGenerateKeyRequest when MediaKeys is ready.
- [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException] void webkitGenerateKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, optional Uint8Array initData);
- [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException] void webkitAddKey([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, Uint8Array key, optional Uint8Array initData, [Default=NullString] optional DOMString sessionId);
- [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException] void webkitCancelKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, [Default=NullString] optional DOMString sessionId);
-
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeyadded;
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeyerror;
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeymessage;
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitneedkey;
-
- [RuntimeEnabled=EncryptedMedia] attribute MediaKeys mediaKeys;
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h b/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h
index f40206ce094..14baccb8e49 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h
@@ -31,7 +31,6 @@
#ifndef HTMLMediaSource_h
#define HTMLMediaSource_h
-#include "core/html/HTMLMediaElement.h"
#include "core/html/URLRegistry.h"
#include "wtf/Forward.h"
@@ -41,6 +40,7 @@ class WebMediaSource;
namespace WebCore {
+class HTMLMediaElement;
class TimeRanges;
class HTMLMediaSource : public URLRegistrable {
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp
index 2783c047b6a..5643bc146a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLMenuElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,9 +35,6 @@ inline HTMLMenuElement::HTMLMenuElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMenuElement> HTMLMenuElement::create(Document& document)
-{
- return adoptRef(new HTMLMenuElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLMenuElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h
index b1fdab64b05..4df4c6d101c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLMenuElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLMenuElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLMenuElement);
private:
explicit HTMLMenuElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp
index 02060a45742..78505207eb5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp
@@ -23,9 +23,12 @@
#include "config.h"
#include "core/html/HTMLMetaElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -51,10 +54,7 @@ inline HTMLMetaElement::HTMLMetaElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(Document& document)
-{
- return adoptRef(new HTMLMetaElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLMetaElement)
static bool isInvalidSeparator(UChar c)
{
@@ -72,13 +72,12 @@ void HTMLMetaElement::parseContentAttribute(const String& content, KeyValuePairC
bool error = false;
// Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
- int keyBegin, keyEnd;
- int valueBegin, valueEnd;
+ unsigned keyBegin, keyEnd;
+ unsigned valueBegin, valueEnd;
- int i = 0;
- int length = content.length();
String buffer = content.lower();
- while (i < length) {
+ unsigned length = buffer.length();
+ for (unsigned i = 0; i < length; /* no increment here */) {
// skip to first non-separator, but don't skip past the end of the string
while (isSeparator(buffer[i])) {
if (i >= length)
@@ -90,6 +89,8 @@ void HTMLMetaElement::parseContentAttribute(const String& content, KeyValuePairC
// skip to first separator
while (!isSeparator(buffer[i])) {
error |= isInvalidSeparator(buffer[i]);
+ if (i >= length)
+ break;
i++;
}
keyEnd = i;
@@ -113,6 +114,8 @@ void HTMLMetaElement::parseContentAttribute(const String& content, KeyValuePairC
// skip to first separator
while (!isSeparator(buffer[i])) {
error |= isInvalidSeparator(buffer[i]);
+ if (i >= length)
+ break;
i++;
}
valueEnd = i;
@@ -177,10 +180,10 @@ Length HTMLMetaElement::parseViewportValueAsLength(const String& keyString, cons
DEFINE_ARRAY_FOR_MATCHING(characters, valueString, 13);
SWITCH(characters, length) {
CASE("device-width") {
- return Length(100, ViewportPercentageWidth);
+ return Length(DeviceWidth);
}
CASE("device-height") {
- return Length(100, ViewportPercentageHeight);
+ return Length(DeviceHeight);
}
}
@@ -192,7 +195,7 @@ Length HTMLMetaElement::parseViewportValueAsLength(const String& keyString, cons
return Length(clampLengthValue(value), Fixed);
}
-float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const String& valueString)
+float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const String& valueString, bool& computedValueMatchesParsedValue)
{
// 1) Non-negative number values are translated to <number> values.
// 2) Negative number values are translated to auto.
@@ -200,6 +203,7 @@ float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const S
// 4) device-width and device-height are translated to 10.0.
// 5) no and unknown values are translated to 0.0
+ computedValueMatchesParsedValue = false;
unsigned length = valueString.length();
DEFINE_ARRAY_FOR_MATCHING(characters, valueString, 13);
SWITCH(characters, length) {
@@ -228,37 +232,44 @@ float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const S
if (!value && document().settings() && document().settings()->viewportMetaZeroValuesQuirk())
return ViewportDescription::ValueAuto;
- return clampScaleValue(value);
+ float clampedValue = clampScaleValue(value);
+ if (clampedValue == value)
+ computedValueMatchesParsedValue = true;
+
+ return clampedValue;
}
-float HTMLMetaElement::parseViewportValueAsUserZoom(const String& keyString, const String& valueString)
+bool HTMLMetaElement::parseViewportValueAsUserZoom(const String& keyString, const String& valueString, bool& computedValueMatchesParsedValue)
{
// yes and no are used as keywords.
// Numbers >= 1, numbers <= -1, device-width and device-height are mapped to yes.
// Numbers in the range <-1, 1>, and unknown values, are mapped to no.
+ computedValueMatchesParsedValue = false;
unsigned length = valueString.length();
DEFINE_ARRAY_FOR_MATCHING(characters, valueString, 13);
SWITCH(characters, length) {
CASE("yes") {
- return 1;
+ computedValueMatchesParsedValue = true;
+ return true;
}
CASE("no") {
- return 0;
+ computedValueMatchesParsedValue = true;
+ return false;
}
CASE("device-width") {
- return 1;
+ return true;
}
CASE("device-height") {
- return 1;
+ return true;
}
}
float value = parsePositiveNumber(keyString, valueString);
if (fabs(value) < 1)
- return 0;
+ return false;
- return 1;
+ return true;
}
float HTMLMetaElement::parseViewportValueAsDPI(const String& keyString, const String& valueString)
@@ -313,19 +324,19 @@ void HTMLMetaElement::processViewportKeyValuePair(const String& keyString, const
return;
}
CASE("initial-scale") {
- description->zoom = parseViewportValueAsZoom(keyString, valueString);
+ description->zoom = parseViewportValueAsZoom(keyString, valueString, description->zoomIsExplicit);
return;
}
CASE("minimum-scale") {
- description->minZoom = parseViewportValueAsZoom(keyString, valueString);
+ description->minZoom = parseViewportValueAsZoom(keyString, valueString, description->minZoomIsExplicit);
return;
}
CASE("maximum-scale") {
- description->maxZoom = parseViewportValueAsZoom(keyString, valueString);
+ description->maxZoom = parseViewportValueAsZoom(keyString, valueString, description->maxZoomIsExplicit);
return;
}
CASE("user-scalable") {
- description->userZoom = parseViewportValueAsUserZoom(keyString, valueString);
+ description->userZoom = parseViewportValueAsUserZoom(keyString, valueString, description->userZoomIsExplicit);
return;
}
CASE("target-densitydpi") {
@@ -333,6 +344,10 @@ void HTMLMetaElement::processViewportKeyValuePair(const String& keyString, const
reportViewportWarning(TargetDensityDpiUnsupported, String(), String());
return;
}
+ CASE("minimal-ui") {
+ // Ignore vendor-specific argument.
+ return;
+ }
}
reportViewportWarning(UnrecognizedViewportArgumentKeyError, keyString, String());
}
@@ -355,11 +370,10 @@ static MessageLevel viewportErrorMessageLevel(ViewportErrorCode errorCode)
switch (errorCode) {
case TruncatedViewportArgumentValueError:
case TargetDensityDpiUnsupported:
- return WarningMessageLevel;
case UnrecognizedViewportArgumentKeyError:
case UnrecognizedViewportArgumentValueError:
case MaximumScaleTooLargeError:
- return ErrorMessageLevel;
+ return WarningMessageLevel;
}
ASSERT_NOT_REACHED();
@@ -385,9 +399,6 @@ void HTMLMetaElement::processViewportContentAttribute(const String& content, Vie
{
ASSERT(!content.isNull());
- if (!document().settings())
- return;
-
if (!document().shouldOverrideLegacyDescription(origin))
return;
@@ -405,18 +416,6 @@ void HTMLMetaElement::processViewportContentAttribute(const String& content, Vie
descriptionFromLegacyTag.minZoom = std::min(descriptionFromLegacyTag.minZoom, float(5));
}
- const Settings* settings = document().settings();
-
- if (descriptionFromLegacyTag.maxWidth.isAuto()) {
- if (descriptionFromLegacyTag.zoom == ViewportDescription::ValueAuto) {
- descriptionFromLegacyTag.minWidth = Length(ExtendToZoom);
- descriptionFromLegacyTag.maxWidth = Length(settings->layoutFallbackWidth(), Fixed);
- } else if (descriptionFromLegacyTag.maxHeight.isAuto()) {
- descriptionFromLegacyTag.minWidth = Length(ExtendToZoom);
- descriptionFromLegacyTag.maxWidth = Length(ExtendToZoom);
- }
- }
-
document().setViewportDescription(descriptionFromLegacyTag);
}
@@ -435,9 +434,24 @@ void HTMLMetaElement::parseAttribute(const QualifiedName& name, const AtomicStri
Node::InsertionNotificationRequest HTMLMetaElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument())
- process();
- return InsertionDone;
+ return InsertionShouldCallDidNotifySubtreeInsertions;
+}
+
+void HTMLMetaElement::didNotifySubtreeInsertionsToDocument()
+{
+ process();
+}
+
+static bool inDocumentHead(HTMLMetaElement* element)
+{
+ if (!element->inDocument())
+ return false;
+
+ for (Element* current = element; current; current = current->parentElement()) {
+ if (isHTMLHeadElement(*current))
+ return true;
+ }
+ return false;
}
void HTMLMetaElement::process()
@@ -451,24 +465,26 @@ void HTMLMetaElement::process()
return;
const AtomicString& nameValue = fastGetAttribute(nameAttr);
- if (nameValue.isNull()) {
- // 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).
- const AtomicString& httpEquivValue = fastGetAttribute(http_equivAttr);
- if (!httpEquivValue.isNull())
- document().processHttpEquiv(httpEquivValue, contentValue);
- return;
+ if (!nameValue.isEmpty()) {
+ if (equalIgnoringCase(nameValue, "viewport"))
+ processViewportContentAttribute(contentValue, ViewportDescription::ViewportMeta);
+ else if (equalIgnoringCase(nameValue, "referrer"))
+ document().processReferrerPolicy(contentValue);
+ else if (equalIgnoringCase(nameValue, "handheldfriendly") && equalIgnoringCase(contentValue, "true"))
+ processViewportContentAttribute("width=device-width", ViewportDescription::HandheldFriendlyMeta);
+ else if (equalIgnoringCase(nameValue, "mobileoptimized"))
+ processViewportContentAttribute("width=device-width, initial-scale=1", ViewportDescription::MobileOptimizedMeta);
+ else if (RuntimeEnabledFeatures::themeColorEnabled() && equalIgnoringCase(nameValue, "theme-color") && document().frame())
+ document().frame()->loader().client()->dispatchDidChangeThemeColor();
}
- if (equalIgnoringCase(nameValue, "viewport"))
- processViewportContentAttribute(contentValue, ViewportDescription::ViewportMeta);
- else if (equalIgnoringCase(nameValue, "referrer"))
- document().processReferrerPolicy(contentValue);
- else if (equalIgnoringCase(nameValue, "handheldfriendly") && equalIgnoringCase(contentValue, "true"))
- processViewportContentAttribute("width=device-width", ViewportDescription::HandheldFriendlyMeta);
- else if (equalIgnoringCase(nameValue, "mobileoptimized"))
- processViewportContentAttribute("width=device-width, initial-scale=1", ViewportDescription::MobileOptimizedMeta);
+ // 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).
+
+ const AtomicString& httpEquivValue = fastGetAttribute(http_equivAttr);
+ if (!httpEquivValue.isEmpty())
+ document().processHttpEquiv(httpEquivValue, contentValue, inDocumentHead(this));
}
const AtomicString& HTMLMetaElement::content() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h
index c859a33c744..ccdeffbc96c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h
@@ -23,6 +23,7 @@
#ifndef HTMLMetaElement_h
#define HTMLMetaElement_h
+#include "core/dom/ViewportDescription.h"
#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -37,7 +38,7 @@ enum ViewportErrorCode {
class HTMLMetaElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLMetaElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLMetaElement);
const AtomicString& content() const;
const AtomicString& httpEquiv() const;
@@ -52,12 +53,13 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
float parsePositiveNumber(const String& key, const String& value, bool* ok = 0);
Length parseViewportValueAsLength(const String& key, const String& value);
- float parseViewportValueAsZoom(const String& key, const String& value);
- float parseViewportValueAsUserZoom(const String& key, const String& value);
+ float parseViewportValueAsZoom(const String& key, const String& value, bool& computedValueMatchesParsedValue);
+ bool parseViewportValueAsUserZoom(const String& key, const String& value, bool& computedValueMatchesParsedValue);
float parseViewportValueAsDPI(const String& key, const String& value);
void reportViewportWarning(ViewportErrorCode, const String& replacement1, const String& replacement2);
@@ -66,8 +68,6 @@ private:
void processViewportContentAttribute(const String& content, ViewportDescription::Type origin);
};
-DEFINE_NODE_TYPE_CASTS(HTMLMetaElement, hasTagName(HTMLNames::metaTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
index 41e536d9944..f745a7aeaa3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
@@ -22,10 +22,10 @@
#include "core/html/HTMLMeterElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -47,11 +47,11 @@ HTMLMeterElement::~HTMLMeterElement()
{
}
-PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLMeterElement> HTMLMeterElement::create(Document& document)
{
- RefPtr<HTMLMeterElement> meter = adoptRef(new HTMLMeterElement(document));
+ RefPtrWillBeRawPtr<HTMLMeterElement> meter = adoptRefWillBeNoop(new HTMLMeterElement(document));
meter->ensureUserAgentShadowRoot();
- return meter;
+ return meter.release();
}
RenderObject* HTMLMeterElement::createRenderer(RenderStyle* style)
@@ -70,47 +70,35 @@ void HTMLMeterElement::parseAttribute(const QualifiedName& name, const AtomicStr
LabelableElement::parseAttribute(name, value);
}
-double HTMLMeterElement::min() const
+double HTMLMeterElement::value() const
{
- return getFloatingPointAttribute(minAttr, 0);
+ double value = getFloatingPointAttribute(valueAttr, 0);
+ return std::min(std::max(value, min()), max());
}
-void HTMLMeterElement::setMin(double min, ExceptionState& exceptionState)
+void HTMLMeterElement::setValue(double value)
{
- if (!std::isfinite(min)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(min));
- return;
- }
- setFloatingPointAttribute(minAttr, min);
+ setFloatingPointAttribute(valueAttr, value);
}
-double HTMLMeterElement::max() const
+double HTMLMeterElement::min() const
{
- return std::max(getFloatingPointAttribute(maxAttr, std::max(1.0, min())), min());
+ return getFloatingPointAttribute(minAttr, 0);
}
-void HTMLMeterElement::setMax(double max, ExceptionState& exceptionState)
+void HTMLMeterElement::setMin(double min)
{
- if (!std::isfinite(max)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(max));
- return;
- }
- setFloatingPointAttribute(maxAttr, max);
+ setFloatingPointAttribute(minAttr, min);
}
-double HTMLMeterElement::value() const
+double HTMLMeterElement::max() const
{
- double value = getFloatingPointAttribute(valueAttr, 0);
- return std::min(std::max(value, min()), max());
+ return std::max(getFloatingPointAttribute(maxAttr, std::max(1.0, min())), min());
}
-void HTMLMeterElement::setValue(double value, ExceptionState& exceptionState)
+void HTMLMeterElement::setMax(double max)
{
- if (!std::isfinite(value)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(value));
- return;
- }
- setFloatingPointAttribute(valueAttr, value);
+ setFloatingPointAttribute(maxAttr, max);
}
double HTMLMeterElement::low() const
@@ -119,12 +107,8 @@ double HTMLMeterElement::low() const
return std::min(std::max(low, min()), max());
}
-void HTMLMeterElement::setLow(double low, ExceptionState& exceptionState)
+void HTMLMeterElement::setLow(double low)
{
- if (!std::isfinite(low)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(low));
- return;
- }
setFloatingPointAttribute(lowAttr, low);
}
@@ -134,12 +118,8 @@ double HTMLMeterElement::high() const
return std::min(std::max(high, low()), max());
}
-void HTMLMeterElement::setHigh(double high, ExceptionState& exceptionState)
+void HTMLMeterElement::setHigh(double high)
{
- if (!std::isfinite(high)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(high));
- return;
- }
setFloatingPointAttribute(highAttr, high);
}
@@ -149,12 +129,8 @@ double HTMLMeterElement::optimum() const
return std::min(std::max(optimum, min()), max());
}
-void HTMLMeterElement::setOptimum(double optimum, ExceptionState& exceptionState)
+void HTMLMeterElement::setOptimum(double optimum)
{
- if (!std::isfinite(optimum)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(optimum));
- return;
- }
setFloatingPointAttribute(optimumAttr, optimum);
}
@@ -223,10 +199,10 @@ void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
ASSERT(!m_value);
- RefPtr<MeterInnerElement> inner = MeterInnerElement::create(document());
+ RefPtrWillBeRawPtr<MeterInnerElement> inner = MeterInnerElement::create(document());
root.appendChild(inner);
- RefPtr<MeterBarElement> bar = MeterBarElement::create(document());
+ RefPtrWillBeRawPtr<MeterBarElement> bar = MeterBarElement::create(document());
m_value = MeterValueElement::create(document());
m_value->setWidthPercentage(0);
m_value->updatePseudo();
@@ -235,4 +211,10 @@ void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root)
inner->appendChild(bar);
}
+void HTMLMeterElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ LabelableElement::trace(visitor);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h
index e815e602442..44d9e6fd20c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h
@@ -31,7 +31,7 @@ class RenderMeter;
class HTMLMeterElement FINAL : public LabelableElement {
public:
- static PassRefPtr<HTMLMeterElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLMeterElement> create(Document&);
enum GaugeRegion {
GaugeRegionOptimum,
@@ -39,28 +39,30 @@ public:
GaugeRegionEvenLessGood
};
+ double value() const;
+ void setValue(double);
+
double min() const;
- void setMin(double, ExceptionState&);
+ void setMin(double);
double max() const;
- void setMax(double, ExceptionState&);
-
- double value() const;
- void setValue(double, ExceptionState&);
+ void setMax(double);
double low() const;
- void setLow(double, ExceptionState&);
+ void setLow(double);
double high() const;
- void setHigh(double, ExceptionState&);
+ void setHigh(double);
double optimum() const;
- void setOptimum(double, ExceptionState&);
+ void setOptimum(double);
double valueRatio() const;
GaugeRegion gaugeRegion() const;
- bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit HTMLMeterElement(Document&);
@@ -71,23 +73,15 @@ private:
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual bool recalcWillValidate() const { return false; }
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
void didElementStateChange();
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
- RefPtr<MeterValueElement> m_value;
+ RefPtrWillBeMember<MeterValueElement> m_value;
};
-inline bool isHTMLMeterElement(Node* node)
-{
- return node->hasTagName(HTMLNames::meterTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLMeterElement, hasTagName(HTMLNames::meterTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl
index fde8591538e..144f83ec411 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl
@@ -17,12 +17,16 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLMeterElement : HTMLElement {
- [RaisesException=Setter] attribute double value;
- [RaisesException=Setter] attribute double min;
- [RaisesException=Setter] attribute double max;
- [RaisesException=Setter] attribute double low;
- [RaisesException=Setter] attribute double high;
- [RaisesException=Setter] attribute double optimum;
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#htmlmeterelement
+
+[
+ TypeChecking=Unrestricted,
+] interface HTMLMeterElement : HTMLElement {
+ attribute double value;
+ attribute double min;
+ attribute double max;
+ attribute double low;
+ attribute double high;
+ attribute double optimum;
readonly attribute NodeList labels;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp
index e609ef53499..bf4fbd48407 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLModElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,14 +35,21 @@ inline HTMLModElement::HTMLModElement(const QualifiedName& tagName, Document& do
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLModElement> HTMLModElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLModElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLModElement)
bool HTMLModElement::isURLAttribute(const Attribute& attribute) const
{
return attribute.name() == citeAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLModElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == citeAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLModElement::subResourceAttributeName() const
+{
+ return citeAttr;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h
index 7fcc7c93edf..cf112ccdcbc 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h
@@ -30,12 +30,14 @@ namespace WebCore {
class HTMLModElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLModElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLModElement);
private:
HTMLModElement(const QualifiedName&, Document&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl
index c066b68c0ec..3c9bf9f9792 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl
@@ -18,6 +18,6 @@
*/
interface HTMLModElement : HTMLElement {
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString cite;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString cite;
[Reflect] attribute DOMString dateTime;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp
index 9941f554c51..a4829862410 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp
@@ -23,83 +23,23 @@
#include "config.h"
#include "core/html/HTMLNameCollection.h"
-#include "HTMLNames.h"
-#include "core/dom/Element.h"
-#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeRareData.h"
-#include "core/html/HTMLEmbedElement.h"
-#include "core/html/HTMLObjectElement.h"
namespace WebCore {
-using namespace HTMLNames;
-
-HTMLNameCollection::HTMLNameCollection(Node* document, CollectionType type, const AtomicString& name)
- : HTMLCollection(document, type, OverridesItemAfter)
+HTMLNameCollection::HTMLNameCollection(ContainerNode& document, CollectionType type, const AtomicString& name)
+ : HTMLCollection(document, type, DoesNotOverrideItemAfter)
, m_name(name)
{
}
HTMLNameCollection::~HTMLNameCollection()
{
- ASSERT(ownerNode());
- ASSERT(ownerNode()->isDocumentNode());
ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems);
-
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type(), m_name);
+#if !ENABLE(OILPAN)
+ ASSERT(ownerNode().isDocumentNode());
+ ownerNode().nodeLists()->removeCache(this, type(), m_name);
+#endif
}
-Element* HTMLNameCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const
-{
- ASSERT_UNUSED(offsetInArray, !offsetInArray);
- ASSERT(previous != ownerNode());
-
- Element* current;
- if (!previous)
- current = ElementTraversal::firstWithin(*ownerNode());
- else
- current = ElementTraversal::next(*previous, ownerNode());
-
- for (; current; current = ElementTraversal::next(*current, ownerNode())) {
- switch (type()) {
- case WindowNamedItems:
- // find only images, forms, applets, embeds and objects by name,
- // but anything by id
- if (current->hasTagName(imgTag)
- || current->hasTagName(formTag)
- || current->hasTagName(appletTag)
- || current->hasTagName(embedTag)
- || current->hasTagName(objectTag)) {
- if (current->getNameAttribute() == m_name)
- return current;
- }
- if (current->getIdAttribute() == m_name)
- return current;
- 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 (current->hasTagName(formTag)
- || current->hasTagName(iframeTag)
- || (current->hasTagName(embedTag) && toHTMLEmbedElement(current)->isExposed())) {
- if (current->getNameAttribute() == m_name)
- return current;
- } else if (current->hasTagName(appletTag)
- || (current->hasTagName(objectTag) && toHTMLObjectElement(current)->isExposed())) {
- if (current->getNameAttribute() == m_name || current->getIdAttribute() == m_name)
- return current;
- } else if (current->hasTagName(imgTag)) {
- if (current->getNameAttribute() == m_name || (current->getIdAttribute() == m_name && current->hasName()))
- return current;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- return 0;
-}
-
-}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h
index 435d4395860..b7ce7d4317d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h
@@ -24,26 +24,16 @@
#define HTMLNameCollection_h
#include "core/html/HTMLCollection.h"
-
#include "wtf/text/AtomicString.h"
namespace WebCore {
-class Document;
-
-class HTMLNameCollection FINAL : public HTMLCollection {
+class HTMLNameCollection : public HTMLCollection {
public:
- static PassRefPtr<HTMLNameCollection> create(Node* document, CollectionType type, const AtomicString& name)
- {
- return adoptRef(new HTMLNameCollection(document, type, name));
- }
-
- ~HTMLNameCollection();
-
-private:
- HTMLNameCollection(Node*, CollectionType, const AtomicString& name);
+ virtual ~HTMLNameCollection();
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
+protected:
+ HTMLNameCollection(ContainerNode&, CollectionType, const AtomicString& name);
AtomicString m_name;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp
index 3a3109c477d..aa6800d7a0f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 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
@@ -29,32 +29,29 @@
*/
#include "config.h"
-#include "core/html/HTMLImportResourceOwner.h"
+#include "core/html/HTMLNoEmbedElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/loader/FrameLoader.h"
namespace WebCore {
-HTMLImportResourceOwner::HTMLImportResourceOwner()
-{
-}
+using namespace HTMLNames;
-HTMLImportResourceOwner::~HTMLImportResourceOwner()
+inline HTMLNoEmbedElement::HTMLNoEmbedElement(Document& document)
+ : HTMLElement(noembedTag, document)
{
- clearResource();
}
-void HTMLImportResourceOwner::setResource(const ResourcePtr<RawResource>& resource)
-{
- ASSERT(!hasResource());
- m_resource = resource;
- m_resource->addClient(this);
-}
+DEFINE_NODE_FACTORY(HTMLNoEmbedElement)
-void HTMLImportResourceOwner::clearResource()
+bool HTMLNoEmbedElement::rendererIsNeeded(const RenderStyle& style)
{
- if (!hasResource())
- return;
- m_resource->removeClient(this);
- m_resource = 0;
+ if (document().frame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
+ return false;
+ return Element::rendererIsNeeded(style);
}
-} // namespace WebCore
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h
new file mode 100644
index 00000000000..1575f4d483c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 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 HTMLNoEmbedElement_h
+#define HTMLNoEmbedElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <noembed> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's rendererIsNeeded doesn't need to know about it.
+class HTMLNoEmbedElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLNoEmbedElement);
+
+private:
+ explicit HTMLNoEmbedElement(Document&);
+
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/Composition.h b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp
index 43054668f0d..7357a74e251 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/Composition.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 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
@@ -28,36 +28,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Composition_h
-#define Composition_h
+#include "config.h"
+#include "core/html/HTMLNoScriptElement.h"
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/text/WTFString.h"
+#include "bindings/v8/ScriptController.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-class InputMethodContext;
+using namespace HTMLNames;
-class Composition : public ScriptWrappable {
-public:
- static PassOwnPtr<Composition> create(InputMethodContext*);
- ~Composition();
+inline HTMLNoScriptElement::HTMLNoScriptElement(Document& document)
+ : HTMLElement(noscriptTag, document)
+{
+}
- void ref();
- void deref();
+DEFINE_NODE_FACTORY(HTMLNoScriptElement)
- String text() const;
- int selectionStart() const;
- int selectionEnd() const;
- const Vector<unsigned>& getSegments() const;
+bool HTMLNoScriptElement::rendererIsNeeded(const RenderStyle& style)
+{
+ if (document().frame()->script().canExecuteScripts(NotAboutToExecuteScript))
+ return false;
+ return Element::rendererIsNeeded(style);
-private:
- explicit Composition(InputMethodContext*);
+}
- InputMethodContext* m_inputMethodContext;
-};
-
-} // namespace WebCore
-
-#endif // Composition_h
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h
new file mode 100644
index 00000000000..ace1a493f0e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 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 HTMLNoScriptElement_h
+#define HTMLNoScriptElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <noscript> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's rendererIsNeeded doesn't need to know about it.
+class HTMLNoScriptElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLNoScriptElement);
+
+private:
+ explicit HTMLNoScriptElement(Document&);
+
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp
index 03675516a07..40ac89d6349 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp
@@ -23,16 +23,16 @@
#include "config.h"
#include "core/html/HTMLOListElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/rendering/RenderListItem.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLOListElement::HTMLOListElement(Document& document)
+inline HTMLOListElement::HTMLOListElement(Document& document)
: HTMLElement(olTag, document)
, m_start(0xBADBEEF)
, m_itemCount(0)
@@ -43,10 +43,7 @@ HTMLOListElement::HTMLOListElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOListElement> HTMLOListElement::create(Document& document)
-{
- return adoptRef(new HTMLOListElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLOListElement)
bool HTMLOListElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -100,6 +97,9 @@ void HTMLOListElement::setStart(int start)
void HTMLOListElement::updateItemValues()
{
+ if (!renderer())
+ return;
+ document().updateDistributionForNodeIfNeeded(this);
RenderListItem::updateItemValuesForOrderedList(this);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h
index 0da2e2c713d..407c9166979 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLOListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLOListElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLOListElement);
int start() const { return m_hasExplicitStart ? m_start : (m_isReversed ? itemCount() : 1); }
void setStart(int);
@@ -64,8 +64,6 @@ private:
bool m_shouldRecalculateItemCount : 1;
};
-DEFINE_NODE_TYPE_CASTS(HTMLOListElement, hasTagName(HTMLNames::olTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
index 87a5c3eae98..3a503060ff6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
@@ -24,14 +24,13 @@
#include "config.h"
#include "core/html/HTMLObjectElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NodeList.h"
+#include "core/dom/TagCollection.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLDocument.h"
@@ -53,22 +52,30 @@ inline HTMLObjectElement::HTMLObjectElement(Document& document, HTMLFormElement*
: HTMLPlugInElement(objectTag, document, createdByParser, ShouldNotPreferPlugInsForImages)
, m_useFallbackContent(false)
{
- setForm(form ? form : findFormAncestor());
ScriptWrappable::init(this);
+ associateByParser(form);
}
inline HTMLObjectElement::~HTMLObjectElement()
{
+#if !ENABLE(OILPAN)
setForm(0);
+#endif
}
-PassRefPtr<HTMLObjectElement> HTMLObjectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLObjectElement> HTMLObjectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
- RefPtr<HTMLObjectElement> element = adoptRef(new HTMLObjectElement(document, form, createdByParser));
+ RefPtrWillBeRawPtr<HTMLObjectElement> element = adoptRefWillBeNoop(new HTMLObjectElement(document, form, createdByParser));
element->ensureUserAgentShadowRoot();
return element.release();
}
+void HTMLObjectElement::trace(Visitor* visitor)
+{
+ FormAssociatedElement::trace(visitor);
+ HTMLPlugInElement::trace(visitor);
+}
+
RenderWidget* HTMLObjectElement::existingRenderWidget() const
{
return renderPart(); // This will return 0 if the renderer is not a RenderPart.
@@ -98,24 +105,24 @@ void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicSt
size_t pos = m_serviceType.find(";");
if (pos != kNotFound)
m_serviceType = m_serviceType.left(pos);
- if (renderer())
- setNeedsWidgetUpdate(true);
+ // FIXME: What is the right thing to do here? Should we supress the
+ // reload stuff when a persistable widget-type is specified?
+ reloadPluginOnAttributeChange(name);
+ if (!renderer())
+ requestPluginCreationWithoutRendererIfPossible();
} else if (name == dataAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
- if (renderer()) {
+ if (renderer() && isImageType()) {
setNeedsWidgetUpdate(true);
- if (isImageType()) {
- if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
- m_imageLoader->updateFromElementIgnoringPreviousError();
- }
+ if (!m_imageLoader)
+ m_imageLoader = HTMLImageLoader::create(this);
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+ } else {
+ reloadPluginOnAttributeChange(name);
}
} else if (name == classidAttr) {
m_classId = value;
- if (renderer())
- setNeedsWidgetUpdate(true);
- } else if (name == onbeforeloadAttr) {
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
+ reloadPluginOnAttributeChange(name);
} else {
HTMLPlugInElement::parseAttribute(name, value);
}
@@ -126,7 +133,7 @@ static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramV
// 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) {
+ for (unsigned i = 0; i < paramNames->size(); ++i) {
if (equalIgnoringCase((*paramNames)[i], "src"))
srcIndex = i;
else if (equalIgnoringCase((*paramNames)[i], "data"))
@@ -147,11 +154,7 @@ void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<S
// 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 = toHTMLParamElement(child);
+ for (HTMLParamElement* p = Traversal<HTMLParamElement>::firstChild(*this); p; p = Traversal<HTMLParamElement>::nextSibling(*p)) {
String name = p->name();
if (name.isEmpty())
continue;
@@ -185,12 +188,13 @@ void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<S
// Turn the attributes of the <object> element into arrays, but don't override <param> values.
if (hasAttributes()) {
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- const AtomicString& name = attribute->name().localName();
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ const AtomicString& name = it->name().localName();
if (!uniqueParamNames.contains(name.impl())) {
paramNames.append(name.string());
- paramValues.append(attribute->value().string());
+ paramValues.append(it->value().string());
}
}
}
@@ -217,8 +221,9 @@ bool HTMLObjectElement::hasFallbackContent() const
if (child->isTextNode()) {
if (!toText(child)->containsOnlyWhitespace())
return true;
- } else if (!child->hasTagName(paramTag))
+ } else if (!isHTMLParamElement(*child)) {
return true;
+ }
}
return false;
}
@@ -237,7 +242,7 @@ bool HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk()
|| !equalIgnoringCase(classId(), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
return false;
- RefPtr<NodeList> metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
+ RefPtrWillBeRawPtr<TagCollection> metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
unsigned length = metaElements->length();
for (unsigned i = 0; i < length; ++i) {
ASSERT(metaElements->item(i)->isHTMLElement());
@@ -262,6 +267,30 @@ bool HTMLObjectElement::hasValidClassId()
return classId().isEmpty();
}
+void HTMLObjectElement::reloadPluginOnAttributeChange(const QualifiedName& name)
+{
+ // Following,
+ // http://www.whatwg.org/specs/web-apps/current-work/#the-object-element
+ // (Enumerated list below "Whenever one of the following conditions occur:")
+ //
+ // the updating of certain attributes should bring about "redetermination"
+ // of what the element contains.
+ bool needsInvalidation;
+ if (name == typeAttr) {
+ needsInvalidation = !fastHasAttribute(classidAttr) && !fastHasAttribute(dataAttr);
+ } else if (name == dataAttr) {
+ needsInvalidation = !fastHasAttribute(classidAttr);
+ } else if (name == classidAttr) {
+ needsInvalidation = true;
+ } else {
+ ASSERT_NOT_REACHED();
+ needsInvalidation = false;
+ }
+ setNeedsWidgetUpdate(true);
+ if (needsInvalidation)
+ setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
// moved down into HTMLPluginElement.cpp
void HTMLObjectElement::updateWidgetInternal()
@@ -270,14 +299,18 @@ void HTMLObjectElement::updateWidgetInternal()
ASSERT(needsWidgetUpdate());
setNeedsWidgetUpdate(false);
// FIXME: This should ASSERT isFinishedParsingChildren() instead.
- if (!isFinishedParsingChildren())
+ if (!isFinishedParsingChildren()) {
+ dispatchErrorEvent();
return;
+ }
// FIXME: I'm not sure it's ever possible to get into updateWidget during a
// removal, but just in case we should avoid loading the frame to prevent
// security bugs.
- if (!SubframeLoadingDisabler::canLoadFrame(*this))
+ if (!SubframeLoadingDisabler::canLoadFrame(*this)) {
+ dispatchErrorEvent();
return;
+ }
String url = this->url();
String serviceType = m_serviceType;
@@ -288,20 +321,21 @@ void HTMLObjectElement::updateWidgetInternal()
parametersForPlugin(paramNames, paramValues, url, serviceType);
// Note: url is modified above by parametersForPlugin.
- if (!allowedToLoadFrameURL(url))
+ if (!allowedToLoadFrameURL(url)) {
+ dispatchErrorEvent();
return;
+ }
- bool fallbackContent = hasFallbackContent();
- renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
-
- RefPtr<HTMLObjectElement> protect(this); // beforeload and plugin loading can make arbitrary DOM mutations.
- bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
- if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
+ // FIXME: Is it possible to get here without a renderer now that we don't have beforeload events?
+ if (!renderer())
return;
- bool success = beforeLoadAllowedLoad && hasValidClassId() && requestObject(url, serviceType, paramNames, paramValues);
- if (!success && fallbackContent)
- renderFallbackContent();
+ if (!hasValidClassId() || !requestObject(url, serviceType, paramNames, paramValues)) {
+ if (!url.isEmpty())
+ dispatchErrorEvent();
+ if (hasFallbackContent())
+ renderFallbackContent();
+ }
}
bool HTMLObjectElement::rendererIsNeeded(const RenderStyle& style)
@@ -329,7 +363,7 @@ void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange
{
if (inDocument() && !useFallbackContent()) {
setNeedsWidgetUpdate(true);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
HTMLPlugInElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
@@ -341,6 +375,16 @@ bool HTMLObjectElement::isURLAttribute(const Attribute& attribute) const
|| HTMLPlugInElement::isURLAttribute(attribute);
}
+bool HTMLObjectElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == classidAttr || name == dataAttr || name == codebaseAttr || HTMLPlugInElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLObjectElement::subResourceAttributeName() const
+{
+ return dataAttr;
+}
+
const AtomicString HTMLObjectElement::imageSourceURL() const
{
return getAttribute(dataAttr);
@@ -385,12 +429,12 @@ void HTMLObjectElement::renderFallbackContent()
bool HTMLObjectElement::isExposed() const
{
// http://www.whatwg.org/specs/web-apps/current-work/#exposed
- for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(objectTag) && toHTMLObjectElement(ancestor)->isExposed())
+ for (HTMLObjectElement* ancestor = Traversal<HTMLObjectElement>::firstAncestor(*this); ancestor; ancestor = Traversal<HTMLObjectElement>::firstAncestor(*ancestor)) {
+ if (ancestor->isExposed())
return false;
}
- for (Node* node = firstChild(); node; node = NodeTraversal::next(*node, this)) {
- if (node->hasTagName(objectTag) || node->hasTagName(embedTag))
+ for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(*this); element; element = Traversal<HTMLElement>::next(*element, this)) {
+ if (isHTMLObjectElement(*element) || isHTMLEmbedElement(*element))
return false;
}
return true;
@@ -401,33 +445,20 @@ bool HTMLObjectElement::containsJavaApplet() const
if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
return true;
- for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSkippingChildren(*child, this)) {
- if (child->hasTagName(paramTag)
+ for (HTMLElement* child = Traversal<HTMLElement>::firstChild(*this); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (isHTMLParamElement(*child)
&& equalIgnoringCase(child->getNameAttribute(), "type")
&& MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
return true;
- if (child->hasTagName(objectTag) && toHTMLObjectElement(child)->containsJavaApplet())
+ if (isHTMLObjectElement(*child) && toHTMLObjectElement(*child).containsJavaApplet())
return true;
- if (child->hasTagName(appletTag))
+ if (isHTMLAppletElement(*child))
return true;
}
return false;
}
-void HTMLObjectElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLPlugInElement::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::didMoveToNewDocument(Document& oldDocument)
{
FormAssociatedElement::didMoveToNewDocument(oldDocument);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h
index fc2c20860b5..ae30514a0e0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h
@@ -31,9 +31,12 @@ namespace WebCore {
class HTMLFormElement;
class HTMLObjectElement FINAL : public HTMLPlugInElement, public FormAssociatedElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLObjectElement);
+
public:
- static PassRefPtr<HTMLObjectElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLObjectElement> create(Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLObjectElement();
+ virtual void trace(Visitor*) OVERRIDE;
const String& classId() const { return m_classId; }
@@ -41,14 +44,15 @@ public:
bool containsJavaApplet() const;
+ virtual bool hasFallbackContent() const OVERRIDE;
virtual bool useFallbackContent() const OVERRIDE;
virtual void renderFallbackContent() OVERRIDE;
- virtual bool isFormControlElement() const { return false; }
+ virtual bool isFormControlElement() const OVERRIDE { return false; }
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
- virtual bool appendFormData(FormDataList&, bool);
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
virtual bool isObjectElement() const OVERRIDE { return true; }
@@ -58,10 +62,12 @@ public:
bool checkValidity() { return true; }
virtual void setCustomValidity(const String&) OVERRIDE { }
+#if !ENABLE(OILPAN)
using Node::ref;
using Node::deref;
+#endif
- virtual bool canContainRangeEndPoint() const { return useFallbackContent(); }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return useFallbackContent(); }
bool isExposed() const;
@@ -75,25 +81,23 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
virtual RenderWidget* existingRenderWidget() const OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
virtual void updateWidgetInternal() OVERRIDE;
void updateDocNamedItem();
void reattachFallbackContent();
- 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);
@@ -101,8 +105,12 @@ private:
bool shouldAllowQuickTimeClassIdQuirk();
bool hasValidClassId();
- virtual void refFormAssociatedElement() { ref(); }
- virtual void derefFormAssociatedElement() { deref(); }
+ void reloadPluginOnAttributeChange(const QualifiedName&);
+
+#if !ENABLE(OILPAN)
+ virtual void refFormAssociatedElement() OVERRIDE { ref(); }
+ virtual void derefFormAssociatedElement() OVERRIDE { deref(); }
+#endif
virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
virtual bool shouldRegisterAsExtraNamedItem() const OVERRIDE { return true; }
@@ -111,9 +119,13 @@ private:
bool m_useFallbackContent : 1;
};
-DEFINE_NODE_TYPE_CASTS(HTMLObjectElement, hasTagName(HTMLNames::objectTag));
+// Intentionally left unimplemented, template specialization needs to be provided for specific
+// return types.
+template<typename T> inline const T& toElement(const FormAssociatedElement&);
+template<typename T> inline const T* toElement(const FormAssociatedElement*);
-inline const HTMLObjectElement* toHTMLObjectElement(const FormAssociatedElement* element)
+// Make toHTMLObjectElement() accept a FormAssociatedElement as input instead of a Node.
+template<> inline const HTMLObjectElement* toElement<HTMLObjectElement>(const FormAssociatedElement* element)
{
ASSERT_WITH_SECURITY_IMPLICATION(!element || !element->isFormControlElement());
const HTMLObjectElement* objectElement = static_cast<const HTMLObjectElement*>(element);
@@ -123,7 +135,7 @@ inline const HTMLObjectElement* toHTMLObjectElement(const FormAssociatedElement*
return objectElement;
}
-inline const HTMLObjectElement& toHTMLObjectElement(const FormAssociatedElement& element)
+template<> inline const HTMLObjectElement& toElement<HTMLObjectElement>(const FormAssociatedElement& element)
{
ASSERT_WITH_SECURITY_IMPLICATION(!element.isFormControlElement());
const HTMLObjectElement& objectElement = static_cast<const HTMLObjectElement&>(element);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
index 2393f057dd9..b6c7ccee7c2 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
@@ -28,7 +28,7 @@
[Reflect, TreatNullAs=NullString] attribute DOMString border;
[Reflect, URL] attribute DOMString codeBase;
[Reflect] attribute DOMString codeType;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString data;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString data;
[Reflect] attribute boolean declare;
[Reflect] attribute DOMString height;
[Reflect] attribute long hspace;
@@ -51,5 +51,7 @@
[Custom, NotEnumerable] getter Node (DOMString name);
[Custom] setter Node (DOMString name, Node value);
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp
index c9963b0ece4..01c307a46d6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/HTMLOptGroupElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/html/HTMLSelectElement.h"
@@ -42,10 +42,7 @@ inline HTMLOptGroupElement::HTMLOptGroupElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOptGroupElement> HTMLOptGroupElement::create(Document& document)
-{
- return adoptRef(new HTMLOptGroupElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLOptGroupElement)
bool HTMLOptGroupElement::isDisabledFormControl() const
{
@@ -58,12 +55,6 @@ bool HTMLOptGroupElement::rendererIsFocusable() const
return renderStyle() && renderStyle()->display() != NONE;
}
-const AtomicString& HTMLOptGroupElement::formControlType() const
-{
- DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup", AtomicString::ConstructFromLiteral));
- return optgroup;
-}
-
void HTMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
recalcSelectOptions();
@@ -81,21 +72,17 @@ void HTMLOptGroupElement::parseAttribute(const QualifiedName& name, const Atomic
void HTMLOptGroupElement::recalcSelectOptions()
{
- ContainerNode* select = parentNode();
- while (select && !select->hasTagName(selectTag))
- select = select->parentNode();
- if (select)
- toHTMLSelectElement(select)->setRecalcListItems();
+ if (HTMLSelectElement* select = Traversal<HTMLSelectElement>::firstAncestor(*this))
+ select->setRecalcListItems();
}
void HTMLOptGroupElement::attach(const AttachContext& context)
{
+ if (context.resolvedStyle) {
+ ASSERT(!m_style || m_style == context.resolvedStyle);
+ m_style = context.resolvedStyle;
+ }
HTMLElement::attach(context);
- // If after attaching nothing called styleForRenderer() on this node we
- // manually cache the value. This happens if our parent doesn't have a
- // renderer like <optgroup> or if it doesn't allow children like <select>.
- if (!m_style && parentNode()->renderStyle())
- updateNonRenderStyle();
}
void HTMLOptGroupElement::detach(const AttachContext& context)
@@ -106,7 +93,12 @@ void HTMLOptGroupElement::detach(const AttachContext& context)
void HTMLOptGroupElement::updateNonRenderStyle()
{
+ bool oldDisplayNoneStatus = isDisplayNone();
m_style = originalStyleForRenderer();
+ if (oldDisplayNoneStatus != isDisplayNone()) {
+ if (HTMLSelectElement* select = ownerSelectElement())
+ select->updateListOnRenderer();
+ }
}
RenderStyle* HTMLOptGroupElement::nonRendererStyle() const
@@ -116,8 +108,6 @@ RenderStyle* HTMLOptGroupElement::nonRendererStyle() const
PassRefPtr<RenderStyle> HTMLOptGroupElement::customStyleForRenderer()
{
- // styleForRenderer is called whenever a new style should be associated
- // with an Element so now is a good time to update our cached style.
updateNonRenderStyle();
return m_style;
}
@@ -136,14 +126,7 @@ String HTMLOptGroupElement::groupLabelText() const
HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const
{
- ContainerNode* select = parentNode();
- while (select && !select->hasTagName(selectTag))
- select = select->parentNode();
-
- if (!select)
- return 0;
-
- return toHTMLSelectElement(select);
+ return Traversal<HTMLSelectElement>::firstAncestor(*this);
}
void HTMLOptGroupElement::accessKeyAction(bool)
@@ -154,4 +137,10 @@ void HTMLOptGroupElement::accessKeyAction(bool)
select->accessKeyAction(false);
}
+bool HTMLOptGroupElement::isDisplayNone() const
+{
+ RenderStyle* style = nonRendererStyle();
+ return style && style->display() == NONE;
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
index 54ed7b5647d..a6674e0784e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
@@ -32,26 +32,27 @@ class HTMLSelectElement;
class HTMLOptGroupElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLOptGroupElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLOptGroupElement);
virtual bool isDisabledFormControl() const OVERRIDE;
HTMLSelectElement* ownerSelectElement() const;
String groupLabelText() const;
+ bool isDisplayNone() const;
+
private:
explicit HTMLOptGroupElement(Document&);
- virtual const AtomicString& formControlType() const;
virtual bool rendererIsFocusable() const OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
// <optgroup> never has a renderer so we manually manage a cached style.
void updateNonRenderStyle();
@@ -63,23 +64,6 @@ private:
RefPtr<RenderStyle> m_style;
};
-inline bool isHTMLOptGroupElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::optgroupTag);
-}
-
-inline bool isHTMLOptGroupElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::optgroupTag);
-}
-
-inline bool isHTMLOptGroupElement(const Element& element)
-{
- return element.hasTagName(HTMLNames::optgroupTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLOptGroupElement, hasTagName(HTMLNames::optgroupTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
index 0240fb2871e..79239f43d70 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
@@ -27,15 +27,14 @@
#include "config.h"
#include "core/html/HTMLOptionElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/ScriptLoader.h"
#include "core/dom/Text.h"
#include "core/html/HTMLDataListElement.h"
-#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLSelectElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/rendering/RenderTheme.h"
@@ -55,21 +54,18 @@ HTMLOptionElement::HTMLOptionElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLOptionElement> HTMLOptionElement::create(Document& document)
{
- return adoptRef(new HTMLOptionElement(document));
+ return adoptRefWillBeNoop(new HTMLOptionElement(document));
}
-PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const AtomicString& value,
+PassRefPtrWillBeRawPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const AtomicString& value,
bool defaultSelected, bool selected, ExceptionState& exceptionState)
{
- RefPtr<HTMLOptionElement> element = adoptRef(new HTMLOptionElement(document));
-
- RefPtr<Text> text = Text::create(document, data.isNull() ? "" : data);
-
- element->appendChild(text.release(), exceptionState);
+ RefPtrWillBeRawPtr<HTMLOptionElement> element = adoptRefWillBeNoop(new HTMLOptionElement(document));
+ element->appendChild(Text::create(document, data.isNull() ? "" : data), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (!value.isNull())
element->setValue(value);
@@ -82,12 +78,15 @@ PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document
void HTMLOptionElement::attach(const AttachContext& context)
{
- HTMLElement::attach(context);
- // If after attaching nothing called styleForRenderer() on this node we
- // manually cache the value. This happens if our parent doesn't have a
- // renderer like <optgroup> or if it doesn't allow children like <select>.
- if (!m_style && parentNode()->renderStyle())
+ AttachContext optionContext(context);
+ if (context.resolvedStyle) {
+ ASSERT(!m_style || m_style == context.resolvedStyle);
+ m_style = context.resolvedStyle;
+ } else {
updateNonRenderStyle();
+ optionContext.resolvedStyle = m_style.get();
+ }
+ HTMLElement::attach(optionContext);
}
void HTMLOptionElement::detach(const AttachContext& context)
@@ -122,12 +121,12 @@ String HTMLOptionElement::text() const
void HTMLOptionElement::setText(const String &text, ExceptionState& exceptionState)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
// Changing the text causes a recalc of a select's items, which will reset the selected
// index to the first item if the select is single selection with a menu list. We attempt to
// preserve the selected item.
- RefPtr<HTMLSelectElement> select = ownerSelectElement();
+ RefPtrWillBeRawPtr<HTMLSelectElement> select = ownerSelectElement();
bool selectIsMenuList = select && select->usesMenuList();
int oldSelectedIndex = selectIsMenuList ? select->selectedIndex() : -1;
@@ -146,8 +145,7 @@ void HTMLOptionElement::setText(const String &text, ExceptionState& exceptionSta
void HTMLOptionElement::accessKeyAction(bool)
{
- HTMLSelectElement* select = ownerSelectElement();
- if (select)
+ if (HTMLSelectElement* select = ownerSelectElement())
select->accessKeySetSelectedIndex(index());
}
@@ -161,12 +159,12 @@ int HTMLOptionElement::index() const
int optionIndex = 0;
- const Vector<HTMLElement*>& items = selectElement->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = selectElement->listItems();
size_t length = items.size();
for (size_t i = 0; i < length; ++i) {
- if (!items[i]->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*items[i]))
continue;
- if (items[i] == this)
+ if (items[i].get() == this)
return optionIndex;
++optionIndex;
}
@@ -185,7 +183,7 @@ void HTMLOptionElement::parseAttribute(const QualifiedName& name, const AtomicSt
if (oldDisabled != m_disabled) {
didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), EnabledState);
+ RenderTheme::theme().stateChanged(renderer(), EnabledControlState);
}
} else if (name == selectedAttr) {
if (bool willBeSelected = !value.isNull())
@@ -207,17 +205,17 @@ void HTMLOptionElement::setValue(const AtomicString& value)
setAttribute(valueAttr, value);
}
-bool HTMLOptionElement::selected()
+bool HTMLOptionElement::selected() const
{
if (HTMLSelectElement* select = ownerSelectElement()) {
// If a stylesheet contains option:checked selectors, this function is
// called during parsing. updateListItemSelectedStates() is O(N) where N
// is the number of option elements, so the <select> parsing would be
- // O(N^2) without isParsingInProgress check. Also,
+ // O(N^2) without the isFinishedParsingChildren check. Also,
// updateListItemSelectedStates() determines default selection, and we'd
// like to avoid to determine default selection with incomplete option
// list.
- if (select->isParsingInProgress())
+ if (!select->isFinishedParsingChildren())
return m_isSelected;
select->updateListItemSelectedStates();
}
@@ -258,23 +256,12 @@ void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
{
- for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
- if (parent->hasTagName(datalistTag))
- return toHTMLDataListElement(parent);
- }
- return 0;
+ return Traversal<HTMLDataListElement>::firstAncestor(*this);
}
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
{
- ContainerNode* select = parentNode();
- while (select && !select->hasTagName(selectTag))
- select = select->parentNode();
-
- if (!select)
- return 0;
-
- return toHTMLSelectElement(select);
+ return Traversal<HTMLSelectElement>::firstAncestor(*this);
}
String HTMLOptionElement::label() const
@@ -292,7 +279,12 @@ void HTMLOptionElement::setLabel(const AtomicString& label)
void HTMLOptionElement::updateNonRenderStyle()
{
+ bool oldDisplayNoneStatus = isDisplayNone();
m_style = originalStyleForRenderer();
+ if (oldDisplayNoneStatus != isDisplayNone()) {
+ if (HTMLSelectElement* select = ownerSelectElement())
+ select->updateListOnRenderer();
+ }
}
RenderStyle* HTMLOptionElement::nonRendererStyle() const
@@ -302,26 +294,26 @@ RenderStyle* HTMLOptionElement::nonRendererStyle() const
PassRefPtr<RenderStyle> HTMLOptionElement::customStyleForRenderer()
{
- // styleForRenderer is called whenever a new style should be associated
- // with an Element so now is a good time to update our cached style.
updateNonRenderStyle();
return m_style;
}
-void HTMLOptionElement::didRecalcStyle(StyleRecalcChange)
+void HTMLOptionElement::didRecalcStyle(StyleRecalcChange change)
{
- // FIXME: This is nasty, we ask our owner select to repaint even if the new
- // style is exactly the same.
+ if (change == NoChange)
+ return;
+
+ // FIXME: We ask our owner select to repaint regardless of which property changed.
if (HTMLSelectElement* select = ownerSelectElement()) {
if (RenderObject* renderer = select->renderer())
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
}
}
String HTMLOptionElement::textIndentedToRespectGroupLabel() const
{
ContainerNode* parent = parentNode();
- if (parent && isHTMLOptGroupElement(parent))
+ if (parent && isHTMLOptGroupElement(*parent))
return " " + text();
return text();
}
@@ -331,7 +323,7 @@ bool HTMLOptionElement::isDisabledFormControl() const
if (ownElementDisabled())
return true;
if (Element* parent = parentElement())
- return isHTMLOptGroupElement(parent) && parent->isDisabledFormControl();
+ return isHTMLOptGroupElement(*parent) && parent->isDisabledFormControl();
return false;
}
@@ -368,11 +360,22 @@ String HTMLOptionElement::collectOptionInnerText() const
HTMLFormElement* HTMLOptionElement::form() const
{
- HTMLSelectElement* selectElement = ownerSelectElement();
- if (!selectElement)
- return 0;
+ if (HTMLSelectElement* selectElement = ownerSelectElement())
+ return selectElement->formOwner();
- return selectElement->formOwner();
+ return 0;
+}
+
+bool HTMLOptionElement::isDisplayNone() const
+{
+ ContainerNode* parent = parentNode();
+ // Check for parent optgroup having display NONE
+ if (parent && isHTMLOptGroupElement(*parent)) {
+ if (toHTMLOptGroupElement(*parent).isDisplayNone())
+ return true;
+ }
+ RenderStyle* style = nonRendererStyle();
+ return style && style->display() == NONE;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h
index 1f79a1bd81a..65e1a2394b8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h
@@ -35,11 +35,11 @@ class HTMLSelectElement;
class HTMLOptionElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLOptionElement> create(Document&);
- static PassRefPtr<HTMLOptionElement> createForJSConstructor(Document&, const String& data, const AtomicString& value,
+ static PassRefPtrWillBeRawPtr<HTMLOptionElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLOptionElement> createForJSConstructor(Document&, const String& data, const AtomicString& value,
bool defaultSelected, bool selected, ExceptionState&);
- virtual String text() const;
+ String text() const;
void setText(const String&, ExceptionState&);
int index() const;
@@ -47,7 +47,7 @@ public:
String value() const;
void setValue(const AtomicString&);
- bool selected();
+ bool selected() const;
void setSelected(bool);
HTMLDataListElement* ownerDataListElement() const;
@@ -66,27 +66,28 @@ public:
HTMLFormElement* form() const;
+ bool isDisplayNone() const;
+
private:
explicit HTMLOptionElement(Document&);
virtual bool rendererIsFocusable() const OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void accessKeyAction(bool);
+ virtual void accessKeyAction(bool) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
// <option> never has a renderer so we manually manage a cached style.
void updateNonRenderStyle();
virtual RenderStyle* nonRendererStyle() const OVERRIDE;
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
-
- void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
String collectOptionInnerText() const;
@@ -95,8 +96,6 @@ private:
RefPtr<RenderStyle> m_style;
};
-DEFINE_NODE_TYPE_CASTS(HTMLOptionElement, hasTagName(HTMLNames::optionTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
index 41c6592f239..d57d72a5a97 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
@@ -19,7 +19,11 @@
*/
[
- NamedConstructor=Option([Default=NullString] optional DOMString data, [Default=NullString] optional DOMString value, [Default=Undefined] optional boolean defaultSelected, [Default=Undefined] optional boolean selected),
+ NamedConstructor=Option(optional DOMString data = null,
+ optional DOMString value = null,
+ [Default=Undefined] optional boolean defaultSelected,
+ [Default=Undefined] optional boolean selected),
+ ConstructorCallWith=Document,
RaisesException=Constructor
] interface HTMLOptionElement : HTMLElement {
[Reflect] attribute boolean disabled;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp
index aae87b078b9..e27e0e1629d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2011, 2012 Apple Computer, Inc.
+ * Copyright (C) 2014 Samsung Electronics. 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
@@ -30,24 +31,50 @@
namespace WebCore {
-HTMLOptionsCollection::HTMLOptionsCollection(Node* select)
+HTMLOptionsCollection::HTMLOptionsCollection(ContainerNode& select)
: HTMLCollection(select, SelectOptions, DoesNotOverrideItemAfter)
{
- ASSERT(select->hasTagName(HTMLNames::selectTag));
+ ASSERT(isHTMLSelectElement(select));
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Node* select, CollectionType)
+void HTMLOptionsCollection::supportedPropertyNames(Vector<String>& names)
{
- return adoptRef(new HTMLOptionsCollection(select));
+ // As per http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmloptionscollection:
+ // The supported property names consist of the non-empty values of all the id and name attributes of all the elements
+ // represented by the collection, in tree order, ignoring later duplicates, with the id of an element preceding its
+ // name if it contributes both, they differ from each other, and neither is the duplicate of an earlier entry.
+ HashSet<AtomicString> existingNames;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
+ ASSERT(element);
+ const AtomicString& idAttribute = element->getIdAttribute();
+ if (!idAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(idAttribute);
+ if (addResult.isNewEntry)
+ names.append(idAttribute);
+ }
+ const AtomicString& nameAttribute = element->getNameAttribute();
+ if (!nameAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(nameAttribute);
+ if (addResult.isNewEntry)
+ names.append(nameAttribute);
+ }
+ }
+}
+
+PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(ContainerNode& select, CollectionType)
+{
+ return adoptRefWillBeNoop(new HTMLOptionsCollection(select));
}
-void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, ExceptionState& exceptionState)
+void HTMLOptionsCollection::add(PassRefPtrWillBeRawPtr<HTMLOptionElement> element, ExceptionState& exceptionState)
{
add(element, length(), exceptionState);
}
-void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index, ExceptionState& exceptionState)
+void HTMLOptionsCollection::add(PassRefPtrWillBeRawPtr<HTMLOptionElement> element, int index, ExceptionState& exceptionState)
{
HTMLOptionElement* newOption = element.get();
@@ -61,19 +88,19 @@ void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index
return;
}
- HTMLSelectElement* select = toHTMLSelectElement(ownerNode());
+ HTMLSelectElement& select = toHTMLSelectElement(ownerNode());
if (index == -1 || unsigned(index) >= length())
- select->add(newOption, 0, exceptionState);
+ select.add(newOption, 0, exceptionState);
else
- select->add(newOption, toHTMLOptionElement(item(index)), exceptionState);
+ select.addBeforeOptionAtIndex(newOption, index, exceptionState);
ASSERT(!exceptionState.hadException());
}
void HTMLOptionsCollection::remove(int index)
{
- toHTMLSelectElement(ownerNode())->remove(index);
+ toHTMLSelectElement(ownerNode()).remove(index);
}
void HTMLOptionsCollection::remove(HTMLOptionElement* option)
@@ -83,22 +110,22 @@ void HTMLOptionsCollection::remove(HTMLOptionElement* option)
int HTMLOptionsCollection::selectedIndex() const
{
- return toHTMLSelectElement(ownerNode())->selectedIndex();
+ return toHTMLSelectElement(ownerNode()).selectedIndex();
}
void HTMLOptionsCollection::setSelectedIndex(int index)
{
- toHTMLSelectElement(ownerNode())->setSelectedIndex(index);
+ toHTMLSelectElement(ownerNode()).setSelectedIndex(index);
}
void HTMLOptionsCollection::setLength(unsigned length, ExceptionState& exceptionState)
{
- toHTMLSelectElement(ownerNode())->setLength(length, exceptionState);
+ toHTMLSelectElement(ownerNode()).setLength(length, exceptionState);
}
-void HTMLOptionsCollection::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLOptionsCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtrWillBeRawPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtrWillBeRawPtr<Element>& returnValue1)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
this->namedItems(name, namedItems);
if (!namedItems.size())
@@ -110,25 +137,19 @@ void HTMLOptionsCollection::anonymousNamedGetter(const AtomicString& name, bool&
return;
}
+ // FIXME: The spec and Firefox do not return a NodeList. They always return the first matching Element.
returnValue0Enabled = true;
returnValue0 = NamedNodesCollection::create(namedItems);
}
-bool HTMLOptionsCollection::anonymousIndexedSetterRemove(unsigned index, ExceptionState& exceptionState)
-{
- HTMLSelectElement* base = toHTMLSelectElement(ownerNode());
- base->remove(index);
- return true;
-}
-
-bool HTMLOptionsCollection::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
+bool HTMLOptionsCollection::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeRawPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
{
- HTMLSelectElement* base = toHTMLSelectElement(ownerNode());
- if (!value) {
- exceptionState.throwTypeError(ExceptionMessages::failedToSet(String::number(index), "HTMLOptionsCollection", "The element provided was not an HTMLOptionElement."));
+ HTMLSelectElement& base = toHTMLSelectElement(ownerNode());
+ if (!value) { // undefined or null
+ base.remove(index);
return true;
}
- base->setOption(index, value.get(), exceptionState);
+ base.setOption(index, value.get(), exceptionState);
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h
index fe5ad5d746e..bb888abf002 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h
@@ -34,10 +34,10 @@ class HTMLSelectElement;
class HTMLOptionsCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLOptionsCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLOptionsCollection> create(ContainerNode&, CollectionType);
- void add(PassRefPtr<HTMLOptionElement>, ExceptionState&);
- void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionState&);
+ void add(PassRefPtrWillBeRawPtr<HTMLOptionElement>, ExceptionState&);
+ void add(PassRefPtrWillBeRawPtr<HTMLOptionElement>, int index, ExceptionState&);
void remove(int index);
void remove(HTMLOptionElement*);
@@ -45,14 +45,17 @@ public:
void setSelectedIndex(int);
void setLength(unsigned, ExceptionState&);
- void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Node>&);
- bool anonymousIndexedSetter(unsigned, PassRefPtr<HTMLOptionElement>, ExceptionState&);
- bool anonymousIndexedSetterRemove(unsigned, ExceptionState&);
+ void namedGetter(const AtomicString& name, bool&, RefPtrWillBeRawPtr<NodeList>&, bool&, RefPtrWillBeRawPtr<Element>&);
+ bool anonymousIndexedSetter(unsigned, PassRefPtrWillBeRawPtr<HTMLOptionElement>, ExceptionState&);
private:
- explicit HTMLOptionsCollection(Node*);
+ explicit HTMLOptionsCollection(ContainerNode&);
+
+ virtual void supportedPropertyNames(Vector<String>& names) OVERRIDE;
};
+DEFINE_TYPE_CASTS(HTMLOptionsCollection, LiveNodeListBase, collection, collection->type() == SelectOptions, collection.type() == SelectOptions);
+
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
index 32c414795d1..a802b20e388 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2013, 2014 Samsung Electronics. 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
@@ -21,19 +21,17 @@
[
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
] interface HTMLOptionsCollection : HTMLCollection {
attribute long selectedIndex;
[Custom=Setter, RaisesException=Setter] attribute unsigned long length;
- [ImplementedAs=item] getter Node(unsigned long index);
- [ImplementedAs=anonymousIndexedSetter, RaisesException] setter HTMLOptionElement (unsigned long index, [TreatNullAs=anonymousIndexedSetterRemove, TreatUndefinedAs=anonymousIndexedSetterRemove] HTMLOptionElement value);
- [ImplementedAs=anonymousNamedGetter, NotEnumerable] getter (NodeList or Node)(DOMString name);
+ [ImplementedAs=item] getter Node (unsigned long index);
+ [RaisesException, TypeChecking=Interface|Nullable] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value);
- [Custom] Node namedItem([Default=Undefined] optional DOMString name);
+ // FIXME: The spec and firefox return an Element (the first matching Element).
+ [ImplementedAs=namedGetter] getter (NodeList or Element) namedItem(DOMString name);
- [Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option,
- optional unsigned long index);
+ [Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option, optional unsigned long index);
void remove(unsigned long index);
- void remove(HTMLOptionElement option); // Non standard.
+ [MeasureAs=HTMLOptionsCollectionRemoveElement] void remove(HTMLOptionElement option); // non-standard
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
index 00d04356f9c..733b6ff38d0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
@@ -31,24 +31,23 @@
#include "config.h"
#include "core/html/HTMLOutputElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
namespace WebCore {
inline HTMLOutputElement::HTMLOutputElement(Document& document, HTMLFormElement* form)
: HTMLFormControlElement(HTMLNames::outputTag, document, form)
, m_isDefaultValueMode(true)
- , m_isSetTextContentInProgress(false)
, m_defaultValue("")
, m_tokens(DOMSettableTokenList::create())
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLOutputElement> HTMLOutputElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLOutputElement(document, form));
+ return adoptRefWillBeNoop(new HTMLOutputElement(document, form));
}
const AtomicString& HTMLOutputElement::formControlType() const
@@ -75,7 +74,7 @@ DOMSettableTokenList* HTMLOutputElement::htmlFor() const
return m_tokens.get();
}
-void HTMLOutputElement::setFor(const String& value)
+void HTMLOutputElement::setFor(const AtomicString& value)
{
m_tokens->setValue(value);
}
@@ -84,11 +83,6 @@ void HTMLOutputElement::childrenChanged(bool createdByParser, Node* beforeChange
{
HTMLFormControlElement::childrenChanged(createdByParser, beforeChange, afterChange, childCountDelta);
- if (createdByParser || m_isSetTextContentInProgress) {
- m_isSetTextContentInProgress = false;
- return;
- }
-
if (m_isDefaultValueMode)
m_defaultValue = textContent();
}
@@ -98,10 +92,10 @@ void HTMLOutputElement::resetImpl()
// 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);
+ setTextContent(m_defaultValue);
+ m_isDefaultValueMode = true;
}
String HTMLOutputElement::value() const
@@ -115,7 +109,7 @@ void HTMLOutputElement::setValue(const String& value)
m_isDefaultValueMode = false;
if (value == this->value())
return;
- setTextContentInternal(value);
+ setTextContent(value);
}
String HTMLOutputElement::defaultValue() const
@@ -131,14 +125,14 @@ void HTMLOutputElement::setDefaultValue(const String& 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);
+ setTextContent(value);
}
-void HTMLOutputElement::setTextContentInternal(const String& value)
+
+void HTMLOutputElement::trace(Visitor* visitor)
{
- ASSERT(!m_isSetTextContentInProgress);
- m_isSetTextContentInProgress = true;
- setTextContent(value);
+ visitor->trace(m_tokens);
+ HTMLFormControlElement::trace(visitor);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h
index bf1e469e715..d554341032a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h
@@ -38,36 +38,35 @@ namespace WebCore {
class HTMLOutputElement FINAL : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLOutputElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLOutputElement> create(Document&, HTMLFormElement*);
- virtual bool willValidate() const { return false; }
+ virtual bool willValidate() const OVERRIDE { return false; }
String value() const;
void setValue(const String&);
String defaultValue() const;
void setDefaultValue(const String&);
- void setFor(const String&);
+ void setFor(const AtomicString&);
DOMSettableTokenList* htmlFor() const;
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
HTMLOutputElement(Document&, HTMLFormElement*);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual const AtomicString& formControlType() const;
- virtual bool isEnumeratable() const { return true; }
+ virtual const AtomicString& formControlType() const OVERRIDE;
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual bool supportsFocus() const;
- virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual bool supportsFocus() const OVERRIDE;
+ virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual void resetImpl() OVERRIDE;
- void setTextContentInternal(const String&);
-
bool m_isDefaultValueMode;
- bool m_isSetTextContentInProgress;
String m_defaultValue;
- RefPtr<DOMSettableTokenList> m_tokens;
+ RefPtrWillBeMember<DOMSettableTokenList> m_tokens;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp
index 459800856f9..7cfea938976 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLParagraphElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -37,17 +37,7 @@ inline HTMLParagraphElement::HTMLParagraphElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLParagraphElement> HTMLParagraphElement::create(Document& document)
-{
- return adoptRef(new HTMLParagraphElement(document));
-}
-
-bool HTMLParagraphElement::isPresentationAttribute(const QualifiedName& name) const
-{
- if (name == alignAttr)
- return true;
- return HTMLElement::isPresentationAttribute(name);
-}
+DEFINE_NODE_FACTORY(HTMLParagraphElement)
void HTMLParagraphElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h
index 4bfbbf64425..43b8d0ead20 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h
@@ -29,12 +29,11 @@ namespace WebCore {
class HTMLParagraphElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLParagraphElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLParagraphElement);
private:
explicit HTMLParagraphElement(Document&);
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp
index 982d53d993f..63c65aed352 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLParamElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
@@ -37,10 +37,7 @@ inline HTMLParamElement::HTMLParamElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLParamElement> HTMLParamElement::create(Document& document)
-{
- return adoptRef(new HTMLParamElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLParamElement)
const AtomicString& HTMLParamElement::name() const
{
@@ -66,14 +63,4 @@ bool HTMLParamElement::isURLAttribute(const Attribute& attribute) const
return HTMLElement::isURLAttribute(attribute);
}
-void HTMLParamElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- if (!isURLParameter(name()))
- return;
-
- addSubresourceURL(urls, document().completeURL(value()));
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h
index 991e9595db9..1d04d46b0d8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLParamElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLParamElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLParamElement);
const AtomicString& name() const;
const AtomicString& value() const;
@@ -40,12 +40,8 @@ private:
explicit HTMLParamElement(Document&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
};
-DEFINE_NODE_TYPE_CASTS(HTMLParamElement, hasTagName(HTMLNames::paramTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp
new file mode 100644
index 00000000000..d5361777b0b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLPictureElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLImageElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLPictureElement::HTMLPictureElement(Document& document)
+ : HTMLElement(pictureTag, document)
+{
+ ScriptWrappable::init(this);
+}
+
+DEFINE_NODE_FACTORY(HTMLPictureElement)
+
+void HTMLPictureElement::sourceOrMediaChanged()
+{
+ for (HTMLImageElement* imageElement = Traversal<HTMLImageElement>::firstChild(*this); imageElement; imageElement = Traversal<HTMLImageElement>::nextSibling(*imageElement)) {
+ imageElement->selectSourceURL(HTMLImageElement::UpdateNormal);
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h
new file mode 100644
index 00000000000..c5cb0f501fd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLPictureElement_h
+#define HTMLPictureElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLPictureElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLPictureElement);
+
+ void sourceOrMediaChanged();
+
+protected:
+ explicit HTMLPictureElement(Document&);
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl
new file mode 100644
index 00000000000..649316cb8a1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl
@@ -0,0 +1,10 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// http://picture.responsiveimages.org
+[
+ RuntimeEnabled=Picture
+] interface HTMLPictureElement : HTMLElement {
+};
+
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
index c4ba8d0a939..7cbceed497d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
@@ -23,19 +23,20 @@
#include "config.h"
#include "core/html/HTMLPlugInElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/npruntime_impl.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
-#include "core/dom/PostAttachCallbacks.h"
+#include "core/dom/Node.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLImageLoader.h"
#include "core/html/PluginDocument.h"
-#include "core/html/shadow/HTMLContentElement.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/page/EventHandler.h"
#include "core/page/Page.h"
@@ -59,7 +60,6 @@ HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document& doc
, m_isDelayingLoadEvent(false)
, m_NPObject(0)
, m_isCapturingMouseEvents(false)
- , m_inBeforeLoadEventHandler(false)
// 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
@@ -82,6 +82,12 @@ HTMLPlugInElement::~HTMLPlugInElement()
}
}
+void HTMLPlugInElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageLoader);
+ HTMLFrameOwnerElement::trace(visitor);
+}
+
bool HTMLPlugInElement::canProcessDrag() const
{
return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(pluginWidget())->canProcessDrag();
@@ -117,9 +123,10 @@ void HTMLPlugInElement::attach(const AttachContext& context)
if (!renderer() || useFallbackContent())
return;
+
if (isImageType()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElement();
} else if (needsWidgetUpdate()
&& renderEmbeddedObject()
@@ -128,12 +135,13 @@ void HTMLPlugInElement::attach(const AttachContext& context)
&& !m_isDelayingLoadEvent) {
m_isDelayingLoadEvent = true;
document().incrementLoadEventDelayCount();
+ document().loadPluginsSoon();
}
}
void HTMLPlugInElement::updateWidget()
{
- RefPtr<HTMLPlugInElement> protector(this);
+ RefPtrWillBeRawPtr<HTMLPlugInElement> protector(this);
updateWidgetInternal();
if (m_isDelayingLoadEvent) {
m_isDelayingLoadEvent = false;
@@ -141,6 +149,43 @@ void HTMLPlugInElement::updateWidget()
}
}
+void HTMLPlugInElement::requestPluginCreationWithoutRendererIfPossible()
+{
+ if (m_serviceType.isEmpty())
+ return;
+
+ if (!document().frame()
+ || !document().frame()->loader().client()->canCreatePluginWithoutRenderer(m_serviceType))
+ return;
+
+ if (renderer() && renderer()->isWidget())
+ return;
+
+ createPluginWithoutRenderer();
+}
+
+void HTMLPlugInElement::createPluginWithoutRenderer()
+{
+ ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer(m_serviceType));
+
+ KURL url;
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+
+ paramNames.append("type");
+ paramValues.append(m_serviceType);
+
+ bool useFallback = false;
+ loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false);
+}
+
+bool HTMLPlugInElement::shouldAccelerate() const
+{
+ if (Widget* widget = ownedWidget())
+ return widget->isPluginView() && toPluginView(widget)->platformLayer();
+ return false;
+}
+
void HTMLPlugInElement::detach(const AttachContext& context)
{
// Update the widget the next time we attach (detaching destroys the plugin).
@@ -152,11 +197,17 @@ void HTMLPlugInElement::detach(const AttachContext& context)
document().decrementLoadEventDelayCount();
}
+ // Only try to persist a plugin widget we actually own.
+ Widget* plugin = ownedWidget();
+ if (plugin && plugin->pluginShouldPersist())
+ m_persistedPluginWidget = plugin;
resetInstance();
+ // FIXME - is this next line necessary?
+ setWidget(nullptr);
if (m_isCapturingMouseEvents) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_isCapturingMouseEvents = false;
}
@@ -200,7 +251,7 @@ void HTMLPlugInElement::finishParsingChildren()
setNeedsWidgetUpdate(true);
if (inDocument())
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void HTMLPlugInElement::resetInstance()
@@ -210,7 +261,7 @@ void HTMLPlugInElement::resetInstance()
SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 0;
@@ -218,34 +269,21 @@ SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
// return the cached allocated Bindings::Instance. Not supporting this
// edge-case is OK.
if (!m_pluginWrapper) {
- if (Widget* widget = pluginWidget())
- m_pluginWrapper = frame->script().createPluginWrapper(widget);
+ Widget* plugin;
+
+ if (m_persistedPluginWidget)
+ plugin = m_persistedPluginWidget.get();
+ else
+ plugin = pluginWidget();
+
+ if (plugin)
+ m_pluginWrapper = frame->script().createPluginWrapper(plugin);
}
return m_pluginWrapper.get();
}
-bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL)
-{
- // FIXME: Our current plug-in loading design can't guarantee the following
- // assertion is true, since plug-in loading can be initiated during layout,
- // and synchronous layout can be initiated in a beforeload event handler!
- // See <http://webkit.org/b/71264>.
- // ASSERT(!m_inBeforeLoadEventHandler);
- m_inBeforeLoadEventHandler = true;
- bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent(sourceURL);
- m_inBeforeLoadEventHandler = false;
- return beforeLoadAllowedLoad;
-}
-
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;
- }
-
if (RenderWidget* renderWidget = renderWidgetForJSBindings())
return renderWidget->widget();
return 0;
@@ -356,7 +394,7 @@ bool HTMLPlugInElement::isImageType()
if (m_serviceType.isEmpty() && protocolIs(m_url, "data"))
m_serviceType = mimeTypeFromDataURL(m_url);
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
KURL completedURL = document().completeURL(m_url);
return frame->loader().client()->objectContentType(completedURL, m_serviceType, shouldPreferPlugInsForImages()) == ObjectContentImage;
}
@@ -364,14 +402,6 @@ bool HTMLPlugInElement::isImageType()
return Image::supportsType(m_serviceType);
}
-const String HTMLPlugInElement::loadedMimeType() const
-{
- String mimeType = m_serviceType;
- if (mimeType.isEmpty())
- mimeType = mimeTypeFromURL(m_loadedUrl);
- return mimeType;
-}
-
RenderEmbeddedObject* HTMLPlugInElement::renderEmbeddedObject() const
{
// HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
@@ -415,10 +445,13 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
return false;
KURL completedURL = document().completeURL(url);
+ if (!pluginIsLoadable(completedURL, mimeType))
+ return false;
bool useFallback;
- if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
- return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallback);
+ bool requireRenderer = true;
+ if (shouldUsePlugin(completedURL, mimeType, hasFallbackContent(), useFallback))
+ return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallback, requireRenderer);
// If the plug-in element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a new
@@ -427,38 +460,43 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
return loadOrRedirectSubframe(completedURL, getNameAttribute(), true);
}
-bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
+bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireRenderer)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
return false;
- if (!pluginIsLoadable(url, mimeType))
- return false;
-
RenderEmbeddedObject* renderer = renderEmbeddedObject();
// FIXME: This code should not depend on renderer!
- if (!renderer || useFallback)
+ if ((!renderer && requireRenderer) || useFallback)
return false;
WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data());
WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data());
m_loadedUrl = url;
- IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), renderer->contentHeight()));
- bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
- RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually);
+ RefPtr<Widget> widget = m_persistedPluginWidget;
+ if (!widget) {
+ bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
+ FrameLoaderClient::DetachedPluginPolicy policy = requireRenderer ? FrameLoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin;
+ widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, policy);
+ }
if (!widget) {
- if (!renderer->showsUnavailablePluginIndicator())
+ if (renderer && !renderer->showsUnavailablePluginIndicator())
renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
return false;
}
- renderer->setWidget(widget);
+ if (renderer) {
+ setWidget(widget);
+ m_persistedPluginWidget = nullptr;
+ } else if (widget != m_persistedPluginWidget) {
+ m_persistedPluginWidget = widget;
+ }
document().setContainsPlugins();
- setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ scheduleSVGFilterLayerUpdateHack();
return true;
}
@@ -482,9 +520,17 @@ bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
}
+void HTMLPlugInElement::dispatchErrorEvent()
+{
+ if (document().isPluginDocument() && document().ownerElement())
+ document().ownerElement()->dispatchEvent(Event::create(EventTypeNames::error));
+ else
+ dispatchEvent(Event::create(EventTypeNames::error));
+}
+
bool HTMLPlugInElement::pluginIsLoadable(const KURL& url, const String& mimeType)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
Settings* settings = frame->settings();
if (!settings)
return false;
@@ -517,10 +563,14 @@ void HTMLPlugInElement::didAddUserAgentShadowRoot(ShadowRoot&)
userAgentShadowRoot()->appendChild(HTMLContentElement::create(document()));
}
-void HTMLPlugInElement::didAddShadowRoot(ShadowRoot& root)
+void HTMLPlugInElement::willAddFirstAuthorShadowRoot()
+{
+ lazyReattachIfAttached();
+}
+
+bool HTMLPlugInElement::hasFallbackContent() const
{
- if (root.isOldestAuthorShadowRoot())
- lazyReattachIfAttached();
+ return false;
}
bool HTMLPlugInElement::useFallbackContent() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h
index 37d631466b5..9de4531c647 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h
@@ -25,6 +25,7 @@
#include "bindings/v8/SharedPersistent.h"
#include "core/html/HTMLFrameOwnerElement.h"
+#include <v8.h>
struct NPObject;
@@ -43,6 +44,7 @@ enum PreferPlugInsForImagesOption {
class HTMLPlugInElement : public HTMLFrameOwnerElement {
public:
virtual ~HTMLPlugInElement();
+ virtual void trace(Visitor*) OVERRIDE;
void resetInstance();
SharedPersistent<v8::Object>* pluginWrapper();
@@ -56,17 +58,22 @@ public:
void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
void updateWidget();
+ bool shouldAccelerate() const;
+
+ void requestPluginCreationWithoutRendererIfPossible();
+ void createPluginWithoutRenderer();
+
protected:
HTMLPlugInElement(const QualifiedName& tagName, Document&, bool createdByParser, PreferPlugInsForImagesOption);
// Node functions:
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
- virtual bool dispatchBeforeLoadEvent(const String& sourceURL) OVERRIDE;
// Element functions:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
+ virtual bool hasFallbackContent() const;
virtual bool useFallbackContent() const;
// Create or update the RenderWidget and return it, triggering layout if
// necessary.
@@ -79,10 +86,12 @@ protected:
bool requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues);
bool shouldUsePlugin(const KURL&, const String& mimeType, bool hasFallback, bool& useFallback);
+ void dispatchErrorEvent();
+
String m_serviceType;
String m_url;
KURL m_loadedUrl;
- OwnPtr<HTMLImageLoader> m_imageLoader;
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
bool m_isDelayingLoadEvent;
private:
@@ -91,24 +100,24 @@ private:
// Node functions:
virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
- virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void finishParsingChildren() OVERRIDE;
- virtual bool isPluginElement() const OVERRIDE;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE FINAL;
+ virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+ virtual void finishParsingChildren() OVERRIDE FINAL;
// Element functions:
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE FINAL;
- virtual bool supportsFocus() const OVERRIDE { return true; };
- virtual bool rendererIsFocusable() const OVERRIDE;
- virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
- virtual void didAddShadowRoot(ShadowRoot&) OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE FINAL { return true; }
+ virtual bool rendererIsFocusable() const OVERRIDE FINAL;
+ virtual bool isKeyboardFocusable() const OVERRIDE FINAL;
+ virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE FINAL;
+ virtual void willAddFirstAuthorShadowRoot() OVERRIDE FINAL;
// HTMLElement function:
virtual bool hasCustomFocusLogic() const OVERRIDE;
+ virtual bool isPluginElement() const OVERRIDE FINAL;
// Return any existing RenderWidget without triggering relayout, or 0 if it
// doesn't yet exist.
@@ -122,21 +131,36 @@ private:
};
DisplayState displayState() const { return m_displayState; }
void setDisplayState(DisplayState state) { m_displayState = state; }
- const String loadedMimeType() const;
- bool loadPlugin(const KURL&, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback);
+ bool loadPlugin(const KURL&, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireRenderer);
bool pluginIsLoadable(const KURL&, const String& mimeType);
bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
mutable RefPtr<SharedPersistent<v8::Object> > m_pluginWrapper;
NPObject* m_NPObject;
bool m_isCapturingMouseEvents;
- bool m_inBeforeLoadEventHandler;
bool m_needsWidgetUpdate;
bool m_shouldPreferPlugInsForImages;
DisplayState m_displayState;
+
+ // Normally the Widget is stored in HTMLFrameOwnerElement::m_widget.
+ // However, plugins can persist even when not rendered. In order to
+ // prevent confusing code which may assume that widget() != null
+ // means the frame is active, we save off m_widget here while
+ // the plugin is persisting but not being displayed.
+ RefPtr<Widget> m_persistedPluginWidget;
};
-DEFINE_NODE_TYPE_CASTS(HTMLPlugInElement, isPluginElement());
+inline bool isHTMLPlugInElement(const Element& element)
+{
+ return element.isHTMLElement() && toHTMLElement(element).isPluginElement();
+}
+
+inline bool isHTMLPlugInElement(const HTMLElement& element)
+{
+ return element.isPluginElement();
+}
+
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLPlugInElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
index 830f015f841..f8693761312 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
@@ -23,10 +23,11 @@
#include "config.h"
#include "core/html/HTMLPreElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
+#include "core/frame/UseCounter.h"
namespace WebCore {
@@ -38,10 +39,7 @@ inline HTMLPreElement::HTMLPreElement(const QualifiedName& tagName, Document& do
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLPreElement> HTMLPreElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLPreElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLPreElement)
bool HTMLPreElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -52,10 +50,12 @@ bool HTMLPreElement::isPresentationAttribute(const QualifiedName& name) const
void HTMLPreElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
- if (name == wrapAttr)
+ if (name == wrapAttr) {
+ UseCounter::count(document(), UseCounter::HTMLPreElementWrap);
style->setProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
- else
+ } else {
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
+ }
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h
index 408475f457d..0ae5a6affb5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLPreElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLPreElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLPreElement);
private:
HTMLPreElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl
index 3d035940d33..6224bc901f2 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl
@@ -19,11 +19,8 @@
*/
interface HTMLPreElement : HTMLElement {
- // FIXME: DOM spec says that width should be of type DOMString
- // see http://bugs.webkit.org/show_bug.cgi?id=8992
[Reflect] attribute long width;
// Extensions
- [Reflect] attribute boolean wrap;
+ [Reflect, MeasureAs=HTMLPreElementWrap] attribute boolean wrap;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp
index 3baeb6506a6..e8597d0d273 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp
@@ -22,10 +22,10 @@
#include "core/html/HTMLProgressElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -41,7 +41,7 @@ const double HTMLProgressElement::InvalidPosition = -2;
HTMLProgressElement::HTMLProgressElement(Document& document)
: LabelableElement(progressTag, document)
- , m_value(0)
+ , m_value(nullptr)
{
ScriptWrappable::init(this);
}
@@ -50,9 +50,9 @@ HTMLProgressElement::~HTMLProgressElement()
{
}
-PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLProgressElement> HTMLProgressElement::create(Document& document)
{
- RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(document));
+ RefPtrWillBeRawPtr<HTMLProgressElement> progress = adoptRefWillBeNoop(new HTMLProgressElement(document));
progress->ensureUserAgentShadowRoot();
return progress.release();
}
@@ -95,30 +95,30 @@ void HTMLProgressElement::attach(const AttachContext& context)
double HTMLProgressElement::value() const
{
double value = getFloatingPointAttribute(valueAttr);
+ // Otherwise, if the parsed value was greater than or equal to the maximum
+ // value, then the current value of the progress bar is the maximum value
+ // of the progress bar. Otherwise, if parsing the value attribute's value
+ // resulted in an error, or a number less than or equal to zero, then the
+ // current value of the progress bar is zero.
return !std::isfinite(value) || value < 0 ? 0 : std::min(value, max());
}
-void HTMLProgressElement::setValue(double value, ExceptionState& exceptionState)
+void HTMLProgressElement::setValue(double value)
{
- if (!std::isfinite(value)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(value));
- return;
- }
setFloatingPointAttribute(valueAttr, std::max(value, 0.));
}
double HTMLProgressElement::max() const
{
double max = getFloatingPointAttribute(maxAttr);
+ // Otherwise, if the element has no max attribute, or if it has one but
+ // parsing it resulted in an error, or if the parsed value was less than or
+ // equal to zero, then the maximum value of the progress bar is 1.0.
return !std::isfinite(max) || max <= 0 ? 1 : max;
}
-void HTMLProgressElement::setMax(double max, ExceptionState& exceptionState)
+void HTMLProgressElement::setMax(double max)
{
- if (!std::isfinite(max)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(max));
- return;
- }
// FIXME: The specification says we should ignore the input value if it is inferior or equal to 0.
setFloatingPointAttribute(maxAttr, max > 0 ? max : 1);
}
@@ -150,15 +150,15 @@ void HTMLProgressElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
ASSERT(!m_value);
- RefPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
- inner->setPseudo(AtomicString("-webkit-progress-inner-element", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
+ inner->setShadowPseudoId(AtomicString("-webkit-progress-inner-element", AtomicString::ConstructFromLiteral));
root.appendChild(inner);
- RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
- bar->setPseudo(AtomicString("-webkit-progress-bar", AtomicString::ConstructFromLiteral));
- RefPtr<ProgressValueElement> value = ProgressValueElement::create(document());
+ RefPtrWillBeRawPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
+ bar->setShadowPseudoId(AtomicString("-webkit-progress-bar", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<ProgressValueElement> value = ProgressValueElement::create(document());
m_value = value.get();
- m_value->setPseudo(AtomicString("-webkit-progress-value", AtomicString::ConstructFromLiteral));
+ m_value->setShadowPseudoId(AtomicString("-webkit-progress-value", AtomicString::ConstructFromLiteral));
m_value->setWidthPercentage(HTMLProgressElement::IndeterminatePosition * 100);
bar->appendChild(m_value);
@@ -170,4 +170,10 @@ bool HTMLProgressElement::shouldAppearIndeterminate() const
return !isDeterminate();
}
+void HTMLProgressElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ LabelableElement::trace(visitor);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h
index 6162ded1570..cce0dfbbb64 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h
@@ -34,17 +34,19 @@ public:
static const double IndeterminatePosition;
static const double InvalidPosition;
- static PassRefPtr<HTMLProgressElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLProgressElement> create(Document&);
double value() const;
- void setValue(double, ExceptionState&);
+ void setValue(double);
double max() const;
- void setMax(double, ExceptionState&);
+ void setMax(double);
double position() const;
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit HTMLProgressElement(Document&);
@@ -54,7 +56,7 @@ private:
virtual bool shouldAppearIndeterminate() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
RenderProgress* renderProgress() const;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
@@ -65,17 +67,9 @@ private:
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
bool isDeterminate() const;
- ProgressValueElement* m_value;
+ RawPtrWillBeMember<ProgressValueElement> m_value;
};
-inline bool isHTMLProgressElement(Node* node)
-{
- ASSERT(node);
- return node->hasTagName(HTMLNames::progressTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLProgressElement, hasTagName(HTMLNames::progressTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl
index b2f5a9cdbba..a3da90a39e7 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl
@@ -17,10 +17,13 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLProgressElement : HTMLElement {
- [RaisesException=Setter] attribute double value;
- [RaisesException=Setter] attribute double max;
- readonly attribute double position;
- readonly attribute NodeList labels;
-};
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#htmlprogresselement
+[
+ TypeChecking=Unrestricted,
+] interface HTMLProgressElement : HTMLElement {
+ attribute double value;
+ attribute double max;
+ readonly attribute double position;
+ readonly attribute NodeList labels;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp
index ff18c6006e4..228af64484d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLQuoteElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/StyleEngine.h"
@@ -38,14 +38,21 @@ inline HTMLQuoteElement::HTMLQuoteElement(const QualifiedName& tagName, Document
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLQuoteElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLQuoteElement)
bool HTMLQuoteElement::isURLAttribute(const Attribute& attribute) const
{
return attribute.name() == citeAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLQuoteElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == citeAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLQuoteElement::subResourceAttributeName() const
+{
+ return citeAttr;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h
index bfdc9ee176a..fcf12adcf85 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h
@@ -31,12 +31,14 @@ namespace WebCore {
class HTMLQuoteElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLQuoteElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLQuoteElement);
private:
HTMLQuoteElement(const QualifiedName&, Document&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl
index 93a2aff07ea..db0ab9dd9ca 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl
@@ -18,5 +18,5 @@
*/
interface HTMLQuoteElement : HTMLElement {
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString cite;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString cite;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp
new file mode 100644
index 00000000000..d1fb7c03f22
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLRTElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/rendering/RenderRubyText.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLRTElement::HTMLRTElement(Document& document)
+ : HTMLElement(rtTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLRTElement)
+
+RenderObject* HTMLRTElement::createRenderer(RenderStyle* style)
+{
+ if (style->display() == BLOCK)
+ return new RenderRubyText(this);
+ return RenderObject::createObject(this, style);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h
new file mode 100644
index 00000000000..eea1e94bf30
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLRTElement_h
+#define HTMLRTElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <rt> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's createRenderer doesn't need to know about it.
+class HTMLRTElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLRTElement);
+
+private:
+ explicit HTMLRTElement(Document&);
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp
new file mode 100644
index 00000000000..ab6febd1ecc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLRubyElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/rendering/RenderRuby.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLRubyElement::HTMLRubyElement(Document& document)
+ : HTMLElement(rubyTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLRubyElement)
+
+RenderObject* HTMLRubyElement::createRenderer(RenderStyle* style)
+{
+ if (style->display() == INLINE)
+ return new RenderRubyAsInline(this);
+ if (style->display() == BLOCK)
+ return new RenderRubyAsBlock(this);
+ return RenderObject::createObject(this, style);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h
new file mode 100644
index 00000000000..bf177a6daae
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLRubyElement_h
+#define HTMLRubyElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <ruby> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's createRenderer doesn't need to know about it.
+class HTMLRubyElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLRubyElement);
+
+private:
+ explicit HTMLRubyElement(Document&);
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
index fd54cc283c2..ce1adaf24a7 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
@@ -23,15 +23,14 @@
#include "config.h"
#include "core/html/HTMLScriptElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ScriptLoader.h"
#include "core/dom/Text.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -44,9 +43,9 @@ inline HTMLScriptElement::HTMLScriptElement(Document& document, bool wasInserted
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(Document& document, bool wasInsertedByParser, bool alreadyStarted)
+PassRefPtrWillBeRawPtr<HTMLScriptElement> HTMLScriptElement::create(Document& document, bool wasInsertedByParser, bool alreadyStarted)
{
- return adoptRef(new HTMLScriptElement(document, wasInsertedByParser, alreadyStarted));
+ return adoptRefWillBeNoop(new HTMLScriptElement(document, wasInsertedByParser, alreadyStarted));
}
bool HTMLScriptElement::isURLAttribute(const Attribute& attribute) const
@@ -54,6 +53,16 @@ bool HTMLScriptElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLScriptElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLScriptElement::subResourceAttributeName() const
+{
+ return srcAttr;
+}
+
void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
@@ -66,8 +75,6 @@ void HTMLScriptElement::parseAttribute(const QualifiedName& name, const AtomicSt
m_loader->handleSourceAttribute(value);
else if (name == asyncAttr)
m_loader->handleAsyncAttribute();
- else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
else
HTMLElement::parseAttribute(name, value);
}
@@ -85,7 +92,7 @@ void HTMLScriptElement::didNotifySubtreeInsertionsToDocument()
void HTMLScriptElement::setText(const String &value)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
if (hasOneTextChild()) {
toText(firstChild())->setData(value);
@@ -112,13 +119,6 @@ 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();
@@ -170,9 +170,9 @@ void HTMLScriptElement::dispatchLoadEvent()
dispatchEvent(Event::create(EventTypeNames::load));
}
-PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren()
{
- return adoptRef(new HTMLScriptElement(document(), false, m_loader->alreadyStarted()));
+ return adoptRefWillBeNoop(new HTMLScriptElement(document(), false, m_loader->alreadyStarted()));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h
index d4e0efd047e..9dbc0c86fa4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h
@@ -33,7 +33,7 @@ class ScriptLoader;
class HTMLScriptElement FINAL : public HTMLElement, public ScriptLoaderClient {
public:
- static PassRefPtr<HTMLScriptElement> create(Document&, bool wasInsertedByParser, bool alreadyStarted = false);
+ static PassRefPtrWillBeRawPtr<HTMLScriptElement> create(Document&, bool wasInsertedByParser, bool alreadyStarted = false);
String text() { return textFromChildren(); }
void setText(const String&);
@@ -51,31 +51,29 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual String sourceAttributeValue() const OVERRIDE;
+ virtual String charsetAttributeValue() const OVERRIDE;
+ virtual String typeAttributeValue() const OVERRIDE;
+ virtual String languageAttributeValue() const OVERRIDE;
+ virtual String forAttributeValue() const OVERRIDE;
+ virtual String eventAttributeValue() const OVERRIDE;
+ virtual bool asyncAttributeValue() const OVERRIDE;
+ virtual bool deferAttributeValue() const OVERRIDE;
+ virtual bool hasSourceAttribute() const OVERRIDE;
- 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 bool hasSourceAttribute() const;
+ virtual void dispatchLoadEvent() OVERRIDE;
- virtual void dispatchLoadEvent();
-
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
OwnPtr<ScriptLoader> m_loader;
};
-DEFINE_NODE_TYPE_CASTS(HTMLScriptElement, hasTagName(HTMLNames::scriptTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
index 1f1e260a7f9..71b542261e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
@@ -24,8 +24,10 @@ interface HTMLScriptElement : HTMLElement {
[Reflect] attribute DOMString charset;
attribute boolean async;
[Reflect] attribute boolean defer;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
[Reflect] attribute DOMString type;
- [Reflect] attribute DOMString crossOrigin;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
[Reflect, RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] attribute DOMString nonce;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index 8d8332a3e86..b0dc747ff14 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -28,24 +28,23 @@
#include "config.h"
#include "core/html/HTMLSelectElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Attribute.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeTraversal.h"
+#include "core/events/GestureEvent.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLFormElement.h"
-#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/forms/FormController.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/page/SpatialNavigation.h"
#include "core/rendering/RenderListBox.h"
#include "core/rendering/RenderMenuList.h"
@@ -53,7 +52,6 @@
#include "platform/PlatformMouseEvent.h"
#include "platform/text/PlatformLocale.h"
-using namespace std;
using namespace WTF::Unicode;
namespace WebCore {
@@ -63,7 +61,7 @@ using namespace HTMLNames;
// Upper limit agreed upon with representatives of Opera and Mozilla.
static const unsigned maxSelectItems = 10000;
-HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form, bool createdByParser)
+HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form)
: HTMLFormControlElementWithState(selectTag, document, form)
, m_typeAhead(this)
, m_size(0)
@@ -74,19 +72,20 @@ HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form,
, m_multiple(false)
, m_activeSelectionState(false)
, m_shouldRecalcListItems(false)
- , m_isParsingInProgress(createdByParser)
+ , m_suggestedIndex(-1)
{
ScriptWrappable::init(this);
+ setHasCustomStyleCallbacks();
}
-PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document)
{
- return adoptRef(new HTMLSelectElement(document, 0, false));
+ return adoptRefWillBeNoop(new HTMLSelectElement(document, 0));
}
-PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLSelectElement(document, form, createdByParser));
+ return adoptRefWillBeNoop(new HTMLSelectElement(document, form));
}
const AtomicString& HTMLSelectElement::formControlType() const
@@ -96,12 +95,6 @@ const AtomicString& HTMLSelectElement::formControlType() const
return m_multiple ? selectMultiple : selectOne;
}
-void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
-{
- deselectItemsWithoutValidation(excludeElement);
- setNeedsValidityCheck();
-}
-
void HTMLSelectElement::optionSelectedByUser(int optionIndex, bool fireOnChangeNow, bool allowMultipleSelection)
{
// User interaction such as mousedown events can cause list box select elements to send change events.
@@ -121,7 +114,7 @@ void HTMLSelectElement::optionSelectedByUser(int optionIndex, bool fireOnChangeN
if (optionIndex == selectedIndex())
return;
- selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchChangeEvent : 0) | UserDriven);
+ selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchInputAndChangeEvent : 0) | UserDriven);
}
bool HTMLSelectElement::hasPlaceholderLabelOption() const
@@ -209,15 +202,21 @@ int HTMLSelectElement::activeSelectionEndListIndex() const
void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, ExceptionState& exceptionState)
{
// Make sure the element is ref'd and deref'd so we don't leak it.
- RefPtr<HTMLElement> protectNewChild(element);
+ RefPtrWillBeRawPtr<HTMLElement> protectNewChild(element);
- if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
+ if (!element || !(isHTMLOptionElement(element) || isHTMLOptGroupElement(element) || isHTMLHRElement(element)))
return;
insertBefore(element, before, exceptionState);
setNeedsValidityCheck();
}
+void HTMLSelectElement::addBeforeOptionAtIndex(HTMLElement* element, int beforeIndex, ExceptionState& exceptionState)
+{
+ HTMLElement* beforeElement = toHTMLElement(options()->item(beforeIndex));
+ add(element, beforeElement, exceptionState);
+}
+
void HTMLSelectElement::remove(int optionIndex)
{
int listIndex = optionToListIndex(optionIndex);
@@ -227,46 +226,80 @@ void HTMLSelectElement::remove(int optionIndex)
listItems()[listIndex]->remove(IGNORE_EXCEPTION);
}
-void HTMLSelectElement::remove(HTMLOptionElement* option)
-{
- if (option->ownerSelectElement() != this)
- return;
-
- option->remove(IGNORE_EXCEPTION);
-}
-
String HTMLSelectElement::value() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag) && toHTMLOptionElement(items[i])->selected())
+ if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->selected())
return toHTMLOptionElement(items[i])->value();
}
return "";
}
-void HTMLSelectElement::setValue(const String &value)
+void HTMLSelectElement::setValue(const String &value, bool sendEvents)
{
// We clear the previously selected option(s) when needed, to guarantee calling setSelectedIndex() only once.
+ int optionIndex = 0;
+ if (value.isNull()) {
+ optionIndex = -1;
+ } else {
+ // Find the option with value() matching the given parameter and make it the current selection.
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
+ for (unsigned i = 0; i < items.size(); i++) {
+ if (isHTMLOptionElement(items[i])) {
+ if (toHTMLOptionElement(items[i])->value() == value)
+ break;
+ optionIndex++;
+ }
+ }
+ if (optionIndex >= static_cast<int>(items.size()))
+ optionIndex = -1;
+ }
+
+ int previousSelectedIndex = selectedIndex();
+ setSuggestedIndex(-1);
+ setSelectedIndex(optionIndex);
+
+ if (sendEvents && previousSelectedIndex != selectedIndex()) {
+ if (usesMenuList())
+ dispatchInputAndChangeEventForMenuList(false);
+ else
+ listBoxOnChange();
+ }
+}
+
+String HTMLSelectElement::suggestedValue() const
+{
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
+ for (unsigned i = 0; i < items.size(); ++i) {
+ if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) {
+ if (i == static_cast<unsigned>(m_suggestedIndex))
+ return toHTMLOptionElement(items[i])->value();
+ }
+ }
+ return "";
+}
+
+void HTMLSelectElement::setSuggestedValue(const String& value)
+{
if (value.isNull()) {
- setSelectedIndex(-1);
+ setSuggestedIndex(-1);
return;
}
- // Find the option with value() matching the given parameter and make it the current selection.
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
unsigned optionIndex = 0;
- for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
+ for (unsigned i = 0; i < items.size(); ++i) {
+ if (isHTMLOptionElement(items[i])) {
if (toHTMLOptionElement(items[i])->value() == value) {
- setSelectedIndex(optionIndex);
+ setSuggestedIndex(optionIndex);
return;
}
optionIndex++;
}
}
- setSelectedIndex(-1);
+ setSuggestedIndex(-1);
}
bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const
@@ -290,10 +323,10 @@ void HTMLSelectElement::parseAttribute(const QualifiedName& name, const AtomicSt
AtomicString attrSize = AtomicString::number(size);
if (attrSize != value) {
// FIXME: This is horribly factored.
- if (Attribute* sizeAttribute = ensureUniqueElementData()->getAttributeItem(sizeAttr))
+ if (Attribute* sizeAttribute = ensureUniqueElementData().findAttributeByName(sizeAttr))
sizeAttribute->setValue(attrSize);
}
- size = max(size, 1);
+ size = std::max(size, 1);
// Ensure that we've determined selectedness of the items at least once prior to changing the size.
if (oldSize != size)
@@ -310,6 +343,15 @@ void HTMLSelectElement::parseAttribute(const QualifiedName& name, const AtomicSt
else if (name == accesskeyAttr) {
// FIXME: ignore for the moment.
//
+ } else if (name == disabledAttr) {
+ HTMLFormControlElementWithState::parseAttribute(name, value);
+ if (renderer() && renderer()->isMenuList()) {
+ if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
+ if (menuList->popupIsVisible())
+ menuList->hidePopup();
+ }
+ }
+
} else
HTMLFormControlElementWithState::parseAttribute(name, value);
}
@@ -331,24 +373,15 @@ RenderObject* HTMLSelectElement::createRenderer(RenderStyle*)
return new RenderListBox(this);
}
-bool HTMLSelectElement::childShouldCreateRenderer(const Node& child) const
-{
- if (!HTMLFormControlElementWithState::childShouldCreateRenderer(child))
- return false;
- if (!usesMenuList())
- return child.hasTagName(HTMLNames::optionTag) || isHTMLOptGroupElement(&child);
- return false;
-}
-
-PassRefPtr<HTMLCollection> HTMLSelectElement::selectedOptions()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLSelectElement::selectedOptions()
{
updateListItemSelectedStates();
return ensureCachedHTMLCollection(SelectedOptions);
}
-PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
+PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLSelectElement::options()
{
- return static_cast<HTMLOptionsCollection*>(ensureCachedHTMLCollection(SelectOptions).get());
+ return toHTMLOptionsCollection(ensureCachedHTMLCollection(SelectOptions).get());
}
void HTMLSelectElement::updateListItemSelectedStates()
@@ -402,12 +435,12 @@ void HTMLSelectElement::setSize(int size)
setIntegralAttribute(sizeAttr, size);
}
-Node* HTMLSelectElement::namedItem(const AtomicString& name)
+Element* HTMLSelectElement::namedItem(const AtomicString& name)
{
return options()->namedItem(name);
}
-Node* HTMLSelectElement::item(unsigned index)
+Element* HTMLSelectElement::item(unsigned index)
{
return options()->item(index);
}
@@ -417,7 +450,7 @@ void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
if (index > maxSelectItems - 1)
index = maxSelectItems - 1;
int diff = index - length();
- RefPtr<HTMLElement> before = 0;
+ RefPtrWillBeRawPtr<HTMLElement> before = nullptr;
// Out of array bounds? First insert empty dummies.
if (diff > 0) {
setLength(index, exceptionState);
@@ -442,22 +475,22 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionState& exceptionStat
if (diff < 0) { // Add dummy elements.
do {
- RefPtr<Element> option = document().createElement(optionTag, false);
+ RefPtrWillBeRawPtr<Element> option = document().createElement(optionTag, false);
ASSERT(option);
add(toHTMLElement(option), 0, exceptionState);
if (exceptionState.hadException())
break;
} while (++diff);
} else {
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& 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;
+ WillBeHeapVector<RefPtrWillBeMember<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) {
+ if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) {
ASSERT(item->parentNode());
itemsToRemove.append(item);
}
@@ -484,16 +517,17 @@ bool HTMLSelectElement::isRequiredFormControl() const
int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, int skip) const
{
ASSERT(direction == -1 || direction == 1);
- const Vector<HTMLElement*>& listItems = this->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->listItems();
int lastGoodIndex = listIndex;
int size = listItems.size();
for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex += direction) {
--skip;
- if (!listItems[listIndex]->isDisabledFormControl() && listItems[listIndex]->hasTagName(optionTag)) {
- lastGoodIndex = listIndex;
- if (skip <= 0)
- break;
- }
+ HTMLElement* element = listItems[listIndex];
+ if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl() || toHTMLOptionElement(element)->isDisplayNone())
+ continue;
+ lastGoodIndex = listIndex;
+ if (skip <= 0)
+ break;
}
return lastGoodIndex;
}
@@ -512,7 +546,7 @@ int HTMLSelectElement::previousSelectableListIndex(int startIndex) const
int HTMLSelectElement::firstSelectableListIndex() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int index = nextValidIndex(items.size(), SkipBackwards, INT_MAX);
if (static_cast<size_t>(index) == items.size())
return -1;
@@ -527,7 +561,7 @@ int HTMLSelectElement::lastSelectableListIndex() const
// Returns the index of the next valid item one page away from |startIndex| in direction |direction|.
int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirection direction) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
// Can't use m_size because renderer forces a minimum size.
int pageSize = 0;
if (renderer()->isListBox())
@@ -568,10 +602,10 @@ void HTMLSelectElement::saveLastSelection()
}
m_lastOnChangeSelection.clear();
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- m_lastOnChangeSelection.append(element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected());
+ m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
}
}
@@ -583,10 +617,10 @@ void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
// selection pivots around this anchor index.
m_cachedStateForActiveSelection.clear();
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- m_cachedStateForActiveSelection.append(element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected());
+ m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
}
}
@@ -600,13 +634,13 @@ void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
ASSERT(renderer() && (renderer()->isListBox() || m_multiple));
ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0);
- unsigned start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
- unsigned end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
+ unsigned start = std::min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
+ unsigned end = std::max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
+ if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl() || toHTMLOptionElement(element)->isDisplayNone())
continue;
if (i >= start && i <= end)
@@ -626,7 +660,7 @@ void HTMLSelectElement::listBoxOnChange()
{
ASSERT(!usesMenuList() || m_multiple);
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
// If the cached selection list is empty, or the size has changed, then fire
// dispatchFormControlChangeEvent, and return early.
@@ -640,24 +674,29 @@ void HTMLSelectElement::listBoxOnChange()
bool fireOnChange = false;
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- bool selected = element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
+ bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected();
if (selected != m_lastOnChangeSelection[i])
fireOnChange = true;
m_lastOnChangeSelection[i] = selected;
}
- if (fireOnChange)
+ if (fireOnChange) {
+ RefPtrWillBeRawPtr<HTMLSelectElement> protector(this);
+ dispatchInputEvent();
dispatchFormControlChangeEvent();
+ }
}
-void HTMLSelectElement::dispatchChangeEventForMenuList()
+void HTMLSelectElement::dispatchInputAndChangeEventForMenuList(bool requiresUserGesture)
{
ASSERT(usesMenuList());
int selected = selectedIndex();
- if (m_lastOnChangeIndex != selected && m_isProcessingUserDrivenChange) {
+ if (m_lastOnChangeIndex != selected && (!requiresUserGesture || m_isProcessingUserDrivenChange)) {
m_lastOnChangeIndex = selected;
m_isProcessingUserDrivenChange = false;
+ RefPtrWillBeRawPtr<HTMLSelectElement> protector(this);
+ dispatchInputEvent();
dispatchFormControlChangeEvent();
}
}
@@ -681,13 +720,13 @@ void HTMLSelectElement::setOptionsChangedOnRenderer()
}
}
-const Vector<HTMLElement*>& HTMLSelectElement::listItems() const
+const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& HTMLSelectElement::listItems() const
{
if (m_shouldRecalcListItems)
recalcListItems();
else {
-#if !ASSERT_DISABLED
- Vector<HTMLElement*> items = m_listItems;
+#if ASSERT_ENABLED
+ WillBeHeapVector<RawPtrWillBeMember<HTMLElement> > items = m_listItems;
recalcListItems(false);
ASSERT(items == m_listItems);
#endif
@@ -711,7 +750,7 @@ void HTMLSelectElement::setRecalcListItems()
// Manual selection anchor is reset when manipulating the select programmatically.
m_activeSelectionAnchorIndex = -1;
setOptionsChangedOnRenderer();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (!inDocument()) {
if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions))
collection->invalidateCache();
@@ -751,7 +790,7 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
}
}
- if (current.hasTagName(optionTag)) {
+ if (isHTMLOptionElement(current)) {
m_listItems.append(&current);
if (updateSelectedStates && !m_multiple) {
@@ -769,7 +808,7 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
}
}
- if (current.hasTagName(hrTag))
+ if (isHTMLHRElement(current))
m_listItems.append(&current);
// In conforming HTML code, only <optgroup> and <option> will be found
@@ -790,11 +829,11 @@ int HTMLSelectElement::selectedIndex() const
unsigned index = 0;
// Return the number of the first option selected.
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (size_t i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element->hasTagName(optionTag)) {
- if (toHTMLOptionElement(element)->selected())
+ if (isHTMLOptionElement(*element)) {
+ if (toHTMLOptionElement(*element).selected())
return index;
++index;
}
@@ -808,6 +847,22 @@ void HTMLSelectElement::setSelectedIndex(int index)
selectOption(index, DeselectOtherOptions);
}
+int HTMLSelectElement::suggestedIndex() const
+{
+ return m_suggestedIndex;
+}
+
+void HTMLSelectElement::setSuggestedIndex(int suggestedIndex)
+{
+ m_suggestedIndex = suggestedIndex;
+
+ if (RenderObject* renderer = this->renderer()) {
+ renderer->updateFromElement();
+ if (renderer->isListBox())
+ toRenderListBox(renderer)->scrollToRevealElementAtListIndex(suggestedIndex);
+ }
+}
+
void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, bool optionIsSelected)
{
ASSERT(option->ownerSelectElement() == this);
@@ -823,18 +878,18 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
{
bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions);
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int listIndex = optionToListIndex(optionIndex);
HTMLElement* element = 0;
if (listIndex >= 0) {
element = items[listIndex];
- if (element->hasTagName(optionTag)) {
+ if (isHTMLOptionElement(*element)) {
if (m_activeSelectionAnchorIndex < 0 || shouldDeselect)
setActiveSelectionAnchorIndex(listIndex);
if (m_activeSelectionEndIndex < 0 || shouldDeselect)
setActiveSelectionEndIndex(listIndex);
- toHTMLOptionElement(element)->setSelectedState(true);
+ toHTMLOptionElement(*element).setSelectedState(true);
}
}
@@ -847,10 +902,12 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
scrollToSelection();
+ setNeedsValidityCheck();
+
if (usesMenuList()) {
m_isProcessingUserDrivenChange = flags & UserDriven;
- if (flags & DispatchChangeEvent)
- dispatchChangeEventForMenuList();
+ if (flags & DispatchInputAndChangeEvent)
+ dispatchInputAndChangeEventForMenuList();
if (RenderObject* renderer = this->renderer()) {
if (usesMenuList())
toRenderMenuList(renderer)->didSetSelectedIndex(listIndex);
@@ -859,20 +916,19 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
}
}
- setNeedsValidityCheck();
notifyFormStateChanged();
}
int HTMLSelectElement::optionToListIndex(int optionIndex) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int listSize = static_cast<int>(items.size());
if (optionIndex < 0 || optionIndex >= listSize)
return -1;
int optionIndex2 = -1;
for (int listIndex = 0; listIndex < listSize; ++listIndex) {
- if (items[listIndex]->hasTagName(optionTag)) {
+ if (isHTMLOptionElement(*items[listIndex])) {
++optionIndex2;
if (optionIndex2 == optionIndex)
return listIndex;
@@ -884,27 +940,27 @@ int HTMLSelectElement::optionToListIndex(int optionIndex) const
int HTMLSelectElement::listToOptionIndex(int listIndex) const
{
- const Vector<HTMLElement*>& items = listItems();
- if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !items[listIndex]->hasTagName(optionTag))
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
+ if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLOptionElement(*items[listIndex]))
return -1;
// Actual index of option not counting OPTGROUP entries that may be in list.
int optionIndex = 0;
for (int i = 0; i < listIndex; ++i) {
- if (items[i]->hasTagName(optionTag))
+ if (isHTMLOptionElement(*items[i]))
++optionIndex;
}
return optionIndex;
}
-void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
{
// Save the selection so it can be compared to the new selection when
// dispatching change events during blur event dispatch.
if (usesMenuList())
saveLastSelection();
- HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
+ HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, type);
}
void HTMLSelectElement::dispatchBlurEvent(Element* newFocusedElement)
@@ -913,27 +969,27 @@ void HTMLSelectElement::dispatchBlurEvent(Element* newFocusedElement)
// change events for list boxes whenever the selection change is actually made.
// This matches other browsers' behavior.
if (usesMenuList())
- dispatchChangeEventForMenuList();
+ dispatchInputAndChangeEventForMenuList();
HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
}
void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeElement)
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element != excludeElement && element->hasTagName(optionTag))
+ if (element != excludeElement && isHTMLOptionElement(*element))
toHTMLOptionElement(element)->setSelectedState(false);
}
}
FormControlState HTMLSelectElement::saveFormControlState() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
size_t length = items.size();
FormControlState state;
for (unsigned i = 0; i < length; ++i) {
- if (!items[i]->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*items[i]))
continue;
HTMLOptionElement* option = toHTMLOptionElement(items[i]);
if (!option->selected())
@@ -947,10 +1003,10 @@ FormControlState HTMLSelectElement::saveFormControlState() const
size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t listIndexStart, size_t listIndexEnd) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
size_t loopEndIndex = std::min(items.size(), listIndexEnd);
for (size_t i = listIndexStart; i < loopEndIndex; ++i) {
- if (!items[i]->hasLocalName(optionTag))
+ if (!isHTMLOptionElement(items[i]))
continue;
if (toHTMLOptionElement(items[i])->value() == value)
return i;
@@ -962,13 +1018,13 @@ void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
{
recalcListItems();
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
size_t itemsSize = items.size();
if (!itemsSize)
return;
for (size_t i = 0; i < itemsSize; ++i) {
- if (!items[i]->hasLocalName(optionTag))
+ if (!isHTMLOptionElement(items[i]))
continue;
toHTMLOptionElement(items[i])->setSelectedState(false);
}
@@ -1011,12 +1067,12 @@ bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
return false;
bool successful = false;
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected() && !toHTMLOptionElement(element)->isDisabledFormControl()) {
- list.appendData(name, toHTMLOptionElement(element)->value());
+ if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selected() && !toHTMLOptionElement(*element).isDisabledFormControl()) {
+ list.appendData(name, toHTMLOptionElement(*element).value());
successful = true;
}
}
@@ -1032,10 +1088,10 @@ void HTMLSelectElement::resetImpl()
HTMLOptionElement* firstOption = 0;
HTMLOptionElement* selectedOption = 0;
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (!element->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*element))
continue;
if (items[i]->fastHasAttribute(selectedAttr)) {
@@ -1054,7 +1110,7 @@ void HTMLSelectElement::resetImpl()
firstOption->setSelectedState(true);
setOptionsChangedOnRenderer();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
setNeedsValidityCheck();
}
@@ -1070,7 +1126,7 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
// Calling focus() may cause us to lose our renderer. Return true so
// that our caller doesn't process the event further, but don't set
// the event as handled.
- if (!renderer())
+ if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
return true;
// Save the selection so it can be compared to the new selection
@@ -1110,7 +1166,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier();
bool handled = true;
- const Vector<HTMLElement*>& listItems = this->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->listItems();
int listIndex = optionToListIndex(selectedIndex());
if (keyIdentifier == "Down" || keyIdentifier == "Right")
@@ -1129,7 +1185,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
handled = false;
if (handled && static_cast<size_t>(listIndex) < listItems.size())
- selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
+ selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchInputAndChangeEvent | UserDriven);
if (handled)
event->setDefaultHandled();
@@ -1157,7 +1213,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// Calling focus() may remove the renderer or change the
// renderer type.
- if (!renderer() || !renderer()->isMenuList())
+ if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
return;
// Save the selection so it can be compared to the new selection
@@ -1175,7 +1231,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// Calling focus() may remove the renderer or change the
// renderer type.
- if (!renderer() || !renderer()->isMenuList())
+ if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
return;
// Save the selection so it can be compared to the new selection
@@ -1189,7 +1245,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
} else if (keyCode == '\r') {
if (form())
form()->submitImplicitly(event, false);
- dispatchChangeEventForMenuList();
+ dispatchInputAndChangeEventForMenuList();
handled = true;
}
}
@@ -1200,7 +1256,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
focus();
- if (renderer() && renderer()->isMenuList()) {
+ if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) {
if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
if (menuList->popupIsVisible())
menuList->hidePopup();
@@ -1230,6 +1286,11 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
{
ASSERT(listIndex >= 0);
+ HTMLElement* clickedElement = listItems()[listIndex];
+ ASSERT(clickedElement);
+ if (isHTMLOptGroupElement(clickedElement))
+ return;
+
// Save the selection so it can be compared to the new selection when
// dispatching change events during mouseup, or after autoscroll finishes.
saveLastSelection();
@@ -1239,14 +1300,13 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
bool shiftSelect = m_multiple && shift;
bool multiSelect = m_multiple && multi && !shift;
- HTMLElement* clickedElement = listItems()[listIndex];
- if (clickedElement->hasTagName(optionTag)) {
+ if (isHTMLOptionElement(*clickedElement)) {
// Keep track of whether an active selection (like during drag
// selection), should select or deselect.
- if (toHTMLOptionElement(clickedElement)->selected() && multiSelect)
+ if (toHTMLOptionElement(*clickedElement).selected() && multiSelect)
m_activeSelectionState = false;
if (!m_activeSelectionState)
- toHTMLOptionElement(clickedElement)->setSelectedState(false);
+ toHTMLOptionElement(*clickedElement).setSelectedState(false);
}
// If we're not in any special multiple selection mode, then deselect all
@@ -1261,8 +1321,8 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
setActiveSelectionAnchorIndex(selectedIndex());
// Set the selection state of the clicked option.
- if (clickedElement->hasTagName(optionTag) && !toHTMLOptionElement(clickedElement)->isDisabledFormControl())
- toHTMLOptionElement(clickedElement)->setSelectedState(true);
+ if (isHTMLOptionElement(*clickedElement) && !toHTMLOptionElement(*clickedElement).isDisabledFormControl())
+ toHTMLOptionElement(*clickedElement).setSelectedState(true);
// If there was no selectedIndex() for the previous initialization, or If
// we're doing a single selection, or a multiple selection (using cmd or
@@ -1277,12 +1337,26 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
{
- const Vector<HTMLElement*>& listItems = this->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->listItems();
+ if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent()) {
+ focus();
+ // Calling focus() may cause us to lose our renderer or change the render type, in which case do not want to handle the event.
+ if (!renderer() || !renderer()->isListBox())
+ return;
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
+ // Convert to coords relative to the list box if needed.
+ GestureEvent& gestureEvent = toGestureEvent(*event);
+ IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(gestureEvent.absoluteLocation(), UseTransforms));
+ int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset));
+ if (listIndex >= 0) {
+ if (!isDisabledFormControl())
+ updateSelectedState(listIndex, true, gestureEvent.shiftKey());
+ event->setDefaultHandled();
+ }
+ } else if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
focus();
// Calling focus() may cause us to lose our renderer, in which case do not want to handle the event.
- if (!renderer())
+ if (!renderer() || !renderer()->isListBox() || isDisabledFormControl())
return;
// Convert to coords relative to the list box if needed.
@@ -1297,7 +1371,7 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent->shiftKey());
#endif
}
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().setMouseDownMayStartAutoscroll();
event->setDefaultHandled();
@@ -1324,15 +1398,11 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
updateListBoxSelection(true);
}
}
- event->setDefaultHandled();
}
} else if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton && renderer() && !toRenderBox(renderer())->autoscrollInProgress()) {
// We didn't start this click/drag on any options.
if (m_lastOnChangeSelection.isEmpty())
return;
- // This makes sure we fire dispatchFormControlChangeEvent for a single
- // click. For drag selection, onChange will fire when the autoscroll
- // timer stops.
listBoxOnChange();
} else if (event->type() == EventTypeNames::keydown) {
if (!event->isKeyboardEvent())
@@ -1466,10 +1536,10 @@ void HTMLSelectElement::defaultEventHandler(Event* event)
int HTMLSelectElement::lastSelectedListIndex() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (size_t i = items.size(); i;) {
HTMLElement* element = items[--i];
- if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected())
+ if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected())
return i;
}
return -1;
@@ -1487,10 +1557,10 @@ int HTMLSelectElement::optionCount() const
String HTMLSelectElement::optionAtIndex(int index) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
HTMLElement* element = items[index];
- if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
+ if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl())
return String();
return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
}
@@ -1500,7 +1570,7 @@ void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar);
if (index < 0)
return;
- selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
+ selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchInputAndChangeEvent | UserDriven);
if (!usesMenuList())
listBoxOnChange();
}
@@ -1522,20 +1592,20 @@ void HTMLSelectElement::accessKeySetSelectedIndex(int index)
accessKeyAction(false);
// If this index is already selected, unselect. otherwise update the selected index.
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int listIndex = optionToListIndex(index);
if (listIndex >= 0) {
HTMLElement* element = items[listIndex];
- if (element->hasTagName(optionTag)) {
- if (toHTMLOptionElement(element)->selected())
- toHTMLOptionElement(element)->setSelectedState(false);
+ if (isHTMLOptionElement(*element)) {
+ if (toHTMLOptionElement(*element).selected())
+ toHTMLOptionElement(*element).setSelectedState(false);
else
- selectOption(index, DispatchChangeEvent | UserDriven);
+ selectOption(index, DispatchInputAndChangeEvent | UserDriven);
}
}
if (usesMenuList())
- dispatchChangeEventForMenuList();
+ dispatchInputAndChangeEventForMenuList();
else
listBoxOnChange();
@@ -1546,9 +1616,9 @@ unsigned HTMLSelectElement::length() const
{
unsigned options = 0;
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- if (items[i]->hasTagName(optionTag))
+ if (isHTMLOptionElement(*items[i]))
++options;
}
@@ -1558,29 +1628,40 @@ unsigned HTMLSelectElement::length() const
void HTMLSelectElement::finishParsingChildren()
{
HTMLFormControlElementWithState::finishParsingChildren();
- m_isParsingInProgress = false;
updateListItemSelectedStates();
}
-bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
+bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeRawPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
{
- if (!value) {
- exceptionState.throwTypeError(ExceptionMessages::failedToSet(String::number(index), "HTMLSelectElement", "The value provided was not an HTMLOptionElement."));
- return false;
+ if (!value) { // undefined or null
+ remove(index);
+ return true;
}
setOption(index, value.get(), exceptionState);
return true;
}
-bool HTMLSelectElement::anonymousIndexedSetterRemove(unsigned index, ExceptionState& exceptionState)
+bool HTMLSelectElement::isInteractiveContent() const
{
- remove(index);
return true;
}
-bool HTMLSelectElement::isInteractiveContent() const
+bool HTMLSelectElement::supportsAutofocus() const
{
return true;
}
+void HTMLSelectElement::updateListOnRenderer()
+{
+ setOptionsChangedOnRenderer();
+}
+
+void HTMLSelectElement::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_listItems);
+#endif
+ HTMLFormControlElementWithState::trace(visitor);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h
index 7564360b5cc..05bf5124376 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h
@@ -39,11 +39,13 @@ class HTMLOptionElement;
class HTMLSelectElement FINAL : public HTMLFormControlElementWithState, public TypeAheadDataSource {
public:
- static PassRefPtr<HTMLSelectElement> create(Document&);
- static PassRefPtr<HTMLSelectElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLSelectElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLSelectElement> create(Document&, HTMLFormElement*);
int selectedIndex() const;
void setSelectedIndex(int);
+ int suggestedIndex() const;
+ void setSuggestedIndex(int);
void optionSelectedByUser(int index, bool dispatchChangeEvent, bool allowMultipleSelection = false);
@@ -61,16 +63,18 @@ public:
bool usesMenuList() const;
void add(HTMLElement*, HTMLElement* beforeElement, ExceptionState&);
+ void addBeforeOptionAtIndex(HTMLElement*, int beforeIndex, ExceptionState&);
using Node::remove;
void remove(int index);
- void remove(HTMLOptionElement*);
String value() const;
- void setValue(const String&);
+ void setValue(const String&, bool sendEvents = false);
+ String suggestedValue() const;
+ void setSuggestedValue(const String&);
- PassRefPtr<HTMLOptionsCollection> options();
- PassRefPtr<HTMLCollection> selectedOptions();
+ PassRefPtrWillBeRawPtr<HTMLOptionsCollection> options();
+ PassRefPtrWillBeRawPtr<HTMLCollection> selectedOptions();
void optionElementChildrenChanged();
@@ -78,9 +82,9 @@ public:
void invalidateSelectedItems();
void updateListItemSelectedStates();
- const Vector<HTMLElement*>& listItems() const;
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems() const;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
void accessKeySetSelectedIndex(int);
void setMultiple(bool);
@@ -90,8 +94,8 @@ public:
void setOption(unsigned index, HTMLOptionElement*, ExceptionState&);
void setLength(unsigned, ExceptionState&);
- Node* namedItem(const AtomicString& name);
- Node* item(unsigned index);
+ Element* namedItem(const AtomicString& name);
+ Element* item(unsigned index);
void scrollToSelection();
@@ -110,25 +114,28 @@ public:
// For use in the implementation of HTMLOptionElement.
void optionSelectionStateChanged(HTMLOptionElement*, bool optionIsSelected);
- bool isParsingInProgress() const { return m_isParsingInProgress; }
- bool anonymousIndexedSetter(unsigned, PassRefPtr<HTMLOptionElement>, ExceptionState&);
- bool anonymousIndexedSetterRemove(unsigned, ExceptionState&);
+ bool anonymousIndexedSetter(unsigned, PassRefPtrWillBeRawPtr<HTMLOptionElement>, ExceptionState&);
+
+ void updateListOnRenderer();
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
- HTMLSelectElement(Document&, HTMLFormElement*, bool createdByParser);
+ HTMLSelectElement(Document&, HTMLFormElement*);
private:
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE;
virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE;
virtual void dispatchBlurEvent(Element* newFocusedElemnet) OVERRIDE;
- virtual bool canStartSelection() const { return false; }
+ virtual bool canStartSelection() const OVERRIDE { return false; }
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
virtual FormControlState saveFormControlState() const OVERRIDE;
@@ -137,30 +144,28 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle *);
- virtual bool appendFormData(FormDataList&, bool);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- void dispatchChangeEventForMenuList();
+ void dispatchInputAndChangeEventForMenuList(bool requiresUserGesture = true);
void recalcListItems(bool updateSelectedStates = true) const;
- void deselectItems(HTMLOptionElement* excludeElement = 0);
void typeAheadFind(KeyboardEvent*);
void saveLastSelection();
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const;
+ virtual bool isOptionalFormControl() const OVERRIDE { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const OVERRIDE;
bool hasPlaceholderLabelOption() const;
enum SelectOptionFlag {
DeselectOtherOptions = 1 << 0,
- DispatchChangeEvent = 1 << 1,
+ DispatchInputAndChangeEvent = 1 << 1,
UserDriven = 1 << 2,
};
typedef unsigned SelectOptionFlags;
@@ -186,7 +191,7 @@ private:
int lastSelectableListIndex() const;
int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
virtual void finishParsingChildren() OVERRIDE;
@@ -196,7 +201,7 @@ private:
virtual String optionAtIndex(int index) const OVERRIDE;
// m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects.
- mutable Vector<HTMLElement*> m_listItems;
+ mutable WillBeHeapVector<RawPtrWillBeMember<HTMLElement> > m_listItems;
Vector<bool> m_lastOnChangeSelection;
Vector<bool> m_cachedStateForActiveSelection;
TypeAhead m_typeAhead;
@@ -208,11 +213,9 @@ private:
bool m_multiple;
bool m_activeSelectionState;
mutable bool m_shouldRecalcListItems;
- bool m_isParsingInProgress;
+ int m_suggestedIndex;
};
-DEFINE_NODE_TYPE_CASTS(HTMLSelectElement, hasTagName(HTMLNames::selectTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl
index b61f5128247..52a124495f9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl
@@ -19,6 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#htmlselectelement
+
interface HTMLSelectElement : HTMLElement {
[Reflect] attribute boolean autofocus;
[Reflect] attribute boolean disabled;
@@ -33,17 +35,18 @@ interface HTMLSelectElement : HTMLElement {
readonly attribute HTMLOptionsCollection options;
[RaisesException=Setter] attribute unsigned long length;
- getter Node item(unsigned long index);
- [ImplementedAs=anonymousIndexedSetter, RaisesException] setter HTMLOptionElement (unsigned long index, [TreatNullAs=anonymousIndexedSetterRemove, TreatUndefinedAs=anonymousIndexedSetterRemove] HTMLOptionElement value);
- Node namedItem([Default=Undefined] optional DOMString name);
- [RaisesException] void add([Default=Undefined] optional HTMLElement element,
- [Default=Undefined] optional HTMLElement before);
+ getter Element item(unsigned long index);
+ Element namedItem([Default=Undefined] optional DOMString name);
+ // FIXME: should be union type http://crbug.com/240176
+ [RaisesException, TypeChecking=Interface] void add(HTMLElement element, optional HTMLElement? before = null);
+ [ImplementedAs=addBeforeOptionAtIndex, RaisesException, TypeChecking=Interface] void add(HTMLElement element, long before);
+ [RaisesException] void remove(); // ChildNode overload
void remove(long index);
- void remove(HTMLOptionElement option); // Non standard.
- [RaisesException] void remove();
+ [RaisesException, TypeChecking=Interface|Nullable] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value);
+
readonly attribute HTMLCollection selectedOptions;
- attribute long selectedIndex;
- attribute DOMString value;
+ attribute long selectedIndex;
+ attribute DOMString value;
readonly attribute boolean willValidate;
readonly attribute ValidityState validity;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp
index edfba07e3e1..d44d71b741f 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp
@@ -29,9 +29,9 @@
*/
#include "config.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
@@ -44,10 +44,7 @@ inline HTMLShadowElement::HTMLShadowElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLShadowElement> HTMLShadowElement::create(Document& document)
-{
- return adoptRef(new HTMLShadowElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLShadowElement)
HTMLShadowElement::~HTMLShadowElement()
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h
index 70833399beb..5f0f02695b1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h
@@ -1,2 +1,53 @@
-// FIXME: Move HTMLShadowElement.h here.
-#include "core/html/shadow/HTMLShadowElement.h"
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 HTMLShadowElement_h
+#define HTMLShadowElement_h
+
+#include "core/dom/shadow/InsertionPoint.h"
+#include "wtf/Forward.h"
+
+namespace WebCore {
+
+class HTMLShadowElement FINAL : public InsertionPoint {
+public:
+ DECLARE_NODE_FACTORY(HTMLShadowElement);
+ virtual ~HTMLShadowElement();
+
+ ShadowRoot* olderShadowRoot();
+
+private:
+ explicit HTMLShadowElement(Document&);
+ virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint) OVERRIDE;
+};
+
+} // namespace WebCore
+
+#endif // HTMLShadowElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl
index faceace1458..86532b18888 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl
@@ -29,7 +29,5 @@
*/
interface HTMLShadowElement : HTMLElement {
- attribute boolean resetStyleInheritance;
- [DeprecateAs=HTMLShadowElementOlderShadowRoot] readonly attribute ShadowRoot olderShadowRoot;
- [RuntimeEnabled=ShadowDOM] NodeList getDistributedNodes();
+ NodeList getDistributedNodes();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
index 75daceb07a4..6364f84b11d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
@@ -26,37 +26,45 @@
#include "config.h"
#include "core/html/HTMLSourceElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/events/EventSender.h"
#include "core/html/HTMLMediaElement.h"
+#include "core/html/HTMLPictureElement.h"
#include "platform/Logging.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
+static SourceEventSender& sourceErrorEventSender()
+{
+ DEFINE_STATIC_LOCAL(SourceEventSender, sharedErrorEventSender, (EventTypeNames::error));
+ return sharedErrorEventSender;
+}
+
inline HTMLSourceElement::HTMLSourceElement(Document& document)
: HTMLElement(sourceTag, document)
- , m_errorEventTimer(this, &HTMLSourceElement::errorEventTimerFired)
{
WTF_LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLSourceElement> HTMLSourceElement::create(Document& document)
+DEFINE_NODE_FACTORY(HTMLSourceElement)
+
+HTMLSourceElement::~HTMLSourceElement()
{
- return adoptRef(new HTMLSourceElement(document));
+ sourceErrorEventSender().cancelEvent(this);
}
Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
Element* parent = parentElement();
- if (parent && parent->isMediaElement())
- toHTMLMediaElement(parentNode())->sourceWasAdded(this);
+ if (isHTMLMediaElement(parent))
+ toHTMLMediaElement(parent)->sourceWasAdded(this);
+ if (isHTMLPictureElement(parent))
+ toHTMLPictureElement(parent)->sourceOrMediaChanged();
return InsertionDone;
}
@@ -65,8 +73,10 @@ void HTMLSourceElement::removedFrom(ContainerNode* removalRoot)
Element* parent = parentElement();
if (!parent && removalRoot->isElementNode())
parent = toElement(removalRoot);
- if (parent && parent->isMediaElement())
+ if (isHTMLMediaElement(parent))
toHTMLMediaElement(parent)->sourceWasRemoved(this);
+ if (isHTMLPictureElement(parent))
+ toHTMLPictureElement(parent)->sourceOrMediaChanged();
HTMLElement::removedFrom(removalRoot);
}
@@ -75,16 +85,6 @@ void HTMLSourceElement::setSrc(const String& url)
setAttribute(srcAttr, AtomicString(url));
}
-const AtomicString& HTMLSourceElement::media() const
-{
- return getAttribute(mediaAttr);
-}
-
-void HTMLSourceElement::setMedia(const AtomicString& media)
-{
- setAttribute(mediaAttr, media);
-}
-
const AtomicString& HTMLSourceElement::type() const
{
return getAttribute(typeAttr);
@@ -98,21 +98,19 @@ void HTMLSourceElement::setType(const AtomicString& type)
void HTMLSourceElement::scheduleErrorEvent()
{
WTF_LOG(Media, "HTMLSourceElement::scheduleErrorEvent - %p", this);
- if (m_errorEventTimer.isActive())
- return;
-
- m_errorEventTimer.startOneShot(0);
+ sourceErrorEventSender().dispatchEventSoon(this);
}
void HTMLSourceElement::cancelPendingErrorEvent()
{
WTF_LOG(Media, "HTMLSourceElement::cancelPendingErrorEvent - %p", this);
- m_errorEventTimer.stop();
+ sourceErrorEventSender().cancelEvent(this);
}
-void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>*)
+void HTMLSourceElement::dispatchPendingEvent(SourceEventSender* eventSender)
{
- WTF_LOG(Media, "HTMLSourceElement::errorEventTimerFired - %p", this);
+ ASSERT_UNUSED(eventSender, eventSender == &sourceErrorEventSender());
+ WTF_LOG(Media, "HTMLSourceElement::dispatchPendingEvent - %p", this);
dispatchEvent(Event::createCancelable(EventTypeNames::error));
}
@@ -121,4 +119,14 @@ bool HTMLSourceElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
}
+void HTMLSourceElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+ HTMLElement::parseAttribute(name, value);
+ if (name == srcsetAttr || name == sizesAttr || name == mediaAttr || name == typeAttr) {
+ Element* parent = parentElement();
+ if (isHTMLPictureElement(parent))
+ toHTMLPictureElement(parent)->sourceOrMediaChanged();
+ }
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h
index 0002d210706..339c12a99af 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h
@@ -31,33 +31,32 @@
namespace WebCore {
+template<typename T> class EventSender;
+typedef EventSender<HTMLSourceElement> SourceEventSender;
+
class HTMLSourceElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLSourceElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLSourceElement);
+ virtual ~HTMLSourceElement();
- const AtomicString& media() const;
const AtomicString& type() const;
void setSrc(const String&);
- void setMedia(const AtomicString&);
void setType(const AtomicString&);
void scheduleErrorEvent();
void cancelPendingErrorEvent();
+ void dispatchPendingEvent(SourceEventSender*);
+
private:
explicit HTMLSourceElement(Document&);
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
-
- void errorEventTimerFired(Timer<HTMLSourceElement>*);
-
- Timer<HTMLSourceElement> m_errorEventTimer;
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLSourceElement, hasTagName(HTMLNames::sourceTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl
index 4e10349051e..45f76b93977 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl
@@ -26,7 +26,12 @@
[
RuntimeEnabled=Media
] interface HTMLSourceElement : HTMLElement {
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
attribute DOMString type;
- attribute DOMString media;
+
+ [Reflect, RuntimeEnabled=Picture] attribute DOMString srcset;
+ [Reflect, RuntimeEnabled=Picture] attribute DOMString sizes;
+ [Reflect, RuntimeEnabled=Picture] attribute DOMString media;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp
index 193c659b84d..840377e2aa2 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/HTMLSpanElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -38,9 +38,6 @@ HTMLSpanElement::HTMLSpanElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLSpanElement> HTMLSpanElement::create(Document& document)
-{
- return adoptRef(new HTMLSpanElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLSpanElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h
index ca77b867cfb..69e0e049b2e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLSpanElement : public HTMLElement {
public:
- static PassRefPtr<HTMLSpanElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLSpanElement);
protected:
explicit HTMLSpanElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
index c3d7e1c31aa..3076436827d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/html/HTMLStyleElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/ContextFeatures.h"
@@ -49,135 +49,48 @@ inline HTMLStyleElement::HTMLStyleElement(Document& document, bool createdByPars
, StyleElement(&document, createdByParser)
, m_firedLoad(false)
, m_loadedSheet(false)
- , m_scopedStyleRegistrationState(NotRegistered)
{
ScriptWrappable::init(this);
}
HTMLStyleElement::~HTMLStyleElement()
{
- // During tear-down, willRemove isn't called, so m_scopedStyleRegistrationState may still be RegisteredAsScoped or RegisteredInShadowRoot here.
- // Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered).
+#if !ENABLE(OILPAN)
StyleElement::clearDocumentData(document(), this);
+#endif
styleLoadEventSender().cancelEvent(this);
}
-PassRefPtr<HTMLStyleElement> HTMLStyleElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& document, bool createdByParser)
{
- return adoptRef(new HTMLStyleElement(document, createdByParser));
+ return adoptRefWillBeNoop(new HTMLStyleElement(document, createdByParser));
}
void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == titleAttr && m_sheet) {
m_sheet->setTitle(value);
- } else if (name == scopedAttr && ContextFeatures::styleScopedEnabled(&document())) {
- scopedAttributeChanged(!value.isNull());
} else if (name == mediaAttr && inDocument() && document().isActive() && m_sheet) {
m_sheet->setMediaQueries(MediaQuerySet::create(value));
- // FIXME: This shold be RecalcStyleDeferred.
- document().modifiedStyleSheet(m_sheet.get(), RecalcStyleImmediately);
+ document().modifiedStyleSheet(m_sheet.get());
} else {
HTMLElement::parseAttribute(name, value);
}
}
-void HTMLStyleElement::scopedAttributeChanged(bool scoped)
-{
- ASSERT(ContextFeatures::styleScopedEnabled(&document()));
-
- if (!inDocument())
- return;
-
- if (scoped) {
- if (m_scopedStyleRegistrationState == RegisteredAsScoped)
- return;
-
- // As any <style> in a shadow tree is treated as "scoped",
- // need to remove the <style> from its shadow root.
- ContainerNode* scopingNode = 0;
- if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
- scopingNode = containingShadowRoot();
- unregisterWithScopingNode(scopingNode);
- }
- document().styleEngine()->removeStyleSheetCandidateNode(this, scopingNode);
- registerWithScopingNode(true);
-
- document().styleEngine()->addStyleSheetCandidateNode(this, false);
- document().modifiedStyleSheet(sheet());
- return;
- }
-
- // If the <style> was scoped, need to remove the <style> from the scoping
- // element, i.e. the parent node.
- if (m_scopedStyleRegistrationState != RegisteredAsScoped)
- return;
-
- unregisterWithScopingNode(parentNode());
- document().styleEngine()->removeStyleSheetCandidateNode(this, parentNode());
-
- // As any <style> in a shadow tree is treated as "scoped",
- // need to add the <style> to its shadow root.
- if (isInShadowTree())
- registerWithScopingNode(false);
-
- document().styleEngine()->addStyleSheetCandidateNode(this, false);
- // FIXME: currently need to use FullStyleUpdate here.
- // Because ShadowTreeStyleSheetCollection doesn't know old scoping node.
- // So setNeedsStyleRecalc for old scoping node is not invoked.
- document().modifiedStyleSheet(sheet());
-}
-
void HTMLStyleElement::finishParsingChildren()
{
StyleElement::finishParsingChildren(this);
HTMLElement::finishParsingChildren();
}
-void HTMLStyleElement::registerWithScopingNode(bool scoped)
-{
- // Note: We cannot rely on the 'scoped' element already being present when this method is invoked.
- // Therefore we cannot rely on scoped()!
- ASSERT(m_scopedStyleRegistrationState == NotRegistered);
- ASSERT(inDocument());
- if (m_scopedStyleRegistrationState != NotRegistered)
- return;
-
- ContainerNode* scope = scoped ? parentNode() : containingShadowRoot();
- if (!scope)
- return;
- if (!scope->isElementNode() && !scope->isShadowRoot()) {
- // DocumentFragment nodes should never be inDocument,
- // <style> should not be a child of Document, PI or some such.
- ASSERT_NOT_REACHED();
- return;
- }
- scope->registerScopedHTMLStyleChild();
- m_scopedStyleRegistrationState = scoped ? RegisteredAsScoped : RegisteredInShadowRoot;
-}
-
-void HTMLStyleElement::unregisterWithScopingNode(ContainerNode* scope)
-{
- ASSERT(m_scopedStyleRegistrationState != NotRegistered || !ContextFeatures::styleScopedEnabled(&document()));
- if (!isRegisteredAsScoped())
- return;
-
- ASSERT(scope);
- if (scope) {
- ASSERT(scope->hasScopedHTMLStyleChild());
- scope->unregisterScopedHTMLStyleChild();
- }
-
- m_scopedStyleRegistrationState = NotRegistered;
-}
-
Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument()) {
- if (m_scopedStyleRegistrationState == NotRegistered && (scoped() || isInShadowTree()))
- registerWithScopingNode(scoped());
+ if (insertionPoint->inDocument() && isInShadowTree()) {
+ if (ShadowRoot* scope = containingShadowRoot())
+ scope->registerScopedHTMLStyleChild();
}
return InsertionShouldCallDidNotifySubtreeInsertions;
}
@@ -186,23 +99,18 @@ void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
{
HTMLElement::removedFrom(insertionPoint);
- // In the current implementation, <style scoped> is only registered if the node is in the document.
- // That is, because willRemove() is also called if an ancestor is removed from the document.
- // Now, if we want to register <style scoped> even if it's not inDocument,
- // we'd need to find a way to discern whether that is the case, or whether <style scoped> itself is about to be removed.
- ContainerNode* scope = 0;
- if (m_scopedStyleRegistrationState != NotRegistered) {
- if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
- scope = containingShadowRoot();
- if (!scope)
- scope = insertionPoint->containingShadowRoot();
- } else
- scope = parentNode() ? parentNode() : insertionPoint;
- unregisterWithScopingNode(scope);
- }
+ if (!insertionPoint->inDocument())
+ return;
+
+ ShadowRoot* scopingNode = containingShadowRoot();
+ if (!scopingNode)
+ scopingNode = insertionPoint->containingShadowRoot();
+
+ if (scopingNode)
+ scopingNode->unregisterScopedHTMLStyleChild();
- if (insertionPoint->inDocument())
- StyleElement::removedFromDocument(document(), this, scope);
+ TreeScope* containingScope = containingShadowRoot();
+ StyleElement::removedFromDocument(document(), this, scopingNode, containingScope ? *containingScope : insertionPoint->treeScope());
}
void HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
@@ -226,28 +134,15 @@ const AtomicString& HTMLStyleElement::type() const
return getAttribute(typeAttr);
}
-bool HTMLStyleElement::scoped() const
-{
- return fastHasAttribute(scopedAttr) && ContextFeatures::styleScopedEnabled(&document());
-}
-
-void HTMLStyleElement::setScoped(bool scopedValue)
-{
- setBooleanAttribute(scopedAttr, scopedValue);
-}
-
ContainerNode* HTMLStyleElement::scopingNode()
{
if (!inDocument())
return 0;
- if (!isRegisteredAsScoped())
- return &document();
-
- if (isRegisteredInShadowRoot())
+ if (isInShadowTree())
return containingShadowRoot();
- return parentNode();
+ return &document();
}
void HTMLStyleElement::dispatchPendingLoadEvents()
@@ -270,14 +165,6 @@ void HTMLStyleElement::notifyLoadedSheetAndAllCriticalSubresources(bool errorOcc
m_firedLoad = true;
}
-void HTMLStyleElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- if (CSSStyleSheet* styleSheet = const_cast<HTMLStyleElement*>(this)->sheet())
- styleSheet->contents()->addSubresourceStyleURLs(urls);
-}
-
bool HTMLStyleElement::disabled() const
{
if (!m_sheet)
@@ -292,4 +179,10 @@ void HTMLStyleElement::setDisabled(bool setDisabled)
styleSheet->setDisabled(setDisabled);
}
+void HTMLStyleElement::trace(Visitor* visitor)
+{
+ StyleElement::trace(visitor);
+ HTMLElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h
index 3ab95c6c0ee..71da210804c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h
@@ -35,28 +35,14 @@ template<typename T> class EventSender;
typedef EventSender<HTMLStyleElement> StyleEventSender;
class HTMLStyleElement FINAL : public HTMLElement, private StyleElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLStyleElement);
public:
- static PassRefPtr<HTMLStyleElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLStyleElement> create(Document&, bool createdByParser);
virtual ~HTMLStyleElement();
void setType(const AtomicString&);
- bool scoped() const;
- void setScoped(bool);
ContainerNode* scopingNode();
- bool isRegisteredAsScoped() const
- {
- // Note: We cannot rely on the 'scoped' attribute still being present when this method is invoked.
- // Therefore we cannot rely on scoped()!
- if (m_scopedStyleRegistrationState == NotRegistered)
- return false;
- return true;
- }
-
- bool isRegisteredInShadowRoot() const
- {
- return m_scopedStyleRegistrationState == RegisteredInShadowRoot;
- }
using StyleElement::sheet;
@@ -66,6 +52,8 @@ public:
void dispatchPendingEvent(StyleEventSender*);
static void dispatchPendingLoadEvents();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
HTMLStyleElement(Document&, bool createdByParser);
@@ -74,43 +62,21 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- 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 notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred);
- virtual void startLoadingDynamicSheet() { StyleElement::startLoadingDynamicSheet(document()); }
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual void finishParsingChildren() OVERRIDE;
- virtual const AtomicString& media() const;
- virtual const AtomicString& type() const;
+ virtual bool sheetLoaded() OVERRIDE { return StyleElement::sheetLoaded(document()); }
+ virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) OVERRIDE;
+ virtual void startLoadingDynamicSheet() OVERRIDE { StyleElement::startLoadingDynamicSheet(document()); }
- void scopedAttributeChanged(bool);
- void registerWithScopingNode(bool);
- void unregisterWithScopingNode(ContainerNode*);
+ virtual const AtomicString& media() const OVERRIDE;
+ virtual const AtomicString& type() const OVERRIDE;
bool m_firedLoad;
bool m_loadedSheet;
-
- enum ScopedStyleRegistrationState {
- NotRegistered,
- RegisteredAsScoped,
- RegisteredInShadowRoot
- };
- ScopedStyleRegistrationState m_scopedStyleRegistrationState;
};
-inline bool isHTMLStyleElement(Node* node)
-{
- ASSERT(node);
- return node->hasTagName(HTMLNames::styleTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLStyleElement, hasTagName(HTMLNames::styleTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl
index 42a38de99d4..ecc6b2bd57d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl
@@ -20,7 +20,6 @@
interface HTMLStyleElement : HTMLElement {
attribute boolean disabled;
- [RuntimeEnabled=StyleScoped] attribute boolean scoped;
[Reflect] attribute DOMString media;
[Reflect] attribute DOMString type;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp
index 7f13462137e..821b37a8e99 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp
@@ -21,23 +21,23 @@
#include "config.h"
#include "core/html/HTMLSummaryElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLDetailsElement.h"
#include "core/html/shadow/DetailsMarkerControl.h"
-#include "core/html/shadow/HTMLContentElement.h"
#include "core/rendering/RenderBlockFlow.h"
namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
{
- RefPtr<HTMLSummaryElement> summary = adoptRef(new HTMLSummaryElement(document));
+ RefPtrWillBeRawPtr<HTMLSummaryElement> summary = adoptRefWillBeNoop(new HTMLSummaryElement(document));
summary->ensureUserAgentShadowRoot();
return summary.release();
}
@@ -61,7 +61,7 @@ void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot& root)
HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
{
Node* parent = NodeRenderingTraversal::parent(this);
- if (parent && isHTMLDetailsElement(parent))
+ if (isHTMLDetailsElement(parent))
return toHTMLDetailsElement(parent);
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h
index 45f14630a86..1a05da725ae 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h
@@ -29,23 +29,21 @@ class HTMLDetailsElement;
class HTMLSummaryElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLSummaryElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLSummaryElement> create(Document&);
bool isMainSummary() const;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
private:
explicit HTMLSummaryElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual void defaultEventHandler(Event*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
HTMLDetailsElement* detailsElement() const;
- bool supportsFocus() const OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLSummaryElement, hasTagName(HTMLNames::summaryTag));
-
}
#endif // HTMLSummaryElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp
index 0212e3249e4..872845f736f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLTableCaptionElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -38,17 +38,7 @@ inline HTMLTableCaptionElement::HTMLTableCaptionElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableCaptionElement> HTMLTableCaptionElement::create(Document& document)
-{
- return adoptRef(new HTMLTableCaptionElement(document));
-}
-
-bool HTMLTableCaptionElement::isPresentationAttribute(const QualifiedName& name) const
-{
- if (name == alignAttr)
- return true;
- return HTMLElement::isPresentationAttribute(name);
-}
+DEFINE_NODE_FACTORY(HTMLTableCaptionElement)
void HTMLTableCaptionElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h
index 33315acfdb0..ce8b6c11d91 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h
@@ -32,17 +32,14 @@ namespace WebCore {
class HTMLTableCaptionElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTableCaptionElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTableCaptionElement);
private:
HTMLTableCaptionElement(Document&);
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLTableCaptionElement, hasTagName(HTMLNames::captionTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp
index 01b712585fc..2f6d5d5418f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "core/html/HTMLTableCellElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/html/HTMLTableElement.h"
#include "core/rendering/RenderTableCell.h"
@@ -48,10 +48,7 @@ inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName,
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLTableCellElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement)
int HTMLTableCellElement::colSpan() const
{
@@ -67,14 +64,12 @@ int HTMLTableCellElement::rowSpan() const
int HTMLTableCellElement::cellIndex() const
{
- int index = 0;
- if (!parentElement() || !parentElement()->hasTagName(trTag))
+ if (!isHTMLTableRowElement(parentElement()))
return -1;
- for (const Node * node = previousSibling(); node; node = node->previousSibling()) {
- if (node->hasTagName(tdTag) || node->hasTagName(thTag))
- index++;
- }
+ int index = 0;
+ for (const HTMLTableCellElement* element = Traversal<HTMLTableCellElement>::previousSibling(*this); element; element = Traversal<HTMLTableCellElement>::previousSibling(*element))
+ ++index;
return index;
}
@@ -130,14 +125,24 @@ bool HTMLTableCellElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLTablePartElement::isURLAttribute(attribute);
}
+bool HTMLTableCellElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return (hasLocalName(tdTag) && name == backgroundAttr) || HTMLTablePartElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLTableCellElement::subResourceAttributeName() const
+{
+ return hasLocalName(tdTag) ? backgroundAttr : HTMLTablePartElement::subResourceAttributeName();
+}
+
const AtomicString& HTMLTableCellElement::abbr() const
{
- return getAttribute(abbrAttr);
+ return fastGetAttribute(abbrAttr);
}
const AtomicString& HTMLTableCellElement::axis() const
{
- return getAttribute(axisAttr);
+ return fastGetAttribute(axisAttr);
}
void HTMLTableCellElement::setColSpan(int n)
@@ -147,7 +152,7 @@ void HTMLTableCellElement::setColSpan(int n)
const AtomicString& HTMLTableCellElement::headers() const
{
- return getAttribute(headersAttr);
+ return fastGetAttribute(headersAttr);
}
void HTMLTableCellElement::setRowSpan(int n)
@@ -157,14 +162,7 @@ void HTMLTableCellElement::setRowSpan(int n)
const AtomicString& HTMLTableCellElement::scope() const
{
- return getAttribute(scopeAttr);
-}
-
-void HTMLTableCellElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLTablePartElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
+ return fastGetAttribute(scopeAttr);
}
HTMLTableCellElement* HTMLTableCellElement::cellAbove() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h
index 8c22cccfb38..55cbd5f4b6b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableCellElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableCellElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement);
int cellIndex() const;
@@ -59,16 +59,21 @@ private:
virtual const StylePropertySet* additionalPresentationAttributeStyle() OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
};
-inline bool isHTMLTableCellElement(const Node& node)
+inline bool isHTMLTableCellElement(const Element& element)
+{
+ return element.hasTagName(HTMLNames::tdTag) || element.hasTagName(HTMLNames::thTag);
+}
+
+inline bool isHTMLTableCellElement(const HTMLElement& element)
{
- return node.hasTagName(HTMLNames::tdTag) || node.hasTagName(HTMLNames::thTag);
+ return element.hasLocalName(HTMLNames::tdTag) || element.hasLocalName(HTMLNames::thTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp
index 19e301d95c0..5094868e388 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLTableColElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLTableElement.h"
#include "core/rendering/RenderTableCol.h"
@@ -41,10 +41,7 @@ inline HTMLTableColElement::HTMLTableColElement(const QualifiedName& tagName, Do
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLTableColElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableColElement)
bool HTMLTableColElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -64,7 +61,10 @@ void HTMLTableColElement::collectStyleForPresentationAttribute(const QualifiedNa
void HTMLTableColElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == spanAttr) {
- m_span = !value.isNull() ? value.toInt() : 1;
+ int newSpan = value.toInt();
+ // If the value of span is not a valid non-negative integer greater than zero,
+ // set it to 1.
+ m_span = newSpan ? newSpan : 1;
if (renderer() && renderer()->isRenderTableCol())
renderer()->updateFromElement();
} else if (name == widthAttr) {
@@ -73,7 +73,7 @@ void HTMLTableColElement::parseAttribute(const QualifiedName& name, const Atomic
RenderTableCol* col = toRenderTableCol(renderer());
int newWidth = width().toInt();
if (newWidth != col->width())
- col->setNeedsLayoutAndPrefWidthsRecalc();
+ col->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
} else
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h
index ecd3f73f241..72e859673ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableColElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableColElement> create(const QualifiedName& tagName, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableColElement);
int span() const { return m_span; }
void setSpan(int);
@@ -50,12 +50,17 @@ private:
int m_span;
};
-inline bool isHTMLTableColElement(const Node& node)
+inline bool isHTMLTableColElement(const Element& element)
{
- return node.hasTagName(HTMLNames::colTag) || node.hasTagName(HTMLNames::colgroupTag);
+ return element.hasTagName(HTMLNames::colTag) || element.hasTagName(HTMLNames::colgroupTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
+inline bool isHTMLTableColElement(const HTMLElement& element)
+{
+ return element.hasLocalName(HTMLNames::colTag) || element.hasLocalName(HTMLNames::colgroupTag);
+}
+
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
index c963c1f65a0..cebf9c3d6ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
@@ -25,29 +25,33 @@
#include "config.h"
#include "core/html/HTMLTableElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Attribute.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLTableCaptionElement.h"
+#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTableRowElement.h"
#include "core/html/HTMLTableRowsCollection.h"
#include "core/html/HTMLTableSectionElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/rendering/RenderTable.h"
+#include "platform/weborigin/Referrer.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLTableElement::HTMLTableElement(Document& document)
+inline HTMLTableElement::HTMLTableElement(Document& document)
: HTMLElement(tableTag, document)
, m_borderAttr(false)
, m_borderColorAttr(false)
@@ -58,21 +62,14 @@ HTMLTableElement::HTMLTableElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableElement> HTMLTableElement::create(Document& document)
-{
- return adoptRef(new HTMLTableElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLTableElement)
HTMLTableCaptionElement* HTMLTableElement::caption() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(captionTag))
- return toHTMLTableCaptionElement(child);
- }
- return 0;
+ return Traversal<HTMLTableCaptionElement>::firstChild(*this);
}
-void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionState& exceptionState)
+void HTMLTableElement::setCaption(PassRefPtrWillBeRawPtr<HTMLTableCaptionElement> newCaption, ExceptionState& exceptionState)
{
deleteCaption();
insertBefore(newCaption, firstChild(), exceptionState);
@@ -80,51 +77,53 @@ void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption
HTMLTableSectionElement* HTMLTableElement::tHead() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
if (child->hasTagName(theadTag))
return toHTMLTableSectionElement(child);
}
return 0;
}
-void HTMLTableElement::setTHead(PassRefPtr<HTMLTableSectionElement> newHead, ExceptionState& exceptionState)
+void HTMLTableElement::setTHead(PassRefPtrWillBeRawPtr<HTMLTableSectionElement> newHead, ExceptionState& exceptionState)
{
deleteTHead();
- Node* child;
- for (child = firstChild(); child; child = child->nextSibling())
- if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
+ Element* child;
+ for (child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
+ if (!child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
break;
+ }
insertBefore(newHead, child, exceptionState);
}
HTMLTableSectionElement* HTMLTableElement::tFoot() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
if (child->hasTagName(tfootTag))
return toHTMLTableSectionElement(child);
}
return 0;
}
-void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, ExceptionState& exceptionState)
+void HTMLTableElement::setTFoot(PassRefPtrWillBeRawPtr<HTMLTableSectionElement> newFoot, ExceptionState& exceptionState)
{
deleteTFoot();
- Node* child;
- for (child = firstChild(); child; child = child->nextSibling())
- if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
+ Element* child;
+ for (child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
+ if (!child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
break;
+ }
insertBefore(newFoot, child, exceptionState);
}
-PassRefPtr<HTMLElement> HTMLTableElement::createTHead()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createTHead()
{
if (HTMLTableSectionElement* existingHead = tHead())
return existingHead;
- RefPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
setTHead(head, IGNORE_EXCEPTION);
return head.release();
}
@@ -134,11 +133,11 @@ void HTMLTableElement::deleteTHead()
removeChild(tHead(), IGNORE_EXCEPTION);
}
-PassRefPtr<HTMLElement> HTMLTableElement::createTFoot()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createTFoot()
{
if (HTMLTableSectionElement* existingFoot = tFoot())
return existingFoot;
- RefPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
setTFoot(foot, IGNORE_EXCEPTION);
return foot.release();
}
@@ -148,20 +147,20 @@ void HTMLTableElement::deleteTFoot()
removeChild(tFoot(), IGNORE_EXCEPTION);
}
-PassRefPtr<HTMLElement> HTMLTableElement::createTBody()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createTBody()
{
- RefPtr<HTMLTableSectionElement> body = HTMLTableSectionElement::create(tbodyTag, document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> body = HTMLTableSectionElement::create(tbodyTag, document());
Node* referenceElement = lastBody() ? lastBody()->nextSibling() : 0;
insertBefore(body, referenceElement);
return body.release();
}
-PassRefPtr<HTMLElement> HTMLTableElement::createCaption()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createCaption()
{
if (HTMLTableCaptionElement* existingCaption = caption())
return existingCaption;
- RefPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(document());
+ RefPtrWillBeRawPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(document());
setCaption(caption, IGNORE_EXCEPTION);
return caption.release();
}
@@ -180,26 +179,32 @@ HTMLTableSectionElement* HTMLTableElement::lastBody() const
return 0;
}
-PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::insertRow(ExceptionState& exceptionState)
+{
+ // The default 'index' argument value is -1.
+ return insertRow(-1, exceptionState);
+}
+
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& exceptionState)
{
if (index < -1) {
exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is less than -1.");
- return 0;
+ return nullptr;
}
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
- RefPtr<HTMLTableRowElement> lastRow = 0;
- RefPtr<HTMLTableRowElement> row = 0;
+ RefPtrWillBeRawPtr<HTMLTableRowElement> lastRow = nullptr;
+ RefPtrWillBeRawPtr<HTMLTableRowElement> row = nullptr;
if (index == -1)
- lastRow = HTMLTableRowsCollection::lastRow(this);
+ lastRow = HTMLTableRowsCollection::lastRow(*this);
else {
for (int i = 0; i <= index; ++i) {
- row = HTMLTableRowsCollection::rowAfter(this, lastRow.get());
+ row = HTMLTableRowsCollection::rowAfter(*this, lastRow.get());
if (!row) {
if (i != index) {
exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is greater than the number of rows in the table (" + String::number(i) + ").");
- return 0;
+ return nullptr;
}
break;
}
@@ -207,21 +212,21 @@ PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& e
}
}
- RefPtr<ContainerNode> parent;
+ RefPtrWillBeRawPtr<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());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> newBody = HTMLTableSectionElement::create(tbodyTag, document());
+ RefPtrWillBeRawPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
newBody->appendChild(newRow, exceptionState);
appendChild(newBody.release(), exceptionState);
return newRow.release();
}
}
- RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
+ RefPtrWillBeRawPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
parent->insertBefore(newRow, row.get(), exceptionState);
return newRow.release();
}
@@ -236,10 +241,10 @@ void HTMLTableElement::deleteRow(int index, ExceptionState& exceptionState)
HTMLTableRowElement* row = 0;
int i = 0;
if (index == -1)
- row = HTMLTableRowsCollection::lastRow(this);
+ row = HTMLTableRowsCollection::lastRow(*this);
else {
for (i = 0; i <= index; ++i) {
- row = HTMLTableRowsCollection::rowAfter(this, row);
+ row = HTMLTableRowsCollection::rowAfter(*this, row);
if (!row)
break;
}
@@ -251,29 +256,16 @@ void HTMLTableElement::deleteRow(int index, ExceptionState& exceptionState)
row->remove(exceptionState);
}
-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)
+void HTMLTableElement::setNeedsTableStyleRecalc() const
{
- 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);
+ Element* element = ElementTraversal::next(*this, this);
+ while (element) {
+ element->setNeedsStyleRecalc(LocalStyleChange);
+ if (isHTMLTableCellElement(*element))
+ element = ElementTraversal::nextSkippingChildren(*element, this);
+ else
+ element = ElementTraversal::next(*element, this);
}
-
- if (cellChanged)
- n->setNeedsStyleRecalc();
-
- return cellChanged;
}
static bool getBordersFromFrameAttributeValue(const AtomicString& value, bool& borderTop, bool& borderRight, bool& borderBottom, bool& borderLeft)
@@ -317,8 +309,11 @@ void HTMLTableElement::collectStyleForPresentationAttribute(const QualifiedName&
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
else if (name == backgroundAttr) {
String url = stripLeadingAndTrailingHTMLSpaces(value);
- if (!url.isEmpty())
- style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url).string())));
+ if (!url.isEmpty()) {
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
+ imageValue->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
+ style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
+ }
} else if (name == valignAttr) {
if (!value.isEmpty())
addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, value);
@@ -326,9 +321,11 @@ void HTMLTableElement::collectStyleForPresentationAttribute(const QualifiedName&
if (!value.isEmpty())
addHTMLLengthToStyle(style, CSSPropertyBorderSpacing, value);
} else if (name == vspaceAttr) {
+ UseCounter::count(document(), UseCounter::HTMLTableElementVspace);
addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
} else if (name == hspaceAttr) {
+ UseCounter::count(document(), UseCounter::HTMLTableElementHspace);
addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
} else if (name == alignAttr) {
@@ -406,18 +403,14 @@ void HTMLTableElement::parseAttribute(const QualifiedName& name, const AtomicStr
HTMLElement::parseAttribute(name, value);
if (bordersBefore != cellBorders() || oldPadding != m_padding) {
- m_sharedCellStyle = 0;
- bool cellChanged = false;
- for (Node* child = firstChild(); child; child = child->nextSibling())
- cellChanged |= setTableCellsChanged(child);
- if (cellChanged)
- setNeedsStyleRecalc();
+ m_sharedCellStyle = nullptr;
+ setNeedsTableStyleRecalc();
}
}
static PassRefPtr<StylePropertySet> createBorderStyle(CSSValueID value)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(CSSPropertyBorderTopStyle, value);
style->setProperty(CSSPropertyBorderBottomStyle, value);
style->setProperty(CSSPropertyBorderLeftStyle, value);
@@ -471,9 +464,9 @@ HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
return NoBorders;
}
-PassRefPtr<StylePropertySet> HTMLTableElement::createSharedCellStyle()
+PassRefPtrWillBeRawPtr<StylePropertySet> HTMLTableElement::createSharedCellStyle()
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
switch (cellBorders()) {
case SolidBordersColsOnly:
@@ -518,9 +511,9 @@ const StylePropertySet* HTMLTableElement::additionalCellStyle()
return m_sharedCellStyle.get();
}
-static PassRefPtr<StylePropertySet> createGroupBorderStyle(int rows)
+static PassRefPtrWillBeRawPtr<StylePropertySet> createGroupBorderStyle(int rows)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
if (rows) {
style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
@@ -553,12 +546,22 @@ bool HTMLTableElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
}
-PassRefPtr<HTMLCollection> HTMLTableElement::rows()
+bool HTMLTableElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == backgroundAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLTableElement::subResourceAttributeName() const
+{
+ return backgroundAttr;
+}
+
+PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> HTMLTableElement::rows()
{
- return ensureCachedHTMLCollection(TableRows);
+ return toHTMLTableRowsCollection(ensureCachedHTMLCollection(TableRows).get());
}
-PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableElement::tBodies()
{
return ensureCachedHTMLCollection(TableTBodies);
}
@@ -573,11 +576,10 @@ const AtomicString& HTMLTableElement::summary() const
return getAttribute(summaryAttr);
}
-void HTMLTableElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+void HTMLTableElement::trace(Visitor* visitor)
{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
+ visitor->trace(m_sharedCellStyle);
+ HTMLElement::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h
index d25a23c59bf..c8b2dbcf35a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h
@@ -38,29 +38,30 @@ class HTMLTableSectionElement;
class HTMLTableElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTableElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTableElement);
HTMLTableCaptionElement* caption() const;
- void setCaption(PassRefPtr<HTMLTableCaptionElement>, ExceptionState&);
+ void setCaption(PassRefPtrWillBeRawPtr<HTMLTableCaptionElement>, ExceptionState&);
HTMLTableSectionElement* tHead() const;
- void setTHead(PassRefPtr<HTMLTableSectionElement>, ExceptionState&);
+ void setTHead(PassRefPtrWillBeRawPtr<HTMLTableSectionElement>, ExceptionState&);
HTMLTableSectionElement* tFoot() const;
- void setTFoot(PassRefPtr<HTMLTableSectionElement>, ExceptionState&);
+ void setTFoot(PassRefPtrWillBeRawPtr<HTMLTableSectionElement>, ExceptionState&);
- PassRefPtr<HTMLElement> createTHead();
+ PassRefPtrWillBeRawPtr<HTMLElement> createTHead();
void deleteTHead();
- PassRefPtr<HTMLElement> createTFoot();
+ PassRefPtrWillBeRawPtr<HTMLElement> createTFoot();
void deleteTFoot();
- PassRefPtr<HTMLElement> createTBody();
- PassRefPtr<HTMLElement> createCaption();
+ PassRefPtrWillBeRawPtr<HTMLElement> createTBody();
+ PassRefPtrWillBeRawPtr<HTMLElement> createCaption();
void deleteCaption();
- PassRefPtr<HTMLElement> insertRow(int index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(int index, ExceptionState&);
void deleteRow(int index, ExceptionState&);
- PassRefPtr<HTMLCollection> rows();
- PassRefPtr<HTMLCollection> tBodies();
+ PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> rows();
+ PassRefPtrWillBeRawPtr<HTMLCollection> tBodies();
const AtomicString& rules() const;
const AtomicString& summary() const;
@@ -68,6 +69,8 @@ public:
const StylePropertySet* additionalCellStyle();
const StylePropertySet* additionalGroupStyle(bool rows);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit HTMLTableElement(Document&);
@@ -75,21 +78,23 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
// Used to obtain either a solid or outset border decl and to deal with the frame and rules attributes.
virtual const StylePropertySet* additionalPresentationAttributeStyle() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
enum TableRules { UnsetRules, NoneRules, GroupsRules, RowsRules, ColsRules, AllRules };
enum CellBorders { NoBorders, SolidBorders, InsetBorders, SolidBordersColsOnly, SolidBordersRowsOnly };
CellBorders cellBorders() const;
- PassRefPtr<StylePropertySet> createSharedCellStyle();
+ PassRefPtrWillBeRawPtr<StylePropertySet> createSharedCellStyle();
HTMLTableSectionElement* lastBody() const;
+ void setNeedsTableStyleRecalc() 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.
@@ -97,21 +102,9 @@ private:
// are present, to none otherwise).
unsigned short m_padding;
- RefPtr<StylePropertySet> m_sharedCellStyle;
+ RefPtrWillBeMember<StylePropertySet> m_sharedCellStyle;
};
-inline bool isHTMLTableElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::tableTag);
-}
-
-inline bool isHTMLTableElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::tableTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLTableElement, hasTagName(HTMLNames::tableTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl
index 4cd6d6f573b..3072583711c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl
@@ -45,6 +45,6 @@ interface HTMLTableElement : HTMLElement {
HTMLElement createCaption();
void deleteCaption();
- [RaisesException] HTMLElement insertRow([Default=Undefined] optional long index);
+ [RaisesException] HTMLElement insertRow(optional long index);
[RaisesException] void deleteRow([Default=Undefined] optional long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
index 79b2b6c1138..4483de09ecc 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
@@ -25,15 +25,16 @@
#include "config.h"
#include "core/html/HTMLTablePartElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSImageValue.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/html/HTMLTableElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "platform/weborigin/Referrer.h"
namespace WebCore {
@@ -52,8 +53,11 @@ void HTMLTablePartElement::collectStyleForPresentationAttribute(const QualifiedN
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
else if (name == backgroundAttr) {
String url = stripLeadingAndTrailingHTMLSpaces(value);
- if (!url.isEmpty())
- style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url).string())));
+ if (!url.isEmpty()) {
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
+ imageValue->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
+ style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
+ }
} else if (name == valignAttr) {
if (equalIgnoringCase(value, "top"))
addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, CSSValueTop);
@@ -86,7 +90,7 @@ void HTMLTablePartElement::collectStyleForPresentationAttribute(const QualifiedN
HTMLTableElement* HTMLTablePartElement::findParentTable() const
{
ContainerNode* parent = NodeRenderingTraversal::parent(this);
- while (parent && !isHTMLTableElement(parent))
+ while (parent && !isHTMLTableElement(*parent))
parent = NodeRenderingTraversal::parent(parent);
return toHTMLTableElement(parent);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp
index b643924cf72..2aadf0ba3e3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp
@@ -25,8 +25,9 @@
#include "config.h"
#include "core/html/HTMLTableRowElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLTableCellElement.h"
@@ -37,15 +38,22 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLTableRowElement::HTMLTableRowElement(Document& document)
+inline HTMLTableRowElement::HTMLTableRowElement(Document& document)
: HTMLTablePartElement(trTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(Document& document)
+DEFINE_NODE_FACTORY(HTMLTableRowElement)
+
+bool HTMLTableRowElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == backgroundAttr || HTMLTablePartElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLTableRowElement::subResourceAttributeName() const
{
- return adoptRef(new HTMLTableRowElement(document));
+ return backgroundAttr;
}
int HTMLTableRowElement::rowIndex() const
@@ -54,7 +62,7 @@ int HTMLTableRowElement::rowIndex() const
if (!table)
return -1;
table = table->parentNode();
- if (!table || !isHTMLTableElement(table))
+ if (!isHTMLTableElement(table))
return -1;
// To match Firefox, the row indices work like this:
@@ -65,32 +73,29 @@ int HTMLTableRowElement::rowIndex() const
int rIndex = 0;
if (HTMLTableSectionElement* head = toHTMLTableElement(table)->tHead()) {
- for (Node *row = head->firstChild(); row; row = row->nextSibling()) {
+ for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*head); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
if (row == this)
return rIndex;
- if (row->hasTagName(trTag))
- ++rIndex;
+ ++rIndex;
}
}
- for (Node *node = table->firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(tbodyTag)) {
- HTMLTableSectionElement* section = toHTMLTableSectionElement(node);
- for (Node* row = section->firstChild(); row; row = row->nextSibling()) {
+ for (Element* child = ElementTraversal::firstWithin(*table); child; child = ElementTraversal::nextSibling(*child)) {
+ if (child->hasTagName(tbodyTag)) {
+ HTMLTableSectionElement* section = toHTMLTableSectionElement(child);
+ for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*section); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
if (row == this)
return rIndex;
- if (row->hasTagName(trTag))
- ++rIndex;
+ ++rIndex;
}
}
}
if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) {
- for (Node *row = foot->firstChild(); row; row = row->nextSibling()) {
+ for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*foot); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
if (row == this)
return rIndex;
- if (row->hasTagName(trTag))
- ++rIndex;
+ ++rIndex;
}
}
@@ -101,55 +106,54 @@ int HTMLTableRowElement::rowIndex() const
int HTMLTableRowElement::sectionRowIndex() const
{
int rIndex = 0;
- const Node *n = this;
+ const Node* n = this;
do {
n = n->previousSibling();
- if (n && n->hasTagName(trTag))
- rIndex++;
- }
- while (n);
+ if (n && isHTMLTableRowElement(*n))
+ ++rIndex;
+ } while (n);
return rIndex;
}
-PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(ExceptionState& exceptionState)
+{
+ // The default 'index' argument value is -1.
+ return insertCell(-1, exceptionState);
+}
+
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLCollection> children = cells();
+ RefPtrWillBeRawPtr<HTMLCollection> children = cells();
int numCells = children ? children->length() : 0;
if (index < -1 || index > numCells) {
exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [-1, " + String::number(numCells) + "].");
- return 0;
+ return nullptr;
}
- RefPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
- if (index < 0 || index >= numCells)
+ RefPtrWillBeRawPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
+ if (numCells == index || index == -1)
appendChild(cell, exceptionState);
- else {
- Node* n;
- if (index < 1)
- n = firstChild();
- else
- n = children->item(index);
- insertBefore(cell, n, exceptionState);
- }
+ else
+ insertBefore(cell, children->item(index), exceptionState);
return cell.release();
}
void HTMLTableRowElement::deleteCell(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLCollection> children = cells();
+ RefPtrWillBeRawPtr<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);
+ RefPtrWillBeRawPtr<Element> cell = children->item(index);
HTMLElement::removeChild(cell.get(), exceptionState);
} else {
exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [0, " + String::number(numCells) + ").");
}
}
-PassRefPtr<HTMLCollection> HTMLTableRowElement::cells()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableRowElement::cells()
{
return ensureCachedHTMLCollection(TRCells);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h
index 1fe3867218b..539856ef5d5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h
@@ -34,27 +34,24 @@ class ExceptionState;
class HTMLTableRowElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableRowElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTableRowElement);
int rowIndex() const;
int sectionRowIndex() const;
- PassRefPtr<HTMLElement> insertCell(int index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertCell(ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertCell(int index, ExceptionState&);
void deleteCell(int index, ExceptionState&);
- PassRefPtr<HTMLCollection> cells();
+ PassRefPtrWillBeRawPtr<HTMLCollection> cells();
private:
explicit HTMLTableRowElement(Document&);
-};
-
-inline bool isHTMLTableRowElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::trTag);
-}
-DEFINE_NODE_TYPE_CASTS(HTMLTableRowElement, hasTagName(HTMLNames::trTag));
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
+};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
index aa7b9cae5bd..e38f999ef53 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
@@ -27,6 +27,6 @@ interface HTMLTableRowElement : HTMLElement {
[Reflect=char] attribute DOMString ch;
[Reflect=charoff] attribute DOMString chOff;
[Reflect] attribute DOMString vAlign;
- [RaisesException] HTMLElement insertCell([Default=Undefined] optional long index);
+ [RaisesException] HTMLElement insertCell(optional long index);
[RaisesException] void deleteCell([Default=Undefined] optional long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp
index 3037aff1c61..dbf5e04e827 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp
@@ -29,7 +29,8 @@
#include "config.h"
#include "core/html/HTMLTableRowsCollection.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLTableElement.h"
#include "core/html/HTMLTableRowElement.h"
@@ -52,96 +53,81 @@ static bool isInFoot(Element* row)
return row->parentNode() && toElement(row->parentNode())->hasLocalName(tfootTag);
}
-HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
+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 (isHTMLTableRowElement(child))
- return toHTMLTableRowElement(child);
- }
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::nextSibling(*previous))
+ return row;
}
// If still looking at head sections, find the first row in the next head section.
+ HTMLElement* child = 0;
if (!previous)
- child = table->firstChild();
+ child = Traversal<HTMLElement>::firstChild(table);
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 (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ child = Traversal<HTMLElement>::nextSibling(*previous->parentNode());
+ for (; child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (child->hasLocalName(theadTag)) {
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*child))
+ return row;
}
}
// 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();
+ child = Traversal<HTMLElement>::firstChild(table);
else if (previous->parentNode() == table)
- child = previous->nextSibling();
+ child = Traversal<HTMLElement>::nextSibling(*previous);
else if (isInBody(previous))
- child = previous->parentNode()->nextSibling();
- for (; child; child = child->nextSibling()) {
+ child = Traversal<HTMLElement>::nextSibling(*previous->parentNode());
+ for (; child; child = Traversal<HTMLElement>::nextSibling(*child)) {
if (isHTMLTableRowElement(child))
return toHTMLTableRowElement(child);
- if (child->hasTagName(tbodyTag)) {
- for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ if (child->hasLocalName(tbodyTag)) {
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*child))
+ return row;
}
}
// Find the first row in the next foot section.
if (!previous || !isInFoot(previous))
- child = table->firstChild();
+ child = Traversal<HTMLElement>::firstChild(table);
else
- child = previous->parentNode()->nextSibling();
- for (; child; child = child->nextSibling()) {
- if (child->hasTagName(tfootTag)) {
- for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ child = Traversal<HTMLElement>::nextSibling(*previous->parentNode());
+ for (; child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (child->hasLocalName(tfootTag)) {
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*child))
+ return row;
}
}
return 0;
}
-HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
+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 (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ for (HTMLElement* child = Traversal<HTMLElement>::lastChild(table); child; child = Traversal<HTMLElement>::previousSibling(*child)) {
+ if (child->hasLocalName(tfootTag)) {
+ if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+ return lastRow;
}
}
- for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+ for (HTMLElement* child = Traversal<HTMLElement>::lastChild(table); child; child = Traversal<HTMLElement>::previousSibling(*child)) {
if (isHTMLTableRowElement(child))
return toHTMLTableRowElement(child);
- if (child->hasTagName(tbodyTag)) {
- for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ if (child->hasLocalName(tbodyTag)) {
+ if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+ return lastRow;
}
}
- for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
- if (child->hasTagName(theadTag)) {
- for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ for (HTMLElement* child = Traversal<HTMLElement>::lastChild(table); child; child = Traversal<HTMLElement>::previousSibling(*child)) {
+ if (child->hasLocalName(theadTag)) {
+ if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+ return lastRow;
}
}
@@ -151,20 +137,20 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
// Must call get() on the table in case that argument is compiled before dereferencing the
// table to get at the collection cache. Order of argument evaluation is undefined and can
// differ between compilers.
-HTMLTableRowsCollection::HTMLTableRowsCollection(Node* table)
+HTMLTableRowsCollection::HTMLTableRowsCollection(ContainerNode& table)
: HTMLCollection(table, TableRows, OverridesItemAfter)
{
ASSERT(isHTMLTableElement(table));
}
-PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Node* table, CollectionType)
+PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(ContainerNode& table, CollectionType type)
{
- return adoptRef(new HTMLTableRowsCollection(table));
+ ASSERT_UNUSED(type, type == TableRows);
+ return adoptRefWillBeNoop(new HTMLTableRowsCollection(table));
}
-Element* HTMLTableRowsCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const
+Element* HTMLTableRowsCollection::virtualItemAfter(Element* previous) const
{
- ASSERT_UNUSED(offsetInArray, !offsetInArray);
return rowAfter(toHTMLTableElement(ownerNode()), toHTMLTableRowElement(previous));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h
index d643d430de4..653328e7305 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h
@@ -38,17 +38,19 @@ class HTMLTableRowElement;
class HTMLTableRowsCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLTableRowsCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> create(ContainerNode&, CollectionType);
- static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
- static HTMLTableRowElement* lastRow(HTMLTableElement*);
+ static HTMLTableRowElement* rowAfter(HTMLTableElement&, HTMLTableRowElement*);
+ static HTMLTableRowElement* lastRow(HTMLTableElement&);
private:
- explicit HTMLTableRowsCollection(Node*);
+ explicit HTMLTableRowsCollection(ContainerNode&);
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
+ virtual Element* virtualItemAfter(Element*) const OVERRIDE;
};
+DEFINE_TYPE_CASTS(HTMLTableRowsCollection, LiveNodeListBase, collection, collection->type() == TableRows, collection.type() == TableRows);
+
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
index 01ec777a27f..e4b42660287 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
@@ -25,8 +25,9 @@
#include "config.h"
#include "core/html/HTMLTableSectionElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLTableElement.h"
@@ -42,10 +43,7 @@ inline HTMLTableSectionElement::HTMLTableSectionElement(const QualifiedName& tag
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLTableSectionElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableSectionElement)
const StylePropertySet* HTMLTableSectionElement::additionalPresentationAttributeStyle()
{
@@ -54,99 +52,54 @@ const StylePropertySet* HTMLTableSectionElement::additionalPresentationAttribute
return 0;
}
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableSectionElement::insertRow(ExceptionState& exceptionState)
+{
+ // The default 'index' argument value is -1.
+ return insertRow(-1, exceptionState);
+}
+
// 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, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLTableRowElement> row;
- RefPtr<HTMLCollection> children = rows();
- int numRows = children ? (int)children->length() : 0;
- if (index < -1 || index > numRows)
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError); // per the DOM
- else {
- row = HTMLTableRowElement::create(document());
- if (numRows == index || index == -1)
- appendChild(row, exceptionState);
- else {
- Node* n;
- if (index < 1)
- n = firstChild();
- else
- n = children->item(index);
- insertBefore(row, n, exceptionState);
- }
+ RefPtrWillBeRawPtr<HTMLCollection> children = rows();
+ int numRows = children ? static_cast<int>(children->length()) : 0;
+ if (index < -1 || index > numRows) {
+ exceptionState.throwDOMException(IndexSizeError, "The provided index (" + String::number(index) + " is outside the range [-1, " + String::number(numRows) + "].");
+ return nullptr;
}
+
+ RefPtrWillBeRawPtr<HTMLTableRowElement> row = HTMLTableRowElement::create(document());
+ if (numRows == index || index == -1)
+ appendChild(row, exceptionState);
+ else
+ insertBefore(row, children->item(index), exceptionState);
return row.release();
}
void HTMLTableSectionElement::deleteRow(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLCollection> children = rows();
+ RefPtrWillBeRawPtr<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);
+ RefPtrWillBeRawPtr<Element> row = children->item(index);
HTMLElement::removeChild(row.get(), exceptionState);
} else {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided index (" + String::number(index) + " is outside the range [-1, " + String::number(numRows) + "].");
}
}
int HTMLTableSectionElement::numRows() const
{
- int rows = 0;
- const Node *n = firstChild();
- while (n) {
- if (n->hasTagName(trTag))
- rows++;
- n = n->nextSibling();
- }
-
- return rows;
-}
-
-const AtomicString& HTMLTableSectionElement::align() const
-{
- return getAttribute(alignAttr);
-}
-
-void HTMLTableSectionElement::setAlign(const AtomicString& value)
-{
- setAttribute(alignAttr, value);
-}
-
-const AtomicString& HTMLTableSectionElement::ch() const
-{
- return getAttribute(charAttr);
-}
-
-void HTMLTableSectionElement::setCh(const AtomicString& value)
-{
- setAttribute(charAttr, value);
-}
-
-const AtomicString& HTMLTableSectionElement::chOff() const
-{
- return getAttribute(charoffAttr);
-}
-
-void HTMLTableSectionElement::setChOff(const AtomicString& value)
-{
- setAttribute(charoffAttr, value);
-}
-
-const AtomicString& HTMLTableSectionElement::vAlign() const
-{
- return getAttribute(valignAttr);
-}
-
-void HTMLTableSectionElement::setVAlign(const AtomicString& value)
-{
- setAttribute(valignAttr, value);
+ int rowCount = 0;
+ for (const HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*this); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row))
+ ++rowCount;
+ return rowCount;
}
-PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableSectionElement::rows()
{
return ensureCachedHTMLCollection(TSectionRows);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h
index 02d55167adb..4fa633b2b4c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h
@@ -34,26 +34,15 @@ class ExceptionState;
class HTMLTableSectionElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableSectionElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableSectionElement);
- PassRefPtr<HTMLElement> insertRow(int index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(int index, ExceptionState&);
void deleteRow(int index, ExceptionState&);
int numRows() const;
- const AtomicString& align() const;
- void setAlign(const AtomicString&);
-
- const AtomicString& ch() const;
- void setCh(const AtomicString&);
-
- const AtomicString& chOff() const;
- void setChOff(const AtomicString&);
-
- const AtomicString& vAlign() const;
- void setVAlign(const AtomicString&);
-
- PassRefPtr<HTMLCollection> rows();
+ PassRefPtrWillBeRawPtr<HTMLCollection> rows();
private:
HTMLTableSectionElement(const QualifiedName& tagName, Document&);
@@ -61,12 +50,17 @@ private:
virtual const StylePropertySet* additionalPresentationAttributeStyle() OVERRIDE;
};
-inline bool isHTMLTableSectionElement(const Node& node)
+inline bool isHTMLTableSectionElement(const Element& element)
+{
+ return element.hasTagName(HTMLNames::tbodyTag) || element.hasTagName(HTMLNames::tfootTag) || element.hasTagName(HTMLNames::theadTag);
+}
+
+inline bool isHTMLTableSectionElement(const HTMLElement& element)
{
- return node.hasTagName(HTMLNames::tbodyTag) || node.hasTagName(HTMLNames::tfootTag) || node.hasTagName(HTMLNames::theadTag);
+ return element.hasLocalName(HTMLNames::tbodyTag) || element.hasLocalName(HTMLNames::tfootTag) || element.hasLocalName(HTMLNames::theadTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableSectionElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableSectionElement);
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl
index 836b712c43e..a8f0b894191 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl
@@ -24,6 +24,6 @@ interface HTMLTableSectionElement : HTMLElement {
[Reflect=charoff] attribute DOMString chOff;
[Reflect] attribute DOMString vAlign;
readonly attribute HTMLCollection rows;
- [RaisesException] HTMLElement insertRow([Default=Undefined] optional long index);
+ [RaisesException] HTMLElement insertRow(optional long index);
[RaisesException] void deleteRow([Default=Undefined] optional long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in b/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in
index ee8c92f89f3..9e349119186 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in
@@ -11,7 +11,7 @@ applet constructorNeedsCreatedByParser
area
article interfaceName=HTMLElement
aside interfaceName=HTMLElement
-audio runtimeEnabled=media, constructorNeedsCreatedByParser
+audio runtimeEnabled=media
b interfaceName=HTMLElement
base
basefont interfaceName=HTMLElement
@@ -66,10 +66,9 @@ html
i interfaceName=HTMLElement
iframe interfaceName=HTMLIFrameElement
image interfaceName=HTMLUnknownElement
-img interfaceName=HTMLImageElement, constructorNeedsFormElement
+img interfaceName=HTMLImageElement, constructorNeedsFormElement, constructorNeedsCreatedByParser
input constructorNeedsFormElement, constructorNeedsCreatedByParser
ins interfaceName=HTMLModElement
-isindex interfaceName=HTMLUnknownElement
kbd interfaceName=HTMLElement
keygen constructorNeedsFormElement
label
@@ -87,7 +86,7 @@ meta
meter interfaceName=HTMLMeterElement
nav interfaceName=HTMLElement
nobr interfaceName=HTMLElement
-noembed interfaceName=HTMLElement
+noembed interfaceName=HTMLNoEmbedElement, JSInterfaceName=HTMLElement
noframes interfaceName=HTMLElement
nolayer interfaceName=HTMLElement
object constructorNeedsFormElement, constructorNeedsCreatedByParser
@@ -98,18 +97,19 @@ output constructorNeedsFormElement
shadow interfaceName=HTMLShadowElement
p interfaceName=HTMLParagraphElement
param
+picture interfaceName=HTMLPictureElement, runtimeEnabled=picture
plaintext interfaceName=HTMLElement
pre
progress interfaceName=HTMLProgressElement
q interfaceName=HTMLQuoteElement
rp interfaceName=HTMLElement
-rt interfaceName=HTMLElement
-ruby interfaceName=HTMLElement
+rt interfaceName=HTMLRTElement, JSInterfaceName=HTMLElement
+ruby interfaceName=HTMLRubyElement, JSInterfaceName=HTMLElement
s interfaceName=HTMLElement
samp interfaceName=HTMLElement
script constructorNeedsCreatedByParser
section interfaceName=HTMLElement
-select constructorNeedsFormElement, constructorNeedsCreatedByParser
+select constructorNeedsFormElement
small interfaceName=HTMLElement
source runtimeEnabled=media
span
@@ -129,12 +129,12 @@ th interfaceName=HTMLTableCellElement
thead interfaceName=HTMLTableSectionElement
title
tr interfaceName=HTMLTableRowElement
-track runtimeEnabled=videoTrack
+track
tt interfaceName=HTMLElement
u interfaceName=HTMLElement
ul interfaceName=HTMLUListElement
var interfaceName=HTMLElement
-video runtimeEnabled=media, constructorNeedsCreatedByParser
-wbr interfaceName=HTMLElement
+video runtimeEnabled=media
+wbr interfaceName=HTMLWBRElement, JSInterfaceName=HTMLElement
xmp interfaceName=HTMLPreElement
-noscript interfaceName=HTMLElement
+noscript interfaceName=HTMLNoScriptElement, JSInterfaceName=HTMLElement
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp
index 2990838c707..3d24f522f91 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp
@@ -32,6 +32,7 @@
#include "core/html/HTMLTemplateElement.h"
+#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/TemplateContentDocumentFragment.h"
@@ -45,15 +46,14 @@ inline HTMLTemplateElement::HTMLTemplateElement(Document& document)
ScriptWrappable::init(this);
}
+DEFINE_NODE_FACTORY(HTMLTemplateElement)
+
HTMLTemplateElement::~HTMLTemplateElement()
{
+#if !ENABLE(OILPAN)
if (m_content)
m_content->clearHost();
-}
-
-PassRefPtr<HTMLTemplateElement> HTMLTemplateElement::create(Document& document)
-{
- return adoptRef(new HTMLTemplateElement(document));
+#endif
}
DocumentFragment* HTMLTemplateElement::content() const
@@ -64,12 +64,12 @@ DocumentFragment* HTMLTemplateElement::content() const
return m_content.get();
}
-PassRefPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
{
if (!deep)
return cloneElementWithoutChildren();
- RefPtr<Node> clone = cloneElementWithChildren();
+ RefPtrWillBeRawPtr<Node> clone = cloneElementWithChildren();
if (m_content)
content()->cloneChildNodes(toHTMLTemplateElement(clone.get())->content());
return clone.release();
@@ -83,4 +83,10 @@ void HTMLTemplateElement::didMoveToNewDocument(Document& oldDocument)
document().ensureTemplateDocument().adoptIfNeeded(*m_content);
}
+void HTMLTemplateElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_content);
+ HTMLElement::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
index b27958dafb1..78467973f94 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
@@ -40,22 +40,21 @@ class TemplateContentDocumentFragment;
class HTMLTemplateElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTemplateElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTemplateElement);
virtual ~HTMLTemplateElement();
+ virtual void trace(Visitor*) OVERRIDE;
DocumentFragment* content() const;
private:
- virtual PassRefPtr<Node> cloneNode(bool deep = true) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
explicit HTMLTemplateElement(Document&);
- mutable RefPtr<TemplateContentDocumentFragment> m_content;
+ mutable RefPtrWillBeMember<TemplateContentDocumentFragment> m_content;
};
-DEFINE_NODE_TYPE_CASTS(HTMLTemplateElement, hasTagName(HTMLNames::templateTag));
-
} // namespace WebCore
#endif // HTMLTemplateElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
index ca7494e2af6..5b4fde76b34 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
@@ -26,10 +26,10 @@
#include "config.h"
#include "core/html/HTMLTextAreaElement.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/Text.h"
@@ -39,12 +39,14 @@
#include "core/editing/TextIterator.h"
#include "core/events/BeforeTextInsertedEvent.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormDataList.h"
#include "core/html/forms/FormController.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/html/shadow/TextControlInnerElements.h"
-#include "core/frame/Frame.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
#include "core/rendering/RenderTextControlMultiLine.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/StdLibExtras.h"
@@ -81,21 +83,21 @@ HTMLTextAreaElement::HTMLTextAreaElement(Document& document, HTMLFormElement* fo
, m_cols(defaultCols)
, m_wrap(SoftWrap)
, m_isDirty(false)
+ , m_valueIsUpToDate(true)
{
- setFormControlValueMatchesRenderer(true);
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document& document, HTMLFormElement* form)
{
- RefPtr<HTMLTextAreaElement> textArea = adoptRef(new HTMLTextAreaElement(document, form));
+ RefPtrWillBeRawPtr<HTMLTextAreaElement> textArea = adoptRefWillBeNoop(new HTMLTextAreaElement(document, form));
textArea->ensureUserAgentShadowRoot();
return textArea.release();
}
void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
- root.appendChild(TextControlInnerTextElement::create(document()));
+ root.appendChild(TextControlInnerEditorElement::create(document()));
}
const AtomicString& HTMLTextAreaElement::formControlType() const
@@ -119,7 +121,7 @@ void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChan
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
setLastChangeWasNotUserEdit();
if (m_isDirty)
- setInnerTextValue(value());
+ setInnerEditorValue(value());
else
setNonDirtyValue(defaultValue());
}
@@ -160,7 +162,7 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
if (m_rows != rows) {
m_rows = rows;
if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else if (name == colsAttr) {
int cols = value.toInt();
@@ -169,7 +171,7 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
if (m_cols != cols) {
m_cols = cols;
if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else if (name == wrapAttr) {
// The virtual/physical values were a Netscape extension of HTML 3.0, now deprecated.
@@ -184,7 +186,7 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
if (wrap != m_wrap) {
m_wrap = wrap;
if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else if (name == accesskeyAttr) {
// ignore for the moment
@@ -238,12 +240,9 @@ bool HTMLTextAreaElement::shouldShowFocusRingOnMouseFocus() const
void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
{
- if (!restorePreviousSelection || !hasCachedSelection()) {
- // 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
+ if (!restorePreviousSelection)
setSelectionRange(0, 0);
- } else
+ else
restoreCachedSelection();
if (document().frame())
@@ -260,16 +259,16 @@ void HTMLTextAreaElement::defaultEventHandler(Event* event)
HTMLTextFormControlElement::defaultEventHandler(event);
}
-void HTMLTextAreaElement::handleFocusEvent(Element*, FocusDirection)
+void HTMLTextAreaElement::handleFocusEvent(Element*, FocusType)
{
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->spellChecker().didBeginEditing(this);
}
void HTMLTextAreaElement::subtreeHasChanged()
{
setChangedSinceLastFormControlChangeEvent(true);
- setFormControlValueMatchesRenderer(false);
+ m_valueIsUpToDate = false;
setNeedsValidityCheck();
if (!focused())
@@ -277,6 +276,9 @@ void HTMLTextAreaElement::subtreeHasChanged()
// When typing in a textarea, childrenChanged is not called, so we need to force the directionality check.
calculateAndAdjustDirectionality();
+
+ ASSERT(document().isActive());
+ document().frameHost()->chrome().client().didChangeValueInTextField(*this);
}
void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const
@@ -288,7 +290,7 @@ void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
return;
unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength);
- const String& currentValue = innerTextValue();
+ const String& currentValue = innerEditorValue();
unsigned currentLength = computeLengthForSubmission(currentValue);
if (currentLength + computeLengthForSubmission(event->text()) < unsignedMaxLength)
return;
@@ -312,19 +314,14 @@ String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue,
return proposedValue.left(maxLength);
}
-void HTMLTextAreaElement::rendererWillBeDestroyed()
-{
- updateValue();
-}
-
void HTMLTextAreaElement::updateValue() const
{
- if (formControlValueMatchesRenderer())
+ if (m_valueIsUpToDate)
return;
ASSERT(renderer());
- m_value = innerTextValue();
- const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true);
+ m_value = innerEditorValue();
+ const_cast<HTMLTextAreaElement*>(this)->m_valueIsUpToDate = true;
const_cast<HTMLTextAreaElement*>(this)->notifyFormStateChanged();
m_isDirty = true;
const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false);
@@ -336,21 +333,24 @@ String HTMLTextAreaElement::value() const
return m_value;
}
-void HTMLTextAreaElement::setValue(const String& value)
+void HTMLTextAreaElement::setValue(const String& value, TextFieldEventBehavior eventBehavior)
{
- setValueCommon(value);
+ RefPtrWillBeRawPtr<HTMLTextAreaElement> protector(this);
+ setValueCommon(value, eventBehavior);
m_isDirty = true;
setNeedsValidityCheck();
+ if (document().focusedElement() == this)
+ document().frameHost()->chrome().client().didUpdateTextOfFocusedElementByNonUserInput();
}
void HTMLTextAreaElement::setNonDirtyValue(const String& value)
{
- setValueCommon(value);
+ setValueCommon(value, DispatchNoEvent);
m_isDirty = false;
setNeedsValidityCheck();
}
-void HTMLTextAreaElement::setValueCommon(const String& newValue)
+void HTMLTextAreaElement::setValueCommon(const String& newValue, TextFieldEventBehavior eventBehavior)
{
// Code elsewhere normalizes line endings added by the user via the keyboard or pasting.
// We normalize line endings coming from JavaScript here.
@@ -364,11 +364,12 @@ void HTMLTextAreaElement::setValueCommon(const String& newValue)
return;
m_value = normalizedValue;
- setInnerTextValue(m_value);
- setLastChangeWasNotUserEdit();
+ setInnerEditorValue(m_value);
+ if (eventBehavior == DispatchNoEvent)
+ setLastChangeWasNotUserEdit();
updatePlaceholderVisibility(false);
- setNeedsStyleRecalc();
- setFormControlValueMatchesRenderer(true);
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ m_suggestedValue = String();
// Set the caret to the end of the text value.
if (document().focusedElement() == this) {
@@ -377,7 +378,19 @@ void HTMLTextAreaElement::setValueCommon(const String& newValue)
}
notifyFormStateChanged();
- setTextAsOfLastFormControlChangeEvent(normalizedValue);
+ if (eventBehavior == DispatchNoEvent) {
+ setTextAsOfLastFormControlChangeEvent(normalizedValue);
+ } else {
+ if (eventBehavior == DispatchInputAndChangeEvent)
+ dispatchFormControlInputEvent();
+ dispatchFormControlChangeEvent();
+ }
+}
+
+void HTMLTextAreaElement::setInnerEditorValue(const String& value)
+{
+ HTMLTextFormControlElement::setInnerEditorValue(value);
+ m_valueIsUpToDate = true;
}
String HTMLTextAreaElement::defaultValue() const
@@ -395,10 +408,10 @@ String HTMLTextAreaElement::defaultValue() const
void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
// To preserve comments, remove only the text nodes, then add a single text node.
- Vector<RefPtr<Node> > textNodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > textNodes;
for (Node* n = firstChild(); n; n = n->nextSibling()) {
if (n->isTextNode())
textNodes.append(n);
@@ -433,6 +446,23 @@ void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionState& exceptionSt
setIntegralAttribute(maxlengthAttr, newValue);
}
+String HTMLTextAreaElement::suggestedValue() const
+{
+ return m_suggestedValue;
+}
+
+void HTMLTextAreaElement::setSuggestedValue(const String& value)
+{
+ m_suggestedValue = value;
+
+ if (!value.isNull())
+ setInnerEditorValue(m_suggestedValue);
+ else
+ setInnerEditorValue(m_value);
+ updatePlaceholderVisibility(false);
+ setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
String HTMLTextAreaElement::validationMessage() const
{
if (!willValidate())
@@ -511,18 +541,18 @@ bool HTMLTextAreaElement::matchesReadWritePseudoClass() const
void HTMLTextAreaElement::updatePlaceholderText()
{
HTMLElement* placeholder = placeholderElement();
- String placeholderText = strippedPlaceholder();
+ const AtomicString& placeholderText = fastGetAttribute(placeholderAttr);
if (placeholderText.isEmpty()) {
if (placeholder)
userAgentShadowRoot()->removeChild(placeholder);
return;
}
if (!placeholder) {
- RefPtr<HTMLDivElement> newElement = HTMLDivElement::create(document());
+ RefPtrWillBeRawPtr<HTMLDivElement> newElement = HTMLDivElement::create(document());
placeholder = newElement.get();
- placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
+ placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
placeholder->setAttribute(idAttr, ShadowElementNames::placeholder());
- userAgentShadowRoot()->insertBefore(placeholder, innerTextElement()->nextSibling());
+ userAgentShadowRoot()->insertBefore(placeholder, innerEditorElement()->nextSibling());
}
placeholder->setTextContent(placeholderText);
}
@@ -532,4 +562,9 @@ bool HTMLTextAreaElement::isInteractiveContent() const
return true;
}
+bool HTMLTextAreaElement::supportsAutofocus() const
+{
+ return true;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
index a5693348c08..57b3b4e52b8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
@@ -34,28 +34,30 @@ class VisibleSelection;
class HTMLTextAreaElement FINAL : public HTMLTextFormControlElement {
public:
- static PassRefPtr<HTMLTextAreaElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLTextAreaElement> create(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&);
+ virtual String value() const OVERRIDE;
+ void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
String defaultValue() const;
void setDefaultValue(const String&);
int textLength() const { return value().length(); }
- virtual int maxLength() const;
+ int maxLength() const;
void setMaxLength(int, ExceptionState&);
+
+ String suggestedValue() const;
+ void setSuggestedValue(const String&);
+
// For ValidityState
virtual String validationMessage() const OVERRIDE;
virtual bool valueMissing() const OVERRIDE;
virtual bool tooLong() const OVERRIDE;
bool isValidValue(const String&) const;
- void rendererWillBeDestroyed();
-
void setCols(int);
void setRows(int);
@@ -72,47 +74,50 @@ private:
void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) const;
static String sanitizeUserInputValue(const String&, unsigned maxLength);
void updateValue() const;
+ virtual void setInnerEditorValue(const String&) OVERRIDE;
void setNonDirtyValue(const String&);
- void setValueCommon(const String&);
+ void setValueCommon(const String&, TextFieldEventBehavior);
- virtual bool supportsPlaceholder() const { return true; }
- virtual void updatePlaceholderText();
- virtual bool isEmptyValue() const { return value().isEmpty(); }
+ virtual bool supportsPlaceholder() const OVERRIDE { return true; }
+ virtual void updatePlaceholderText() OVERRIDE;
+ virtual bool isEmptyValue() const OVERRIDE { return value().isEmpty(); }
+ virtual bool isEmptySuggestedValue() const OVERRIDE FINAL { return suggestedValue().isEmpty(); }
- virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const { return isRequired(); }
+ virtual bool isOptionalFormControl() const OVERRIDE { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const OVERRIDE { return isRequired(); }
- virtual void defaultEventHandler(Event*);
- virtual void handleFocusEvent(Element* oldFocusedNode, FocusDirection) OVERRIDE;
+ virtual void defaultEventHandler(Event*) OVERRIDE;
+ virtual void handleFocusEvent(Element* oldFocusedNode, FocusType) OVERRIDE;
- virtual void subtreeHasChanged();
+ virtual void subtreeHasChanged() OVERRIDE;
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE;
virtual FormControlState saveFormControlState() const OVERRIDE;
virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
- virtual bool isTextFormControl() const { return true; }
+ virtual bool isTextFormControl() const OVERRIDE { return true; }
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool appendFormData(FormDataList&, bool);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
virtual void resetImpl() OVERRIDE;
virtual bool hasCustomFocusLogic() const OVERRIDE;
virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void updateFocusAppearance(bool restorePreviousSelection);
+ virtual void updateFocusAppearance(bool restorePreviousSelection) OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
- virtual bool shouldUseInputMethod();
+ virtual bool shouldUseInputMethod() OVERRIDE;
virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
virtual bool matchesReadWritePseudoClass() const OVERRIDE;
@@ -124,20 +129,10 @@ private:
WrapMethod m_wrap;
mutable String m_value;
mutable bool m_isDirty;
+ bool m_valueIsUpToDate;
+ String m_suggestedValue;
};
-inline bool isHTMLTextAreaElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::textareaTag);
-}
-
-inline bool isHTMLTextAreaElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::textareaTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLTextAreaElement, hasTagName(HTMLNames::textareaTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl
index e5d79264392..937c8c94193 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl
@@ -56,7 +56,7 @@ interface HTMLTextAreaElement : HTMLElement {
[RaisesException] void setRangeText(DOMString replacement,
unsigned long start,
unsigned long end,
- [Default=NullString] optional DOMString selectionMode);
+ optional DOMString selectionMode = null);
void setSelectionRange([Default=Undefined] optional long start,
[Default=Undefined] optional long end,
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
index d4b83cb03d8..06a5579087d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "core/html/HTMLTextFormControlElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/NodeTraversal.h"
@@ -36,25 +36,24 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/Frame.h"
-#include "core/frame/UseCounter.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderTheme.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document& doc, HTMLFormElement* form)
: HTMLFormControlElementWithState(tagName, doc, form)
, m_lastChangeWasUserEdit(false)
- , m_cachedSelectionStart(-1)
- , m_cachedSelectionEnd(-1)
+ , m_cachedSelectionStart(0)
+ , m_cachedSelectionEnd(0)
, m_cachedSelectionDirection(SelectionHasNoDirection)
{
}
@@ -73,12 +72,12 @@ Node::InsertionNotificationRequest HTMLTextFormControlElement::insertedInto(Cont
return InsertionDone;
}
-void HTMLTextFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLTextFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
{
if (supportsPlaceholder())
updatePlaceholderVisibility(false);
- handleFocusEvent(oldFocusedElement, direction);
- HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
+ handleFocusEvent(oldFocusedElement, type);
+ HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, type);
}
void HTMLTextFormControlElement::dispatchBlurEvent(Element* newFocusedElement)
@@ -104,7 +103,7 @@ void HTMLTextFormControlElement::forwardEvent(Event* event)
{
if (event->type() == EventTypeNames::blur || event->type() == EventTypeNames::focus)
return;
- innerTextElement()->defaultEventHandler(event);
+ innerEditorElement()->defaultEventHandler(event);
}
String HTMLTextFormControlElement::strippedPlaceholder() const
@@ -164,12 +163,12 @@ void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderVal
void HTMLTextFormControlElement::setSelectionStart(int start)
{
- setSelectionRange(start, max(start, selectionEnd()), selectionDirection());
+ setSelectionRange(start, std::max(start, selectionEnd()), selectionDirection());
}
void HTMLTextFormControlElement::setSelectionEnd(int end)
{
- setSelectionRange(min(end, selectionStart()), end, selectionDirection());
+ setSelectionRange(std::min(end, selectionStart()), end, selectionDirection());
}
void HTMLTextFormControlElement::setSelectionDirection(const String& direction)
@@ -179,21 +178,20 @@ void HTMLTextFormControlElement::setSelectionDirection(const String& direction)
void HTMLTextFormControlElement::select()
{
- setSelectionRange(0, numeric_limits<int>::max(), SelectionHasNoDirection);
+ setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection);
}
-String HTMLTextFormControlElement::selectedText() const
+bool HTMLTextFormControlElement::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
{
- if (!isTextFormControl())
- return String();
- return value().substring(selectionStart(), selectionEnd() - selectionStart());
+ return !equalIgnoringNullity(oldValue, newValue);
}
void HTMLTextFormControlElement::dispatchFormControlChangeEvent()
{
- if (m_textAsOfLastFormControlChangeEvent != value()) {
- HTMLElement::dispatchChangeEvent();
- setTextAsOfLastFormControlChangeEvent(value());
+ String newValue = value();
+ if (shouldDispatchFormControlChangeEvent(m_textAsOfLastFormControlChangeEvent, newValue)) {
+ setTextAsOfLastFormControlChangeEvent(newValue);
+ dispatchChangeEvent();
}
setChangedSinceLastFormControlChangeEvent(false);
}
@@ -216,8 +214,10 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
exceptionState.throwDOMException(IndexSizeError, "The provided start value (" + String::number(start) + ") is larger than the provided end value (" + String::number(end) + ").");
return;
}
+ if (hasAuthorShadowRoot())
+ return;
- String text = innerTextValue();
+ String text = innerEditorValue();
unsigned textLength = text.length();
unsigned replacementLength = replacement.length();
unsigned newSelectionStart = selectionStart();
@@ -231,7 +231,7 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
else
text.insert(replacement, start);
- setInnerTextValue(text);
+ setInnerEditorValue(text);
// FIXME: What should happen to the value (as in value()) if there's no renderer?
if (!renderer())
@@ -282,10 +282,10 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
if (!renderer() || !renderer()->isTextControl())
return;
- end = max(end, 0);
- start = min(max(start, 0), end);
+ end = std::max(end, 0);
+ start = std::min(std::max(start, 0), end);
- if (!hasVisibleTextArea(renderer(), innerTextElement())) {
+ if (!hasVisibleTextArea(renderer(), innerEditorElement())) {
cacheSelection(start, end, direction);
return;
}
@@ -309,16 +309,16 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
newSelection = VisibleSelection(startPosition, endPosition);
newSelection.setIsDirectional(direction != SelectionHasNoDirection);
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->selection().setSelection(newSelection);
}
VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) const
{
if (index <= 0)
- return VisiblePosition(firstPositionInNode(innerTextElement()), DOWNSTREAM);
- RefPtr<Range> range = Range::create(document());
- range->selectNodeContents(innerTextElement(), ASSERT_NO_EXCEPTION);
+ return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNSTREAM);
+ RefPtrWillBeRawPtr<Range> range = Range::create(document());
+ range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION);
CharacterIterator it(range.get());
it.advance(index - 1);
return VisiblePosition(it.range()->endPosition(), UPSTREAM);
@@ -330,8 +330,8 @@ int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& p
if (enclosingTextFormControl(indexPosition) != this)
return 0;
ASSERT(indexPosition.document());
- RefPtr<Range> range = Range::create(*indexPosition.document());
- range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document());
+ range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION);
range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainerNode(), ASSERT_NO_EXCEPTION);
return TextIterator::rangeLength(range.get());
}
@@ -340,7 +340,7 @@ int HTMLTextFormControlElement::selectionStart() const
{
if (!isTextFormControl())
return 0;
- if (document().focusedElement() != this && hasCachedSelection())
+ if (document().focusedElement() != this)
return m_cachedSelectionStart;
return computeSelectionStart();
@@ -349,18 +349,18 @@ int HTMLTextFormControlElement::selectionStart() const
int HTMLTextFormControlElement::computeSelectionStart() const
{
ASSERT(isTextFormControl());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 0;
- return indexForVisiblePosition(frame->selection().start());
+ return indexForVisiblePosition(VisiblePosition(frame->selection().start()));
}
int HTMLTextFormControlElement::selectionEnd() const
{
if (!isTextFormControl())
return 0;
- if (document().focusedElement() != this && hasCachedSelection())
+ if (document().focusedElement() != this)
return m_cachedSelectionEnd;
return computeSelectionEnd();
}
@@ -368,11 +368,11 @@ int HTMLTextFormControlElement::selectionEnd() const
int HTMLTextFormControlElement::computeSelectionEnd() const
{
ASSERT(isTextFormControl());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 0;
- return indexForVisiblePosition(frame->selection().end());
+ return indexForVisiblePosition(VisiblePosition(frame->selection().end()));
}
static const AtomicString& directionString(TextFieldSelectionDirection direction)
@@ -398,7 +398,7 @@ const AtomicString& HTMLTextFormControlElement::selectionDirection() const
{
if (!isTextFormControl())
return directionString(SelectionHasNoDirection);
- if (document().focusedElement() != this && hasCachedSelection())
+ if (document().focusedElement() != this)
return directionString(m_cachedSelectionDirection);
return directionString(computeSelectionDirection());
@@ -407,7 +407,7 @@ const AtomicString& HTMLTextFormControlElement::selectionDirection() const
TextFieldSelectionDirection HTMLTextFormControlElement::computeSelectionDirection() const
{
ASSERT(isTextFormControl());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return SelectionHasNoDirection;
@@ -426,18 +426,18 @@ static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*&
}
}
-PassRefPtr<Range> HTMLTextFormControlElement::selection() const
+PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const
{
- if (!renderer() || !isTextFormControl() || !hasCachedSelection())
- return 0;
+ if (!renderer() || !isTextFormControl())
+ return nullptr;
int start = m_cachedSelectionStart;
int end = m_cachedSelectionEnd;
ASSERT(start <= end);
- HTMLElement* innerText = innerTextElement();
+ HTMLElement* innerText = innerEditorElement();
if (!innerText)
- return 0;
+ return nullptr;
if (!innerText->firstChild())
return Range::create(document(), innerText, 0, innerText, 0);
@@ -447,7 +447,7 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const
Node* endNode = 0;
for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
ASSERT(!node->firstChild());
- ASSERT(node->isTextNode() || node->hasTagName(brTag));
+ ASSERT(node->isTextNode() || isHTMLBRElement(*node));
int length = node->isTextNode() ? lastOffsetInNode(node) : 1;
if (offset <= start && start <= offset + length)
@@ -462,7 +462,7 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const
}
if (!startNode || !endNode)
- return 0;
+ return nullptr;
return Range::create(document(), startNode, start, endNode, end);
}
@@ -480,7 +480,7 @@ void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
// selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection());
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
if (frame->selection().isRange() && userTriggered)
dispatchEvent(Event::createBubble(EventTypeNames::select));
}
@@ -502,24 +502,23 @@ bool HTMLTextFormControlElement::lastChangeWasUserEdit() const
return m_lastChangeWasUserEdit;
}
-void HTMLTextFormControlElement::setInnerTextValue(const String& value)
+void HTMLTextFormControlElement::setInnerEditorValue(const String& value)
{
- if (!isTextFormControl())
+ ASSERT(!hasAuthorShadowRoot());
+ if (!isTextFormControl() || hasAuthorShadowRoot())
return;
- bool textIsChanged = value != innerTextValue();
- if (textIsChanged || !innerTextElement()->hasChildNodes()) {
+ bool textIsChanged = value != innerEditorValue();
+ if (textIsChanged || !innerEditorElement()->hasChildren()) {
if (textIsChanged && renderer()) {
if (AXObjectCache* cache = document().existingAXObjectCache())
cache->postNotification(this, AXObjectCache::AXValueChanged, false);
}
- innerTextElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
+ innerEditorElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
if (value.endsWith('\n') || value.endsWith('\r'))
- innerTextElement()->appendChild(HTMLBRElement::create(document()));
+ innerEditorElement()->appendChild(HTMLBRElement::create(document()));
}
-
- setFormControlValueMatchesRenderer(true);
}
static String finishText(StringBuilder& result)
@@ -531,15 +530,16 @@ static String finishText(StringBuilder& result)
return result.toString();
}
-String HTMLTextFormControlElement::innerTextValue() const
+String HTMLTextFormControlElement::innerEditorValue() const
{
- HTMLElement* innerText = innerTextElement();
- if (!innerText || !isTextFormControl())
+ ASSERT(!hasAuthorShadowRoot());
+ HTMLElement* innerEditor = innerEditorElement();
+ if (!innerEditor || !isTextFormControl())
return emptyString();
StringBuilder result;
- for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) {
- if (node->hasTagName(brTag))
+ for (Node* node = innerEditor; node; node = NodeTraversal::next(*node, innerEditor)) {
+ if (isHTMLBRElement(*node))
result.append(newlineCharacter);
else if (node->isTextNode())
result.append(toText(node)->data());
@@ -568,7 +568,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const
{
// 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.
- HTMLElement* innerText = innerTextElement();
+ HTMLElement* innerText = innerEditorElement();
if (!innerText || !isTextFormControl())
return value();
@@ -586,7 +586,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const
StringBuilder result;
for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
- if (node->hasTagName(brTag))
+ if (isHTMLBRElement(*node))
result.append(newlineCharacter);
else if (node->isTextNode()) {
String data = toText(node)->data();
@@ -613,12 +613,15 @@ HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
ASSERT(position.isNull() || position.anchorType() == Position::PositionIsOffsetInAnchor
|| position.containerNode() || !position.anchorNode()->shadowHost()
|| (position.anchorNode()->parentNode() && position.anchorNode()->parentNode()->isShadowRoot()));
+ return enclosingTextFormControl(position.containerNode());
+}
- Node* container = position.containerNode();
+HTMLTextFormControlElement* enclosingTextFormControl(Node* container)
+{
if (!container)
return 0;
Element* ancestor = container->shadowHost();
- return ancestor && isHTMLTextFormControlElement(ancestor) ? toHTMLTextFormControlElement(ancestor) : 0;
+ return ancestor && isHTMLTextFormControlElement(*ancestor) && container->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? toHTMLTextFormControlElement(ancestor) : 0;
}
static const HTMLElement* parentHTMLElement(const Element* element)
@@ -651,7 +654,7 @@ String HTMLTextFormControlElement::directionForFormData() const
return "ltr";
}
-HTMLElement* HTMLTextFormControlElement::innerTextElement() const
+HTMLElement* HTMLTextFormControlElement::innerEditorElement() const
{
return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::innerEditor()));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
index 2c7a9bf8895..6d1c5921f2f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
@@ -31,6 +31,7 @@ namespace WebCore {
class ExceptionState;
class Position;
+class Range;
class RenderTextControl;
class VisiblePosition;
@@ -69,20 +70,18 @@ public:
virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&);
void setSelectionRange(int start, int end, const String& direction);
void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection);
- PassRefPtr<Range> selection() const;
- String selectedText() const;
+ PassRefPtrWillBeRawPtr<Range> selection() const;
- virtual void dispatchFormControlChangeEvent();
+ virtual void dispatchFormControlChangeEvent() OVERRIDE FINAL;
- virtual int maxLength() const = 0;
virtual String value() const = 0;
- HTMLElement* innerTextElement() const;
+ HTMLElement* innerEditorElement() const;
void selectionChanged(bool userTriggered);
bool lastChangeWasUserEdit() const;
- void setInnerTextValue(const String&);
- String innerTextValue() const;
+ virtual void setInnerEditorValue(const String&);
+ String innerEditorValue() const;
String directionForFormData() const;
@@ -97,35 +96,37 @@ protected:
void cacheSelection(int start, int end, TextFieldSelectionDirection direction)
{
+ ASSERT(start >= 0);
m_cachedSelectionStart = start;
m_cachedSelectionEnd = end;
m_cachedSelectionDirection = direction;
}
void restoreCachedSelection();
- bool hasCachedSelection() const { return m_cachedSelectionStart >= 0; }
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void subtreeHasChanged() = 0;
void setLastChangeWasNotUserEdit() { m_lastChangeWasUserEdit = false; }
String valueWithHardLineBreaks() const;
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&);
+
private:
int computeSelectionStart() const;
int computeSelectionEnd() const;
TextFieldSelectionDirection computeSelectionDirection() const;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
- virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE;
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE FINAL;
+ virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE FINAL;
// Returns true if user-editable value is empty. Used to check placeholder visibility.
virtual bool isEmptyValue() const = 0;
// Returns true if suggested value is empty. Used to check placeholder visibility.
virtual bool isEmptySuggestedValue() const { return true; }
// Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
- virtual void handleFocusEvent(Element* /* oldFocusedNode */, FocusDirection) { }
+ virtual void handleFocusEvent(Element* /* oldFocusedNode */, FocusType) { }
// Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
virtual void handleBlurEvent() { }
@@ -137,19 +138,15 @@ private:
TextFieldSelectionDirection m_cachedSelectionDirection;
};
-inline bool isHTMLTextFormControlElement(const Node* node)
-{
- return node->isElementNode() && toElement(node)->isTextFormControl();
-}
-
-inline bool isHTMLTextFormControlElement(const Node& node)
+inline bool isHTMLTextFormControlElement(const Element& element)
{
- return node.isElementNode() && toElement(node).isTextFormControl();
+ return element.isTextFormControl();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
+HTMLTextFormControlElement* enclosingTextFormControl(Node*);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp
new file mode 100644
index 00000000000..1134854814f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLTextFormControlElement.h"
+
+#include "core/frame/FrameView.h"
+#include "core/html/HTMLDocument.h"
+#include "core/testing/DummyPageHolder.h"
+#include "wtf/OwnPtr.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class HTMLTextFormControlElementTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ HTMLTextFormControlElement& textControl() const { return *m_textControl; }
+
+private:
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+
+ RefPtrWillBePersistent<HTMLTextFormControlElement> m_textControl;
+};
+
+void HTMLTextFormControlElementTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+ HTMLDocument& document = toHTMLDocument(m_dummyPageHolder->document());
+ document.documentElement()->setInnerHTML("<body><textarea id=textarea></textarea></body>", ASSERT_NO_EXCEPTION);
+ document.view()->updateLayoutAndStyleIfNeededRecursive();
+ m_textControl = toHTMLTextFormControlElement(document.getElementById("textarea"));
+ m_textControl->focus();
+}
+
+TEST_F(HTMLTextFormControlElementTest, SetSelectionRange)
+{
+ EXPECT_EQ(0, textControl().selectionStart());
+ EXPECT_EQ(0, textControl().selectionEnd());
+
+ textControl().setInnerEditorValue("Hello, text form.");
+ EXPECT_EQ(0, textControl().selectionStart());
+ EXPECT_EQ(0, textControl().selectionEnd());
+
+ textControl().setSelectionRange(1, 3);
+ EXPECT_EQ(1, textControl().selectionStart());
+ EXPECT_EQ(3, textControl().selectionEnd());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp
index c9fdaedc0f2..33060e20b43 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp
@@ -23,8 +23,9 @@
#include "config.h"
#include "core/html/HTMLTitleElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ChildListMutationScope.h"
#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/rendering/style/RenderStyle.h"
@@ -37,15 +38,13 @@ using namespace HTMLNames;
inline HTMLTitleElement::HTMLTitleElement(Document& document)
: HTMLElement(titleTag, document)
+ , m_ignoreTitleUpdatesWhenChildrenChange(false)
{
setHasCustomStyleCallbacks();
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTitleElement> HTMLTitleElement::create(Document& document)
-{
- return adoptRef(new HTMLTitleElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLTitleElement)
Node::InsertionNotificationRequest HTMLTitleElement::insertedInto(ContainerNode* insertionPoint)
{
@@ -65,7 +64,7 @@ void HTMLTitleElement::removedFrom(ContainerNode* insertionPoint)
void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (inDocument() && !isInShadowTree())
+ if (inDocument() && !isInShadowTree() && !m_ignoreTitleUpdatesWhenChildrenChange)
document().setTitleElement(text(), this);
}
@@ -83,23 +82,16 @@ String HTMLTitleElement::text() const
void HTMLTitleElement::setText(const String &value)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
+ ChildListMutationScope mutation(*this);
- int numChildren = childNodeCount();
+ // Avoid calling Document::setTitleElement() during intermediate steps.
+ m_ignoreTitleUpdatesWhenChildrenChange = !value.isEmpty();
+ removeChildren();
+ m_ignoreTitleUpdatesWhenChildrenChange = false;
- if (numChildren == 1 && firstChild()->isTextNode())
- toText(firstChild())->setData(value);
- 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()), IGNORE_EXCEPTION);
- }
+ if (!value.isEmpty())
+ appendChild(document().createTextNode(value.impl()), IGNORE_EXCEPTION);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h
index 988f77ac96e..76f2e6bfb9f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h
@@ -28,7 +28,7 @@ namespace WebCore {
class HTMLTitleElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTitleElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTitleElement);
String text() const;
void setText(const String&);
@@ -38,20 +38,10 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-};
-
-inline bool isHTMLTitleElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::titleTag);
-}
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
-inline bool isHTMLTitleElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::titleTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLTitleElement, hasTagName(HTMLNames::titleTag));
+ bool m_ignoreTitleUpdatesWhenChildrenChange;
+};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
index 0182bcef28f..0c1bae6eeb0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
@@ -26,15 +26,13 @@
#include "config.h"
#include "core/html/HTMLTrackElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/events/Event.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLMediaElement.h"
-#include "core/frame/ContentSecurityPolicy.h"
#include "platform/Logging.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -58,15 +56,14 @@ inline HTMLTrackElement::HTMLTrackElement(Document& document)
ScriptWrappable::init(this);
}
+DEFINE_NODE_FACTORY(HTMLTrackElement)
+
HTMLTrackElement::~HTMLTrackElement()
{
+#if !ENABLE(OILPAN)
if (m_track)
- m_track->clearClient();
-}
-
-PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(Document& document)
-{
- return adoptRef(new HTMLTrackElement(document));
+ m_track->clearTrackElement();
+#endif
}
Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode* insertionPoint)
@@ -79,14 +76,14 @@ Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode*
HTMLElement::insertedInto(insertionPoint);
HTMLMediaElement* parent = mediaElement();
if (insertionPoint == parent)
- parent->didAddTrack(this);
+ parent->didAddTrackElement(this);
return InsertionDone;
}
void HTMLTrackElement::removedFrom(ContainerNode* insertionPoint)
{
- if (!parentNode() && isHTMLMediaElement(insertionPoint))
- toHTMLMediaElement(insertionPoint)->didRemoveTrack(this);
+ if (!parentNode() && isHTMLMediaElement(*insertionPoint))
+ toHTMLMediaElement(insertionPoint)->didRemoveTrackElement(this);
HTMLElement::removedFrom(insertionPoint);
}
@@ -162,7 +159,7 @@ void HTMLTrackElement::scheduleLoad()
return;
// 4. Run the remainder of these steps asynchronously, allowing whatever caused these steps to run to continue.
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void HTMLTrackElement::loadTimerFired(Timer<HTMLTrackElement>*)
@@ -207,7 +204,7 @@ bool HTMLTrackElement::canLoadUrl(const KURL& url)
return false;
}
- return dispatchBeforeLoadEvent(url.string());
+ return true;
}
void HTMLTrackElement::didCompleteLoad(LoadStatus status)
@@ -264,53 +261,18 @@ const AtomicString& HTMLTrackElement::mediaElementCrossOriginAttribute() const
return nullAtom;
}
-void HTMLTrackElement::textTrackKindChanged(TextTrack* track)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackKindChanged(track);
-}
-
-void HTMLTrackElement::textTrackModeChanged(TextTrack* track)
-{
- // Since we've moved to a new parent, we may now be able to load.
- if (readyState() == HTMLTrackElement::NONE)
- scheduleLoad();
-
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackModeChanged(track);
-}
-
-void HTMLTrackElement::textTrackAddCues(TextTrack* track, const TextTrackCueList* cues)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackAddCues(track, cues);
-}
-
-void HTMLTrackElement::textTrackRemoveCues(TextTrack* track, const TextTrackCueList* cues)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackRemoveCues(track, cues);
-}
-
-void HTMLTrackElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackAddCue(track, cue);
-}
-
-void HTMLTrackElement::textTrackRemoveCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackRemoveCue(track, cue);
-}
-
HTMLMediaElement* HTMLTrackElement::mediaElement() const
{
Element* parent = parentElement();
- if (parent && parent->isMediaElement())
- return toHTMLMediaElement(parentNode());
+ if (isHTMLMediaElement(parent))
+ return toHTMLMediaElement(parent);
return 0;
}
+void HTMLTrackElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_track);
+ HTMLElement::trace(visitor);
}
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h
index 9e70146d56d..6657fd51f8d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h
@@ -29,14 +29,15 @@
#include "core/html/HTMLElement.h"
#include "core/html/track/LoadableTextTrack.h"
#include "core/html/track/TextTrack.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class HTMLMediaElement;
-class HTMLTrackElement FINAL : public HTMLElement, public TextTrackClient {
+class HTMLTrackElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTrackElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTrackElement);
const AtomicString& kind();
void setKind(const AtomicString&);
@@ -54,6 +55,8 @@ public:
const AtomicString& mediaElementCrossOriginAttribute() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit HTMLTrackElement(Document&);
virtual ~HTMLTrackElement();
@@ -69,23 +72,13 @@ private:
HTMLMediaElement* mediaElement() const;
- // TextTrackClient
- virtual void textTrackModeChanged(TextTrack*) OVERRIDE;
- virtual void textTrackKindChanged(TextTrack*) OVERRIDE;
- virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
- virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
-
LoadableTextTrack* ensureTrack();
bool canLoadUrl(const KURL&);
- RefPtr<LoadableTextTrack> m_track;
+ RefPtrWillBeMember<LoadableTextTrack> m_track;
Timer<HTMLTrackElement> m_loadTimer;
};
-DEFINE_NODE_TYPE_CASTS(HTMLTrackElement, hasTagName(HTMLNames::trackTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl
index da7e22e9e64..7ad3e606e3d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl
@@ -23,11 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- RuntimeEnabled=VideoTrack
-] interface HTMLTrackElement : HTMLElement {
+interface HTMLTrackElement : HTMLElement {
attribute DOMString kind;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
[Reflect] attribute DOMString srclang;
[Reflect] attribute DOMString label;
[Reflect] attribute boolean default;
@@ -40,4 +38,6 @@
readonly attribute unsigned short readyState;
readonly attribute TextTrack track;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp
index 9eb6e55e679..0261d0f7d78 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp
@@ -23,23 +23,20 @@
#include "config.h"
#include "core/html/HTMLUListElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLUListElement::HTMLUListElement(Document& document)
+inline HTMLUListElement::HTMLUListElement(Document& document)
: HTMLElement(ulTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLUListElement> HTMLUListElement::create(Document& document)
-{
- return adoptRef(new HTMLUListElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLUListElement)
bool HTMLUListElement::isPresentationAttribute(const QualifiedName& name) const
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h
index 899467c4945..9a7c238fb38 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLUListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLUListElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLUListElement);
private:
explicit HTMLUListElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h
index 1c1794c0ed5..09d87365f01 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h
@@ -36,9 +36,9 @@ namespace WebCore {
class HTMLUnknownElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLUnknownElement> create(const QualifiedName& tagName, Document& document)
+ static PassRefPtrWillBeRawPtr<HTMLUnknownElement> create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(new HTMLUnknownElement(tagName, document));
+ return adoptRefWillBeNoop(new HTMLUnknownElement(tagName, document));
}
virtual bool isHTMLUnknownElement() const OVERRIDE { return true; }
@@ -51,12 +51,17 @@ private:
}
};
-inline bool isHTMLUnknownElement(const Node& node)
+inline bool isHTMLUnknownElement(const Element& element)
{
- return node.isElementNode() && toHTMLElement(node).isHTMLUnknownElement();
+ return element.isHTMLElement() && toHTMLElement(element).isHTMLUnknownElement();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLUnknownElement);
+inline bool isHTMLUnknownElement(const HTMLElement& element)
+{
+ return element.isHTMLUnknownElement();
+}
+
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLUnknownElement);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
index b5c1c00ebb4..c03e09716cf 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
@@ -26,15 +26,17 @@
#include "config.h"
#include "core/html/HTMLVideoElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderVideo.h"
#include "platform/UserGestureIndicator.h"
@@ -43,19 +45,26 @@ namespace WebCore {
using namespace HTMLNames;
-inline HTMLVideoElement::HTMLVideoElement(Document& document, bool createdByParser)
- : HTMLMediaElement(videoTag, document, createdByParser)
+inline HTMLVideoElement::HTMLVideoElement(Document& document)
+ : HTMLMediaElement(videoTag, document)
{
ScriptWrappable::init(this);
if (document.settings())
- m_defaultPosterURL = document.settings()->defaultVideoPosterURL();
+ m_defaultPosterURL = AtomicString(document.settings()->defaultVideoPosterURL());
+}
+
+PassRefPtrWillBeRawPtr<HTMLVideoElement> HTMLVideoElement::create(Document& document)
+{
+ RefPtrWillBeRawPtr<HTMLVideoElement> video = adoptRefWillBeNoop(new HTMLVideoElement(document));
+ video->ensureUserAgentShadowRoot();
+ video->suspendIfNeeded();
+ return video.release();
}
-PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(Document& document, bool createdByParser)
+void HTMLVideoElement::trace(Visitor* visitor)
{
- RefPtr<HTMLVideoElement> videoElement(adoptRef(new HTMLVideoElement(document, createdByParser)));
- videoElement->suspendIfNeeded();
- return videoElement.release();
+ visitor->trace(m_imageLoader);
+ HTMLMediaElement::trace(visitor);
}
bool HTMLVideoElement::rendererIsNeeded(const RenderStyle& style)
@@ -75,7 +84,7 @@ void HTMLVideoElement::attach(const AttachContext& context)
updateDisplayState();
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElement();
if (renderer())
toRenderImage(renderer())->imageResource()->setImageResource(m_imageLoader->image());
@@ -107,12 +116,15 @@ void HTMLVideoElement::parseAttribute(const QualifiedName& name, const AtomicStr
updateDisplayState();
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElementIgnoringPreviousError();
} else {
if (renderer())
toRenderImage(renderer())->imageResource()->setImageResource(0);
}
+ // Notify the player when the poster image URL changes.
+ if (player())
+ player()->setPoster(posterImageURL());
} else
HTMLMediaElement::parseAttribute(name, value);
}
@@ -122,7 +134,7 @@ bool HTMLVideoElement::supportsFullscreen() const
if (!document().page())
return false;
- if (!player() || !player()->supportsFullscreen())
+ if (!player())
return false;
return true;
@@ -130,16 +142,16 @@ bool HTMLVideoElement::supportsFullscreen() const
unsigned HTMLVideoElement::videoWidth() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->naturalSize().width();
+ return webMediaPlayer()->naturalSize().width;
}
unsigned HTMLVideoElement::videoHeight() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->naturalSize().height();
+ return webMediaPlayer()->naturalSize().height;
}
bool HTMLVideoElement::isURLAttribute(const Attribute& attribute) const
@@ -163,7 +175,9 @@ void HTMLVideoElement::setDisplayMode(DisplayMode mode)
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 && !hasAvailableVideoFrame())
+ // Don't show the poster if there is a seek operation or
+ // the video has restarted because of loop attribute
+ if (mode == Video && oldMode == Poster && !hasAvailableVideoFrame())
mode = PosterWaitingForVideo;
}
@@ -181,7 +195,7 @@ void HTMLVideoElement::updateDisplayState()
setDisplayMode(Poster);
}
-void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
+void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect) const
{
MediaPlayer* player = HTMLMediaElement::player();
if (!player)
@@ -189,7 +203,7 @@ void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, cons
player->paint(context, destRect);
}
-bool HTMLVideoElement::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY)
+bool HTMLVideoElement::copyVideoTextureToPlatformTexture(blink::WebGraphicsContext3D* context, Platform3DObject texture, GLint level, GLenum type, GLenum internalFormat, bool premultiplyAlpha, bool flipY)
{
if (!player())
return false;
@@ -198,10 +212,10 @@ bool HTMLVideoElement::copyVideoTextureToPlatformTexture(GraphicsContext3D* cont
bool HTMLVideoElement::hasAvailableVideoFrame() const
{
- if (!player())
+ if (!webMediaPlayer())
return false;
- return player()->hasVideo() && player()->readyState() >= MediaPlayer::HaveCurrentData;
+ return webMediaPlayer()->hasVideo() && webMediaPlayer()->readyState() >= blink::WebMediaPlayer::ReadyStateHaveCurrentData;
}
void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
@@ -209,12 +223,6 @@ void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
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 (userGestureRequiredForFullscreen() && !UserGestureIndicator::processingUserGesture()) {
- exceptionState.throwDOMException(InvalidStateError, "This element may only enter fullscreen mode in response to a user gesture ('click', for example).");
- return;
- }
if (!supportsFullscreen()) {
exceptionState.throwDOMException(InvalidStateError, "This element does not support fullscreen mode.");
return;
@@ -248,18 +256,18 @@ void HTMLVideoElement::didMoveToNewDocument(Document& oldDocument)
unsigned HTMLVideoElement::webkitDecodedFrameCount() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->decodedFrameCount();
+ return webMediaPlayer()->decodedFrameCount();
}
unsigned HTMLVideoElement::webkitDroppedFrameCount() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->droppedFrameCount();
+ return webMediaPlayer()->droppedFrameCount();
}
KURL HTMLVideoElement::posterImageURL() const
@@ -270,4 +278,39 @@ KURL HTMLVideoElement::posterImageURL() const
return document().completeURL(url);
}
+KURL HTMLVideoElement::mediaPlayerPosterURL()
+{
+ return posterImageURL();
+}
+
+PassRefPtr<Image> HTMLVideoElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+ if (!hasAvailableVideoFrame()) {
+ *status = InvalidSourceImageStatus;
+ return nullptr;
+ }
+
+ IntSize intrinsicSize(videoWidth(), videoHeight());
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(intrinsicSize);
+ if (!imageBuffer) {
+ *status = InvalidSourceImageStatus;
+ return nullptr;
+ }
+
+ paintCurrentFrameInContext(imageBuffer->context(), IntRect(IntPoint(0, 0), intrinsicSize));
+
+ *status = NormalSourceImageStatus;
+ return imageBuffer->copyImage(mode == CopySourceImageIfVolatile ? CopyBackingStore : DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLVideoElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+ return !hasSingleSecurityOrigin() || (!(webMediaPlayer() && webMediaPlayer()->didPassCORSAccessCheck()) && destinationSecurityOrigin->taintsCanvas(currentSrc()));
+}
+
+FloatSize HTMLVideoElement::sourceSize() const
+{
+ return FloatSize(videoWidth(), videoHeight());
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h
index 4d729f39fa5..fa8f5fe1984 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h
@@ -27,15 +27,21 @@
#define HTMLVideoElement_h
#include "core/html/HTMLMediaElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
+
+namespace blink {
+class WebGraphicsContext3D;
+}
namespace WebCore {
class ExceptionState;
class HTMLImageLoader;
-class HTMLVideoElement FINAL : public HTMLMediaElement {
+class HTMLVideoElement FINAL : public HTMLMediaElement, public CanvasImageSource {
public:
- static PassRefPtr<HTMLVideoElement> create(Document&, bool createdByParser = false);
+ static PassRefPtrWillBeRawPtr<HTMLVideoElement> create(Document&);
+ virtual void trace(Visitor*) OVERRIDE;
unsigned videoWidth() const;
unsigned videoHeight() const;
@@ -51,18 +57,28 @@ public:
unsigned webkitDroppedFrameCount() const;
// Used by canvas to gain raw pixel access
- void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+ void paintCurrentFrameInContext(GraphicsContext*, const IntRect&) const;
// Used by WebGL to do GPU-GPU textures copy if possible.
// See more details at MediaPlayer::copyVideoTextureToPlatformTexture() defined in Source/WebCore/platform/graphics/MediaPlayer.h.
- bool copyVideoTextureToPlatformTexture(GraphicsContext3D*, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY);
+ bool copyVideoTextureToPlatformTexture(blink::WebGraphicsContext3D*, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY);
bool shouldDisplayPosterImage() const { return displayMode() == Poster || displayMode() == PosterWaitingForVideo; }
KURL posterImageURL() const;
+ // FIXME: Remove this when WebMediaPlayerClientImpl::loadInternal does not depend on it.
+ virtual KURL mediaPlayerPosterURL() OVERRIDE;
+
+ // CanvasImageSource implementation
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+ virtual bool isVideoElement() const OVERRIDE { return true; }
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+ virtual const KURL& sourceURL() const OVERRIDE { return currentSrc(); }
+
private:
- HTMLVideoElement(Document&, bool);
+ HTMLVideoElement(Document&);
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
@@ -70,9 +86,8 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual bool isVideo() const OVERRIDE { return true; }
- virtual bool hasVideo() const OVERRIDE { return player() && player()->hasVideo(); }
- virtual bool supportsFullscreen() const OVERRIDE;
+ virtual bool hasVideo() const OVERRIDE { return webMediaPlayer() && webMediaPlayer()->hasVideo(); }
+ bool supportsFullscreen() const;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
@@ -81,23 +96,11 @@ private:
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
virtual void setDisplayMode(DisplayMode) OVERRIDE;
- OwnPtr<HTMLImageLoader> m_imageLoader;
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
AtomicString m_defaultPosterURL;
};
-inline bool isHTMLVideoElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::videoTag);
-}
-
-inline bool isHTMLVideoElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::videoTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLVideoElement, hasTagName(HTMLNames::videoTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl
index 4448cd23542..30825e5b91c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl
@@ -30,17 +30,17 @@
[Reflect] attribute unsigned long height;
readonly attribute unsigned long videoWidth;
readonly attribute unsigned long videoHeight;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString poster;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString poster;
- [MeasureAs=PrefixedVideoSupportsFullscreen] readonly attribute boolean webkitSupportsFullscreen;
- [MeasureAs=PrefixedVideoDisplayingFullscreen] readonly attribute boolean webkitDisplayingFullscreen;
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoSupportsFullscreen] readonly attribute boolean webkitSupportsFullscreen;
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoDisplayingFullscreen] readonly attribute boolean webkitDisplayingFullscreen;
- [MeasureAs=PrefixedVideoEnterFullscreen, RaisesException, PerWorldBindings, ActivityLogging=ForAllWorlds] void webkitEnterFullscreen();
- [MeasureAs=PrefixedVideoExitFullscreen] void webkitExitFullscreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoEnterFullscreen, RaisesException, LogActivity, LogAllWorlds] void webkitEnterFullscreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoExitFullscreen] void webkitExitFullscreen();
// Note the different capitalization of the "S" in FullScreen.
- [MeasureAs=PrefixedVideoEnterFullScreen, ImplementedAs=webkitEnterFullscreen, RaisesException, PerWorldBindings, ActivityLogging=ForAllWorlds] void webkitEnterFullScreen();
- [MeasureAs=PrefixedVideoExitFullScreen, ImplementedAs=webkitExitFullscreen] void webkitExitFullScreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoEnterFullScreen, ImplementedAs=webkitEnterFullscreen, RaisesException, LogActivity, LogAllWorlds] void webkitEnterFullScreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoExitFullScreen, ImplementedAs=webkitExitFullscreen] void webkitExitFullScreen();
// The number of frames that have been decoded and made available for
// playback.
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
index 4a55226d0b4..80bfd5cf740 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/HTMLViewSourceDocument.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/Text.h"
#include "core/html/HTMLAnchorElement.h"
@@ -47,6 +47,12 @@ namespace WebCore {
using namespace HTMLNames;
+namespace {
+
+const char kXSSDetected[] = "Token contains a reflected XSS vector";
+
+} // namespace
+
HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer, const String& mimeType)
: HTMLDocument(initializer)
, m_type(mimeType)
@@ -58,27 +64,27 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer,
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> HTMLViewSourceDocument::createParser()
{
- return HTMLViewSourceParser::create(this, m_type);
+ return HTMLViewSourceParser::create(*this, m_type);
}
void HTMLViewSourceDocument::createContainingTable()
{
- RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*this);
parserAppendChild(html);
- RefPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
html->parserAppendChild(head);
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
html->parserAppendChild(body);
// Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
// document.
- RefPtr<HTMLDivElement> div = HTMLDivElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLDivElement> div = HTMLDivElement::create(*this);
div->setAttribute(classAttr, "webkit-line-gutter-backdrop");
body->parserAppendChild(div);
- RefPtr<HTMLTableElement> table = HTMLTableElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLTableElement> table = HTMLTableElement::create(*this);
body->parserAppendChild(table);
m_tbody = HTMLTableSectionElement::create(tbodyTag, *this);
table->parserAppendChild(m_tbody);
@@ -86,7 +92,7 @@ void HTMLViewSourceDocument::createContainingTable()
m_lineNumber = 0;
}
-void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
+void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token, SourceAnnotation annotation)
{
if (!m_current)
createContainingTable();
@@ -103,13 +109,13 @@ void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
break;
case HTMLToken::StartTag:
case HTMLToken::EndTag:
- processTagToken(source, token);
+ processTagToken(source, token, annotation);
break;
case HTMLToken::Comment:
processCommentToken(source, token);
break;
case HTMLToken::Character:
- processCharacterToken(source, token);
+ processCharacterToken(source, token, annotation);
break;
}
}
@@ -128,8 +134,9 @@ void HTMLViewSourceDocument::processEndOfFileToken(const String& source, HTMLTok
m_current = m_td;
}
-void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token)
+void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token, SourceAnnotation annotation)
{
+ maybeAddSpanForAnnotation(annotation);
m_current = addSpanWithClassName("webkit-html-tag");
AtomicString tagName(token.name());
@@ -139,21 +146,21 @@ void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& to
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(), "");
+ index = addRange(source, index, source.length(), emptyAtom);
ASSERT(index == source.length());
break;
}
AtomicString name(iter->name);
- String value = StringImpl::create8BitIfPossible(iter->value);
+ AtomicString value(StringImpl::create8BitIfPossible(iter->value));
- index = addRange(source, index, iter->nameRange.start - token.startIndex(), "");
+ index = addRange(source, index, iter->nameRange.start - token.startIndex(), emptyAtom);
index = addRange(source, index, iter->nameRange.end - token.startIndex(), "webkit-html-attribute-name");
if (tagName == baseTag && name == hrefAttr)
addBase(value);
- index = addRange(source, index, iter->valueRange.start - token.startIndex(), "");
+ index = addRange(source, index, iter->valueRange.start - token.startIndex(), emptyAtom);
bool isLink = name == srcAttr || name == hrefAttr;
index = addRange(source, index, iter->valueRange.end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag, value);
@@ -170,19 +177,19 @@ void HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken
m_current = m_td;
}
-void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&)
+void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&, SourceAnnotation annotation)
{
- addText(source, "");
+ addText(source, "", annotation);
}
-PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
+PassRefPtrWillBeRawPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
{
if (m_current == m_tbody) {
addLine(className);
return m_current;
}
- RefPtr<HTMLSpanElement> span = HTMLSpanElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLSpanElement> span = HTMLSpanElement::create(*this);
span->setAttribute(classAttr, className);
m_current->parserAppendChild(span);
return span.release();
@@ -191,11 +198,11 @@ PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicStr
void HTMLViewSourceDocument::addLine(const AtomicString& className)
{
// Create a table row.
- RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(*this);
m_tbody->parserAppendChild(trow);
// Create a cell that will hold the line number (it is generated in the stylesheet using counters).
- RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, *this);
+ RefPtrWillBeRawPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, *this);
td->setAttribute(classAttr, "webkit-line-number");
td->setIntegralAttribute(valueAttr, ++m_lineNumber);
trow->parserAppendChild(td);
@@ -216,14 +223,14 @@ void HTMLViewSourceDocument::addLine(const AtomicString& className)
void HTMLViewSourceDocument::finishLine()
{
- if (!m_current->hasChildNodes()) {
- RefPtr<HTMLBRElement> br = HTMLBRElement::create(*this);
+ if (!m_current->hasChildren()) {
+ RefPtrWillBeRawPtr<HTMLBRElement> br = HTMLBRElement::create(*this);
m_current->parserAppendChild(br);
}
m_current = m_tbody;
}
-void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className)
+void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className, SourceAnnotation annotation)
{
if (text.isEmpty())
return;
@@ -242,14 +249,16 @@ void HTMLViewSourceDocument::addText(const String& text, const AtomicString& cla
finishLine();
continue;
}
- RefPtr<Text> t = Text::create(*this, substring);
- m_current->parserAppendChild(t);
+ RefPtrWillBeRawPtr<Element> oldElement = m_current;
+ maybeAddSpanForAnnotation(annotation);
+ m_current->parserAppendChild(Text::create(*this, substring));
+ m_current = oldElement;
if (i < size - 1)
finishLine();
}
}
-int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor, const String& link)
+int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const AtomicString& className, bool isLink, bool isAnchor, const AtomicString& link)
{
ASSERT(start <= end);
if (start == end)
@@ -268,21 +277,21 @@ int HTMLViewSourceDocument::addRange(const String& source, int start, int end, c
return end;
}
-PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
+PassRefPtrWillBeRawPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
{
- RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLBaseElement> base = HTMLBaseElement::create(*this);
base->setAttribute(hrefAttr, href);
m_current->parserAppendChild(base);
return base.release();
}
-PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
+PassRefPtrWillBeRawPtr<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);
+ RefPtrWillBeRawPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*this);
const char* classValue;
if (isAnchor)
classValue = "webkit-html-attribute-value webkit-html-external-link";
@@ -295,4 +304,20 @@ PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, boo
return anchor.release();
}
+void HTMLViewSourceDocument::maybeAddSpanForAnnotation(SourceAnnotation annotation)
+{
+ if (annotation == AnnotateSourceAsXSS) {
+ m_current = addSpanWithClassName("webkit-highlight");
+ m_current->setAttribute(titleAttr, kXSSDetected);
+ }
+}
+
+void HTMLViewSourceDocument::trace(Visitor* visitor)
+{
+ visitor->trace(m_current);
+ visitor->trace(m_tbody);
+ visitor->trace(m_td);
+ HTMLDocument::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h
index a1988cc7e2c..29e44ae7a98 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h
@@ -35,37 +35,46 @@ class HTMLToken;
class HTMLViewSourceDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<HTMLViewSourceDocument> create(const DocumentInit& initializer, const String& mimeType)
+ enum SourceAnnotation {
+ AnnotateSourceAsSafe,
+ AnnotateSourceAsXSS
+ };
+
+ static PassRefPtrWillBeRawPtr<HTMLViewSourceDocument> create(const DocumentInit& initializer, const String& mimeType)
{
- return adoptRef(new HTMLViewSourceDocument(initializer, mimeType));
+ return adoptRefWillBeNoop(new HTMLViewSourceDocument(initializer, mimeType));
}
- void addSource(const String&, HTMLToken&);
+ void addSource(const String&, HTMLToken&, SourceAnnotation);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
HTMLViewSourceDocument(const DocumentInit&, const String& mimeType);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
void processDoctypeToken(const String& source, HTMLToken&);
void processEndOfFileToken(const String& source, HTMLToken&);
- void processTagToken(const String& source, HTMLToken&);
+ void processTagToken(const String& source, HTMLToken&, SourceAnnotation);
void processCommentToken(const String& source, HTMLToken&);
- void processCharacterToken(const String& source, HTMLToken&);
+ void processCharacterToken(const String& source, HTMLToken&, SourceAnnotation);
void createContainingTable();
- PassRefPtr<Element> addSpanWithClassName(const AtomicString&);
+ PassRefPtrWillBeRawPtr<Element> addSpanWithClassName(const AtomicString&);
void addLine(const AtomicString& className);
void finishLine();
- void addText(const String& text, const AtomicString& className);
- int addRange(const String& source, int start, int end, const String& className, bool isLink = false, bool isAnchor = false, const String& link = String());
- PassRefPtr<Element> addLink(const AtomicString& url, bool isAnchor);
- PassRefPtr<Element> addBase(const AtomicString& href);
+ void addText(const String& text, const AtomicString& className, SourceAnnotation = AnnotateSourceAsSafe);
+ int addRange(const String& source, int start, int end, const AtomicString& className, bool isLink = false, bool isAnchor = false, const AtomicString& link = nullAtom);
+ void maybeAddSpanForAnnotation(SourceAnnotation);
+
+ PassRefPtrWillBeRawPtr<Element> addLink(const AtomicString& url, bool isAnchor);
+ PassRefPtrWillBeRawPtr<Element> addBase(const AtomicString& href);
String m_type;
- RefPtr<Element> m_current;
- RefPtr<HTMLTableSectionElement> m_tbody;
- RefPtr<HTMLTableCellElement> m_td;
+ RefPtrWillBeMember<Element> m_current;
+ RefPtrWillBeMember<HTMLTableSectionElement> m_tbody;
+ RefPtrWillBeMember<HTMLTableCellElement> m_td;
int m_lineNumber;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp
index 5d510d1248b..74e06d30b05 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 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
@@ -28,17 +28,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef HTMLImportLoaderClient_h
-#define HTMLImportLoaderClient_h
+#include "config.h"
+#include "core/html/HTMLWBRElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/rendering/RenderWordBreak.h"
namespace WebCore {
-class HTMLImportLoaderClient {
-public:
- virtual ~HTMLImportLoaderClient() { }
- virtual void didFinish() = 0;
-};
+using namespace HTMLNames;
+inline HTMLWBRElement::HTMLWBRElement(Document& document)
+ : HTMLElement(wbrTag, document)
+{
}
-#endif // HTMLImportLoaderClient_h
+DEFINE_NODE_FACTORY(HTMLWBRElement)
+
+RenderObject* HTMLWBRElement::createRenderer(RenderStyle* style)
+{
+ return new RenderWordBreak(this);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/Composition.idl b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h
index 494d2a06b75..0f187e2e309 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/Composition.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 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
@@ -28,12 +28,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// http://www.w3.org/TR/ime-api/
-[
- NoInterfaceObject
-] interface Composition {
- readonly attribute DOMString text;
- readonly attribute long selectionStart;
- readonly attribute long selectionEnd;
- sequence<unsigned long> getSegments();
+#ifndef HTMLWBRElement_h
+#define HTMLWBRElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <wbr> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's createRenderer doesn't need to know about it.
+class HTMLWBRElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLWBRElement);
+
+private:
+ explicit HTMLWBRElement(Document&);
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageData.cpp b/chromium/third_party/WebKit/Source/core/html/ImageData.cpp
index 64c86c931b6..14b6fbed3ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageData.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ImageData.cpp
@@ -29,37 +29,104 @@
#include "config.h"
#include "core/html/ImageData.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
namespace WebCore {
-PassRefPtr<ImageData> ImageData::create(const IntSize& size)
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(const IntSize& size)
{
Checked<int, RecordOverflow> dataSize = 4;
dataSize *= size.width();
dataSize *= size.height();
if (dataSize.hasOverflowed())
- return 0;
+ return nullptr;
- return adoptRef(new ImageData(size));
+ return adoptRefWillBeNoop(new ImageData(size));
}
-PassRefPtr<ImageData> ImageData::create(const IntSize& size, PassRefPtr<Uint8ClampedArray> byteArray)
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(const IntSize& size, PassRefPtr<Uint8ClampedArray> byteArray)
{
Checked<int, RecordOverflow> dataSize = 4;
dataSize *= size.width();
dataSize *= size.height();
if (dataSize.hasOverflowed())
- return 0;
+ return nullptr;
if (dataSize.unsafeGet() < 0
|| static_cast<unsigned>(dataSize.unsafeGet()) > byteArray->length())
- return 0;
+ return nullptr;
+
+ return adoptRefWillBeNoop(new ImageData(size, byteArray));
+}
+
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(unsigned width, unsigned height, ExceptionState& exceptionState)
+{
+ if (!RuntimeEnabledFeatures::imageDataConstructorEnabled()) {
+ exceptionState.throwTypeError("Illegal constructor");
+ return nullptr;
+ }
+ if (!width || !height) {
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is zero or not a number.", width ? "height" : "width"));
+ return nullptr;
+ }
+
+ Checked<unsigned, RecordOverflow> dataSize = 4;
+ dataSize *= width;
+ dataSize *= height;
+ if (dataSize.hasOverflowed()) {
+ exceptionState.throwDOMException(IndexSizeError, "The requested image size exceeds the supported range.");
+ return nullptr;
+ }
+
+ RefPtrWillBeRawPtr<ImageData> imageData = adoptRefWillBeNoop(new ImageData(IntSize(width, height)));
+ imageData->data()->zeroFill();
+ return imageData.release();
+}
+
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(Uint8ClampedArray* data, unsigned width, unsigned height, ExceptionState& exceptionState)
+{
+ if (!RuntimeEnabledFeatures::imageDataConstructorEnabled()) {
+ exceptionState.throwTypeError("Illegal constructor");
+ return nullptr;
+ }
+ if (!data) {
+ exceptionState.throwTypeError("Expected a Uint8ClampedArray as first argument.");
+ return nullptr;
+ }
+ if (!width) {
+ exceptionState.throwDOMException(IndexSizeError, "The source width is zero or not a number.");
+ return nullptr;
+ }
+
+ unsigned length = data->length();
+ if (!length) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data has a zero byte length.");
+ return nullptr;
+ }
+ if (length % 4) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data byte length is not a multiple of 4.");
+ return nullptr;
+ }
+ length /= 4;
+ if (length % width) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data byte length is not a multiple of (4 * width).");
+ return nullptr;
+ }
+ if (!height) {
+ height = length / width;
+ } else if (height != length / width) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data byte length is not equal to (4 * width * height).");
+ return nullptr;
+ }
- return adoptRef(new ImageData(size, byteArray));
+ return adoptRefWillBeNoop(new ImageData(IntSize(width, height), data));
}
ImageData::ImageData(const IntSize& size)
: m_size(size)
- , m_data(Uint8ClampedArray::createUninitialized(size.width() * size.height() * 4))
+ , m_data(Uint8ClampedArray::create(size.width() * size.height() * 4))
{
ScriptWrappable::init(this);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageData.h b/chromium/third_party/WebKit/Source/core/html/ImageData.h
index 5015885998b..94fbaa10c72 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageData.h
+++ b/chromium/third_party/WebKit/Source/core/html/ImageData.h
@@ -31,24 +31,31 @@
#include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/IntSize.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
#include "wtf/Uint8ClampedArray.h"
namespace WebCore {
-class ImageData : public RefCounted<ImageData>, public ScriptWrappable {
+class ExceptionState;
+
+class ImageData FINAL : public RefCountedWillBeGarbageCollectedFinalized<ImageData>, public ScriptWrappable {
public:
- static PassRefPtr<ImageData> create(const IntSize&);
- static PassRefPtr<ImageData> create(const IntSize&, PassRefPtr<Uint8ClampedArray>);
+ static PassRefPtrWillBeRawPtr<ImageData> create(const IntSize&);
+ static PassRefPtrWillBeRawPtr<ImageData> create(const IntSize&, PassRefPtr<Uint8ClampedArray>);
+ static PassRefPtrWillBeRawPtr<ImageData> create(unsigned width, unsigned height, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<ImageData> create(Uint8ClampedArray*, unsigned width, unsigned height, ExceptionState&);
IntSize size() const { return m_size; }
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
Uint8ClampedArray* data() const { return m_data.get(); }
+ void trace(Visitor*) { }
+
private:
- ImageData(const IntSize&);
+ explicit ImageData(const IntSize&);
ImageData(const IntSize&, PassRefPtr<Uint8ClampedArray>);
IntSize m_size;
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageData.idl b/chromium/third_party/WebKit/Source/core/html/ImageData.idl
index 06847999097..18ed72f2478 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageData.idl
+++ b/chromium/third_party/WebKit/Source/core/html/ImageData.idl
@@ -26,10 +26,16 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
+
[
+ Constructor(unsigned long width, unsigned long height),
+ Constructor(Uint8ClampedArray data, unsigned long width, [Default=Undefined] optional unsigned long height),
Custom=Wrap,
+ Exposed=Window&Worker,
+ RaisesException=Constructor,
+ WillBeGarbageCollected,
] interface ImageData {
readonly attribute long width;
readonly attribute long height;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp b/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp
index aaeff99d644..62903c2344c 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -25,13 +25,15 @@
#include "config.h"
#include "core/html/ImageDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/RawDataDocumentParser.h"
#include "core/events/EventListener.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLHtmlElement.h"
@@ -40,9 +42,6 @@
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/Settings.h"
#include "wtf/text/StringBuilder.h"
using std::min;
@@ -77,9 +76,9 @@ private:
class ImageDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<ImageDocumentParser> create(ImageDocument* document)
+ static PassRefPtrWillBeRawPtr<ImageDocumentParser> create(ImageDocument* document)
{
- return adoptRef(new ImageDocumentParser(document));
+ return adoptRefWillBeNoop(new ImageDocumentParser(document));
}
ImageDocument* document() const
@@ -101,7 +100,7 @@ private:
static float pageZoomFactor(const Document* document)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
return frame ? frame->pageZoomFactor() : 1;
}
@@ -124,18 +123,22 @@ void ImageDocumentParser::appendBytes(const char* data, size_t length)
if (!length)
return;
- Frame* frame = document()->frame();
+ LocalFrame* frame = document()->frame();
Settings* settings = frame->settings();
if (!frame->loader().client()->allowImage(!settings || settings->imagesEnabled(), document()->url()))
return;
- document()->cachedImage()->appendData(data, length);
+ if (document()->cachedImage())
+ document()->cachedImage()->appendData(data, length);
+ // Make sure the image renderer gets created because we need the renderer
+ // to read the aspect ratio. See crbug.com/320244
+ document()->updateRenderTreeIfNeeded();
document()->imageUpdated();
}
void ImageDocumentParser::finish()
{
- if (!isStopped() && document()->imageElement()) {
+ if (!isStopped() && document()->imageElement() && document()->cachedImage()) {
ImageResource* cachedImage = document()->cachedImage();
cachedImage->finish();
cachedImage->setResponse(document()->frame()->loader().documentLoader()->response());
@@ -162,7 +165,7 @@ void ImageDocumentParser::finish()
ImageDocument::ImageDocument(const DocumentInit& initializer)
: HTMLDocument(initializer, ImageDocumentClass)
- , m_imageElement(0)
+ , m_imageElement(nullptr)
, m_imageSizeIsKnown(false)
, m_didShrinkImage(false)
, m_shouldShrinkImage(shouldShrinkToFit())
@@ -171,27 +174,27 @@ ImageDocument::ImageDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> ImageDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> ImageDocument::createParser()
{
return ImageDocumentParser::create(this);
}
void ImageDocument::createDocumentStructure()
{
- RefPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
appendChild(rootElement);
rootElement->insertedByParser();
if (frame())
frame()->loader().dispatchDocumentElementAvailable();
- RefPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
- RefPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
meta->setAttribute(nameAttr, "viewport");
- meta->setAttribute(contentAttr, "width=device-width");
+ meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1");
head->appendChild(meta);
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
body->setAttribute(styleAttr, "margin: 0px;");
m_imageElement = HTMLImageElement::create(*this);
@@ -203,7 +206,7 @@ void ImageDocument::createDocumentStructure()
if (shouldShrinkToFit()) {
// Add event listeners
RefPtr<EventListener> listener = ImageEventListener::create(this);
- if (DOMWindow* domWindow = this->domWindow())
+ if (LocalDOMWindow* domWindow = this->domWindow())
domWindow->addEventListener("resize", listener, false);
m_imageElement->addEventListener("click", listener.release(), false);
}
@@ -224,15 +227,15 @@ float ImageDocument::scale() const
LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
LayoutSize windowSize = LayoutSize(view->width(), view->height());
- float widthScale = (float)windowSize.width() / imageSize.width();
- float heightScale = (float)windowSize.height() / imageSize.height();
+ float widthScale = windowSize.width().toFloat() / imageSize.width().toFloat();
+ float heightScale = windowSize.height().toFloat() / imageSize.height().toFloat();
return min(widthScale, heightScale);
}
-void ImageDocument::resizeImageToFit()
+void ImageDocument::resizeImageToFit(ScaleType type)
{
- if (!m_imageElement || m_imageElement->document() != this || pageZoomFactor(this) > 1)
+ if (!m_imageElement || m_imageElement->document() != this || (pageZoomFactor(this) > 1 && type == ScaleOnlyUnzoomedDocument))
return;
LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
@@ -241,7 +244,7 @@ void ImageDocument::resizeImageToFit()
m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomIn);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
}
void ImageDocument::imageClicked(int x, int y)
@@ -252,9 +255,9 @@ void ImageDocument::imageClicked(int x, int y)
m_shouldShrinkImage = !m_shouldShrinkImage;
if (m_shouldShrinkImage)
- windowSizeChanged();
+ windowSizeChanged(ScaleZoomedDocument);
else {
- restoreImageSize();
+ restoreImageSize(ScaleZoomedDocument);
updateLayout();
@@ -281,13 +284,13 @@ void ImageDocument::imageUpdated()
if (shouldShrinkToFit()) {
// Force resizing of the image
- windowSizeChanged();
+ windowSizeChanged(ScaleOnlyUnzoomedDocument);
}
}
-void ImageDocument::restoreImageSize()
+void ImageDocument::restoreImageSize(ScaleType type)
{
- if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this || pageZoomFactor(this) < 1)
+ if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this || (pageZoomFactor(this) < 1 && type == ScaleOnlyUnzoomedDocument))
return;
LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), 1.0f);
@@ -297,7 +300,7 @@ void ImageDocument::restoreImageSize()
if (imageFitsInWindow())
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
m_didShrinkImage = false;
}
@@ -317,7 +320,7 @@ bool ImageDocument::imageFitsInWindow() const
return imageSize.width() <= windowSize.width() && imageSize.height() <= windowSize.height();
}
-void ImageDocument::windowSizeChanged()
+void ImageDocument::windowSizeChanged(ScaleType type)
{
if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this)
return;
@@ -330,7 +333,7 @@ void ImageDocument::windowSizeChanged()
if (fitsInWindow)
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
return;
}
@@ -338,13 +341,13 @@ void ImageDocument::windowSizeChanged()
// If the window has been resized so that the image fits, restore the image size
// otherwise update the restored image size.
if (fitsInWindow)
- restoreImageSize();
+ restoreImageSize(type);
else
- resizeImageToFit();
+ resizeImageToFit(type);
} else {
// If the image isn't resized but needs to be, then resize it.
if (!fitsInWindow) {
- resizeImageToFit();
+ resizeImageToFit(type);
m_didShrinkImage = true;
}
}
@@ -363,18 +366,26 @@ bool ImageDocument::shouldShrinkToFit() const
return frame()->settings()->shrinksStandaloneImagesToFit() && frame()->isMainFrame();
}
+#if !ENABLE(OILPAN)
void ImageDocument::dispose()
{
- m_imageElement = 0;
+ m_imageElement = nullptr;
HTMLDocument::dispose();
}
+#endif
+
+void ImageDocument::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageElement);
+ HTMLDocument::trace(visitor);
+}
// --------
void ImageEventListener::handleEvent(ExecutionContext*, Event* event)
{
if (event->type() == EventTypeNames::resize)
- m_doc->windowSizeChanged();
+ m_doc->windowSizeChanged(ImageDocument::ScaleOnlyUnzoomedDocument);
else if (event->type() == EventTypeNames::click && event->isMouseEvent()) {
MouseEvent* mouseEvent = toMouseEvent(event);
m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageDocument.h b/chromium/third_party/WebKit/Source/core/html/ImageDocument.h
index 896a46261da..b52f08f34e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/ImageDocument.h
@@ -35,32 +35,41 @@ class HTMLImageElement;
class ImageDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<ImageDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<ImageDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new ImageDocument(initializer));
+ return adoptRefWillBeNoop(new ImageDocument(initializer));
}
+ enum ScaleType {
+ ScaleZoomedDocument,
+ ScaleOnlyUnzoomedDocument
+ };
+
ImageResource* cachedImage();
HTMLImageElement* imageElement() const { return m_imageElement.get(); }
- void windowSizeChanged();
+ void windowSizeChanged(ScaleType);
void imageUpdated();
void imageClicked(int x, int y);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ImageDocument(const DocumentInit&);
+ explicit ImageDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
+#if !ENABLE(OILPAN)
virtual void dispose() OVERRIDE;
+#endif
void createDocumentStructure();
- void resizeImageToFit();
- void restoreImageSize();
+ void resizeImageToFit(ScaleType);
+ void restoreImageSize(ScaleType);
bool imageFitsInWindow() const;
bool shouldShrinkToFit() const;
float scale() const;
- RefPtr<HTMLImageElement> m_imageElement;
+ RefPtrWillBeMember<HTMLImageElement> m_imageElement;
// Whether enough of the image has been loaded to determine its size
bool m_imageSizeIsKnown;
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp b/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp
index ad302516baf..5233425facd 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp
@@ -39,12 +39,17 @@ LabelableElement::~LabelableElement()
{
}
-PassRefPtr<NodeList> LabelableElement::labels()
+PassRefPtrWillBeRawPtr<LabelsNodeList> LabelableElement::labels()
{
if (!supportLabels())
- return 0;
+ return nullptr;
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<LabelsNodeList>(this, LabelsNodeListType, starAtom);
+ return ensureRareData().ensureNodeLists().addCache<LabelsNodeList>(*this, LabelsNodeListType);
+}
+
+void LabelableElement::trace(Visitor* visitor)
+{
+ HTMLElement::trace(visitor);
}
} // namespace Webcore
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelableElement.h b/chromium/third_party/WebKit/Source/core/html/LabelableElement.h
index f3d2188dbfb..b633b8ab5a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelableElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/LabelableElement.h
@@ -35,14 +35,18 @@
namespace WebCore {
+class LabelsNodeList;
+
// LabelableElement represents "labelable element" defined in the HTML
// specification, and provides the implementation of the "labels" attribute.
class LabelableElement : public HTMLElement {
public:
virtual ~LabelableElement();
- PassRefPtr<NodeList> labels();
+ PassRefPtrWillBeRawPtr<LabelsNodeList> labels();
virtual bool supportLabels() const { return false; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
LabelableElement(const QualifiedName& tagName, Document&);
@@ -50,12 +54,17 @@ private:
virtual bool isLabelable() const OVERRIDE FINAL { return true; }
};
-inline bool isLabelableElement(const Node& node)
+inline bool isLabelableElement(const Element& element)
+{
+ return element.isHTMLElement() && toHTMLElement(element).isLabelable();
+}
+
+inline bool isLabelableElement(const HTMLElement& element)
{
- return node.isHTMLElement() && toHTMLElement(node).isLabelable();
+ return element.isLabelable();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(LabelableElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(LabelableElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
index a3a6579370f..389af27af5f 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/html/LabelsNodeList.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/dom/NodeRareData.h"
#include "core/html/HTMLLabelElement.h"
@@ -33,19 +33,21 @@ namespace WebCore {
using namespace HTMLNames;
-LabelsNodeList::LabelsNodeList(Node* ownerNode)
+LabelsNodeList::LabelsNodeList(ContainerNode& ownerNode)
: LiveNodeList(ownerNode, LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument)
{
}
LabelsNodeList::~LabelsNodeList()
{
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, LabelsNodeListType, starAtom);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, LabelsNodeListType);
+#endif
}
-bool LabelsNodeList::nodeMatches(Element* testNode) const
+bool LabelsNodeList::elementMatches(const Element& element) const
{
- return isHTMLLabelElement(testNode) && toHTMLLabelElement(testNode)->control() == ownerNode();
+ return isHTMLLabelElement(element) && toHTMLLabelElement(element).control() == ownerNode();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h
index 0e5b125ca69..4a8a485be33 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h
@@ -32,18 +32,18 @@ namespace WebCore {
class LabelsNodeList FINAL : public LiveNodeList {
public:
- static PassRefPtr<LabelsNodeList> create(Node* ownerNode, CollectionType type, const AtomicString&)
+ static PassRefPtrWillBeRawPtr<LabelsNodeList> create(ContainerNode& ownerNode, CollectionType type)
{
ASSERT_UNUSED(type, type == LabelsNodeListType);
- return adoptRef(new LabelsNodeList(ownerNode));
+ return adoptRefWillBeNoop(new LabelsNodeList(ownerNode));
}
virtual ~LabelsNodeList();
protected:
- explicit LabelsNodeList(Node*);
+ explicit LabelsNodeList(ContainerNode&);
- virtual bool nodeMatches(Element*) const;
+ virtual bool elementMatches(const Element&) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp b/chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp
new file mode 100644
index 00000000000..09153932596
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/LinkManifest.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/loader/FrameLoaderClient.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<LinkManifest> LinkManifest::create(HTMLLinkElement* owner)
+{
+ return adoptPtrWillBeNoop(new LinkManifest(owner));
+}
+
+LinkManifest::LinkManifest(HTMLLinkElement* owner)
+ : LinkResource(owner)
+{
+}
+
+LinkManifest::~LinkManifest()
+{
+}
+
+void LinkManifest::process()
+{
+ if (!m_owner || !m_owner->document().frame())
+ return;
+
+ m_owner->document().frame()->loader().client()->dispatchDidChangeManifest();
+}
+
+bool LinkManifest::hasLoaded() const
+{
+ return false;
+}
+
+void LinkManifest::ownerRemoved()
+{
+ process();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkManifest.h b/chromium/third_party/WebKit/Source/core/html/LinkManifest.h
new file mode 100644
index 00000000000..c89b449818e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/LinkManifest.h
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LinkManifest_h
+#define LinkManifest_h
+
+#include "core/html/LinkResource.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class HTMLLinkElement;
+
+class LinkManifest FINAL : public LinkResource {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+
+ static PassOwnPtrWillBeRawPtr<LinkManifest> create(HTMLLinkElement* owner);
+
+ virtual ~LinkManifest();
+
+ // LinkResource
+ virtual void process() OVERRIDE;
+ virtual Type type() const OVERRIDE { return Manifest; }
+ virtual bool hasLoaded() const OVERRIDE;
+ virtual void ownerRemoved() OVERRIDE;
+
+private:
+ explicit LinkManifest(HTMLLinkElement* owner);
+};
+
+}
+
+#endif // LinkManifest_h
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp
index 0c2f32be4ca..bc2d746167e 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp
@@ -32,22 +32,10 @@
#include "config.h"
#include "core/html/LinkRelAttribute.h"
-#include "wtf/text/WTFString.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-LinkRelAttribute::LinkRelAttribute()
- : m_iconType(InvalidIcon)
- , m_isStyleSheet(false)
- , m_isAlternate(false)
- , m_isDNSPrefetch(false)
- , m_isLinkPrefetch(false)
- , m_isLinkSubresource(false)
- , m_isLinkPrerender(false)
- , m_isImport(false)
-{
-}
-
LinkRelAttribute::LinkRelAttribute(const String& rel)
: m_iconType(InvalidIcon)
, m_isStyleSheet(false)
@@ -56,51 +44,53 @@ LinkRelAttribute::LinkRelAttribute(const String& rel)
, m_isLinkPrefetch(false)
, m_isLinkSubresource(false)
, m_isLinkPrerender(false)
+ , m_isLinkNext(false)
, m_isImport(false)
+ , m_isManifest(false)
+ , m_isTransitionExitingStylesheet(false)
{
- if (equalIgnoringCase(rel, "stylesheet"))
- m_isStyleSheet = true;
- else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
- m_iconType = Favicon;
-#if ENABLE(TOUCH_ICON_LOADING)
- else if (equalIgnoringCase(rel, "apple-touch-icon"))
- m_iconType = TouchIcon;
- else if (equalIgnoringCase(rel, "apple-touch-icon-precomposed"))
- m_iconType = TouchPrecomposedIcon;
-#endif
- else if (equalIgnoringCase(rel, "dns-prefetch"))
- m_isDNSPrefetch = true;
- else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
- m_isStyleSheet = true;
- m_isAlternate = true;
- } else if (equalIgnoringCase(rel, "import")) {
- m_isImport = true;
- } else {
- // Tokenize the rel attribute and set bits based on specific keywords that we find.
- String relCopy = rel;
- relCopy.replace('\n', ' ');
- Vector<String> list;
- relCopy.split(' ', list);
- Vector<String>::const_iterator end = list.end();
- for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
- if (equalIgnoringCase(*it, "stylesheet"))
+ if (rel.isEmpty())
+ return;
+ String relCopy = rel;
+ relCopy.replace('\n', ' ');
+ Vector<String> list;
+ relCopy.split(' ', list);
+ Vector<String>::const_iterator end = list.end();
+ for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
+ if (equalIgnoringCase(*it, "stylesheet")) {
+ if (!m_isImport)
m_isStyleSheet = true;
- else if (equalIgnoringCase(*it, "alternate"))
- m_isAlternate = true;
- else if (equalIgnoringCase(*it, "icon"))
- m_iconType = Favicon;
-#if ENABLE(TOUCH_ICON_LOADING)
- else if (equalIgnoringCase(*it, "apple-touch-icon"))
+ } else if (equalIgnoringCase(*it, "import")) {
+ if (!m_isStyleSheet)
+ m_isImport = true;
+ } else if (equalIgnoringCase(*it, "alternate")) {
+ m_isAlternate = true;
+ } else if (equalIgnoringCase(*it, "icon")) {
+ // This also allows "shortcut icon" since we just ignore the non-standard "shortcut" token.
+ // FIXME: This doesn't really follow the spec that requires "shortcut icon" to be the
+ // entire string http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon
+ m_iconType = Favicon;
+ } else if (equalIgnoringCase(*it, "prefetch")) {
+ m_isLinkPrefetch = true;
+ } else if (equalIgnoringCase(*it, "dns-prefetch")) {
+ m_isDNSPrefetch = true;
+ } else if (equalIgnoringCase(*it, "subresource")) {
+ m_isLinkSubresource = true;
+ } else if (equalIgnoringCase(*it, "prerender")) {
+ m_isLinkPrerender = true;
+ } else if (equalIgnoringCase(*it, "next")) {
+ m_isLinkNext = true;
+ } else if (equalIgnoringCase(*it, "apple-touch-icon")) {
+ if (RuntimeEnabledFeatures::touchIconLoadingEnabled())
m_iconType = TouchIcon;
- else if (equalIgnoringCase(*it, "apple-touch-icon-precomposed"))
+ } else if (equalIgnoringCase(*it, "apple-touch-icon-precomposed")) {
+ if (RuntimeEnabledFeatures::touchIconLoadingEnabled())
m_iconType = TouchPrecomposedIcon;
-#endif
- else if (equalIgnoringCase(*it, "prefetch"))
- m_isLinkPrefetch = true;
- else if (equalIgnoringCase(*it, "subresource"))
- m_isLinkSubresource = true;
- else if (equalIgnoringCase(*it, "prerender"))
- m_isLinkPrerender = true;
+ } else if (equalIgnoringCase(*it, "manifest")) {
+ m_isManifest = true;
+ } else if (equalIgnoringCase(rel, "transition-exiting-stylesheet")) {
+ if (RuntimeEnabledFeatures::navigationTransitionsEnabled())
+ m_isTransitionExitingStylesheet = true;
}
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h
index a124012055d..d4424100e93 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h
+++ b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h
@@ -33,17 +33,13 @@
#define LinkRelAttribute_h
#include "core/dom/IconURL.h"
-
-namespace WTF {
-class String;
-}
+#include "wtf/text/WTFString.h"
namespace WebCore {
class LinkRelAttribute {
public:
- LinkRelAttribute();
- explicit LinkRelAttribute(const String&);
+ explicit LinkRelAttribute(const String& = "");
bool isStyleSheet() const { return m_isStyleSheet; }
IconType iconType() const { return m_iconType; }
@@ -52,7 +48,10 @@ public:
bool isLinkPrefetch() const { return m_isLinkPrefetch; }
bool isLinkSubresource() const { return m_isLinkSubresource; }
bool isLinkPrerender() const { return m_isLinkPrerender; }
+ bool isLinkNext() const { return m_isLinkNext; }
bool isImport() const { return m_isImport; }
+ bool isManifest() const { return m_isManifest; }
+ bool isTransitionExitingStylesheet() const { return m_isTransitionExitingStylesheet; }
private:
IconType m_iconType;
@@ -62,7 +61,10 @@ private:
bool m_isLinkPrefetch : 1;
bool m_isLinkSubresource : 1;
bool m_isLinkPrerender : 1;
+ bool m_isLinkNext : 1;
bool m_isImport : 1;
+ bool m_isManifest : 1;
+ bool m_isTransitionExitingStylesheet : 1;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp b/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp
index beac0e64066..e75ea4d97eb 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp
@@ -30,6 +30,7 @@
#include "config.h"
#include "core/html/LinkRelAttribute.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/text/CString.h"
#include <gtest/gtest.h>
@@ -38,6 +39,22 @@ using namespace WebCore;
namespace {
+class LinkRelAttributeTest : public testing::Test {
+protected:
+ virtual void SetUp()
+ {
+ m_touchIconLoadingEnabled = RuntimeEnabledFeatures::touchIconLoadingEnabled();
+ }
+
+ virtual void TearDown()
+ {
+ RuntimeEnabledFeatures::setTouchIconLoadingEnabled(m_touchIconLoadingEnabled);
+ }
+
+private:
+ bool m_touchIconLoadingEnabled;
+};
+
static inline void testLinkRelAttribute(String value, bool isStyleSheet, IconType iconType, bool isAlternate, bool isDNSPrefetch, bool isLinkSubresource, bool isLinkPrerender, bool isImport = false)
{
LinkRelAttribute linkRelAttribute(value);
@@ -50,8 +67,10 @@ static inline void testLinkRelAttribute(String value, bool isStyleSheet, IconTyp
ASSERT_EQ(isImport, linkRelAttribute.isImport()) << value.utf8().data();
}
-TEST(CoreLinkRelAttribute, Constructor)
+TEST_F(LinkRelAttributeTest, Constructor)
{
+ RuntimeEnabledFeatures::setTouchIconLoadingEnabled(false);
+
testLinkRelAttribute("stylesheet", true, InvalidIcon, false, false, false, false);
testLinkRelAttribute("sTyLeShEeT", true, InvalidIcon, false, false, false, false);
@@ -60,16 +79,48 @@ TEST(CoreLinkRelAttribute, Constructor)
testLinkRelAttribute("shortcut icon", false, Favicon, false, false, false, false);
testLinkRelAttribute("sHoRtCuT iCoN", false, Favicon, false, false, false, false);
-#if ENABLE(TOUCH_ICON_LOADING)
- testLinkRelAttribute("apple-touch-icon", false, TouchIcon, false, false, false, false);
- testLinkRelAttribute("aPpLe-tOuCh-IcOn", false, TouchIcon, false, false, false, false);
+ testLinkRelAttribute("dns-prefetch", false, InvalidIcon, false, true, false, false);
+ testLinkRelAttribute("dNs-pReFeTcH", false, InvalidIcon, false, true, false, false);
- testLinkRelAttribute("apple-touch-icon-precomposed", false, TouchPrecomposedIcon, false, false, false, false);
- testLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false, TouchPrecomposedIcon, false, false, false, false);
-#endif
+ testLinkRelAttribute("apple-touch-icon", false, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn", false, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("apple-touch-icon-precomposed", false, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false, InvalidIcon, false, false, false, false);
+
+ testLinkRelAttribute("alternate stylesheet", true, InvalidIcon, true, false, false, false);
+ testLinkRelAttribute("stylesheet alternate", true, InvalidIcon, true, false, false, false);
+ testLinkRelAttribute("aLtErNaTe sTyLeShEeT", true, InvalidIcon, true, false, false, false);
+ testLinkRelAttribute("sTyLeShEeT aLtErNaTe", true, InvalidIcon, true, false, false, false);
+
+ testLinkRelAttribute("stylesheet icon prerender aLtErNaTe", true, Favicon, true, false, false, true);
+ testLinkRelAttribute("alternate subresource", false, InvalidIcon, true, false, true, false);
+ testLinkRelAttribute("alternate icon stylesheet", true, Favicon, true, false, false, false);
+
+ testLinkRelAttribute("import", false, InvalidIcon, false, false, false, false, true);
+ // "import" is mutually exclusive and "stylesheet" wins when they conflict.
+ testLinkRelAttribute("stylesheet import", true, InvalidIcon, false, false, false, false, false);
+}
+
+TEST_F(LinkRelAttributeTest, ConstructorTouchIconLoadingEnabled)
+{
+ RuntimeEnabledFeatures::setTouchIconLoadingEnabled(true);
+
+ testLinkRelAttribute("stylesheet", true, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("sTyLeShEeT", true, InvalidIcon, false, false, false, false);
+
+ testLinkRelAttribute("icon", false, Favicon, false, false, false, false);
+ testLinkRelAttribute("iCoN", false, Favicon, false, false, false, false);
+ testLinkRelAttribute("shortcut icon", false, Favicon, false, false, false, false);
+ testLinkRelAttribute("sHoRtCuT iCoN", false, Favicon, false, false, false, false);
testLinkRelAttribute("dns-prefetch", false, InvalidIcon, false, true, false, false);
testLinkRelAttribute("dNs-pReFeTcH", false, InvalidIcon, false, true, false, false);
+ testLinkRelAttribute("alternate dNs-pReFeTcH", false, InvalidIcon, true, true, false, false);
+
+ testLinkRelAttribute("apple-touch-icon", false, TouchIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn", false, TouchIcon, false, false, false, false);
+ testLinkRelAttribute("apple-touch-icon-precomposed", false, TouchPrecomposedIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false, TouchPrecomposedIcon, false, false, false, false);
testLinkRelAttribute("alternate stylesheet", true, InvalidIcon, true, false, false, false);
testLinkRelAttribute("stylesheet alternate", true, InvalidIcon, true, false, false, false);
@@ -81,7 +132,7 @@ TEST(CoreLinkRelAttribute, Constructor)
testLinkRelAttribute("alternate icon stylesheet", true, Favicon, true, false, false, false);
testLinkRelAttribute("import", false, InvalidIcon, false, false, false, false, true);
- // "import" is mutually exclusive and "stylesheet" wins when they conflict.
+ testLinkRelAttribute("alternate import", false, InvalidIcon, true, false, false, false, true);
testLinkRelAttribute("stylesheet import", true, InvalidIcon, false, false, false, false, false);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp b/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp
index ef239527a14..850fbd40d6d 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp
@@ -31,9 +31,10 @@
#include "config.h"
#include "core/html/LinkResource.h"
-#include "HTMLNames.h"
-#include "core/html/HTMLImport.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLLinkElement.h"
+#include "core/html/imports/HTMLImportsController.h"
namespace WebCore {
@@ -50,15 +51,20 @@ LinkResource::~LinkResource()
bool LinkResource::shouldLoadResource() const
{
- return m_owner->document().frame() || m_owner->document().import();
+ return m_owner->document().frame() || m_owner->document().importsController();
}
-Frame* LinkResource::loadingFrame() const
+LocalFrame* LinkResource::loadingFrame() const
{
- HTMLImport* import = m_owner->document().import();
- if (!import)
+ HTMLImportsController* importsController = m_owner->document().importsController();
+ if (!importsController)
return m_owner->document().frame();
- return import->master()->document().frame();
+ return importsController->master()->frame();
+}
+
+void LinkResource::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
}
LinkRequestBuilder::LinkRequestBuilder(HTMLLinkElement* owner)
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkResource.h b/chromium/third_party/WebKit/Source/core/html/LinkResource.h
index a922639d216..93815b08526 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkResource.h
+++ b/chromium/third_party/WebKit/Source/core/html/LinkResource.h
@@ -32,6 +32,7 @@
#define LinkResource_h
#include "core/fetch/FetchRequest.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/text/WTFString.h"
@@ -39,30 +40,35 @@ namespace WebCore {
class HTMLLinkElement;
-class LinkResource {
- WTF_MAKE_NONCOPYABLE(LinkResource); WTF_MAKE_FAST_ALLOCATED;
+class LinkResource : public NoBaseWillBeGarbageCollectedFinalized<LinkResource> {
+ WTF_MAKE_NONCOPYABLE(LinkResource); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
enum Type {
Style,
- Import
+ Import,
+ Manifest
};
explicit LinkResource(HTMLLinkElement*);
virtual ~LinkResource();
bool shouldLoadResource() const;
- Frame* loadingFrame() const;
+ LocalFrame* loadingFrame() const;
virtual Type type() const = 0;
virtual void process() = 0;
- virtual void ownerRemoved() = 0;
+ virtual void ownerRemoved() { }
+ virtual void ownerInserted() { }
virtual bool hasLoaded() const = 0;
+ virtual void trace(Visitor*);
+
protected:
- HTMLLinkElement* m_owner;
+ RawPtrWillBeMember<HTMLLinkElement> m_owner;
};
class LinkRequestBuilder {
+ STACK_ALLOCATED();
public:
explicit LinkRequestBuilder(HTMLLinkElement* owner);
@@ -72,7 +78,7 @@ public:
FetchRequest build(bool blocking) const;
private:
- HTMLLinkElement* m_owner;
+ RawPtrWillBeMember<HTMLLinkElement> m_owner;
KURL m_url;
AtomicString m_charset;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaController.cpp b/chromium/third_party/WebKit/Source/core/html/MediaController.cpp
index e93bbc1df30..2cf4b0a9863 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaController.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaController.cpp
@@ -30,6 +30,9 @@
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/ExecutionContext.h"
+#include "core/events/Event.h"
+#include "core/events/GenericEventQueue.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/TimeRanges.h"
#include "platform/Clock.h"
@@ -37,12 +40,11 @@
#include "wtf/StdLibExtras.h"
#include "wtf/text/AtomicString.h"
-using namespace WebCore;
-using namespace std;
+namespace WebCore {
-PassRefPtr<MediaController> MediaController::create(ExecutionContext* context)
+PassRefPtrWillBeRawPtr<MediaController> MediaController::create(ExecutionContext* context)
{
- return adoptRef(new MediaController(context));
+ return adoptRefWillBeRefCountedGarbageCollected(new MediaController(context));
}
MediaController::MediaController(ExecutionContext* context)
@@ -51,11 +53,10 @@ MediaController::MediaController(ExecutionContext* context)
, m_volume(1)
, m_position(MediaPlayer::invalidTime())
, m_muted(false)
- , m_readyState(HAVE_NOTHING)
+ , m_readyState(HTMLMediaElement::HAVE_NOTHING)
, m_playbackState(WAITING)
- , m_asyncEventTimer(this, &MediaController::asyncEventTimerFired)
+ , m_pendingEventsQueue(GenericEventQueue::create(this))
, m_clearPositionTimer(this, &MediaController::clearPositionTimerFired)
- , m_closedCaptionsVisible(false)
, m_clock(Clock::create())
, m_executionContext(context)
, m_timeupdateTimer(this, &MediaController::timeupdateTimerFired)
@@ -73,7 +74,7 @@ void MediaController::addMediaElement(HTMLMediaElement* element)
ASSERT(element);
ASSERT(!m_mediaElements.contains(element));
- m_mediaElements.append(element);
+ m_mediaElements.add(element);
bringElementUpToSpeed(element);
}
@@ -84,11 +85,6 @@ void MediaController::removeMediaElement(HTMLMediaElement* element)
m_mediaElements.remove(m_mediaElements.find(element));
}
-bool MediaController::containsMediaElement(HTMLMediaElement* element) const
-{
- return m_mediaElements.contains(element);
-}
-
PassRefPtr<TimeRanges> MediaController::buffered() const
{
if (m_mediaElements.isEmpty())
@@ -97,9 +93,10 @@ PassRefPtr<TimeRanges> MediaController::buffered() const
// The buffered attribute must return a new static normalized TimeRanges object that represents
// the intersection of the ranges of the media resources of the slaved media elements that the
// user agent has buffered, at the time the attribute is evaluated.
- RefPtr<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- bufferedRanges->intersectWith(m_mediaElements[index]->buffered().get());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ RefPtr<TimeRanges> bufferedRanges = (*it)->buffered();
+ for (++it; it != m_mediaElements.end(); ++it)
+ bufferedRanges->intersectWith((*it)->buffered().get());
return bufferedRanges;
}
@@ -111,9 +108,10 @@ PassRefPtr<TimeRanges> MediaController::seekable() const
// The seekable attribute must return a new static normalized TimeRanges object that represents
// the intersection of the ranges of the media resources of the slaved media elements that the
// user agent is able to seek to, at the time the attribute is evaluated.
- RefPtr<TimeRanges> seekableRanges = m_mediaElements.first()->seekable();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- seekableRanges->intersectWith(m_mediaElements[index]->seekable().get());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ RefPtr<TimeRanges> seekableRanges = (*it)->seekable();
+ for (++it; it != m_mediaElements.end(); ++it)
+ seekableRanges->intersectWith((*it)->seekable().get());
return seekableRanges;
}
@@ -125,9 +123,10 @@ PassRefPtr<TimeRanges> MediaController::played()
// The played attribute must return a new static normalized TimeRanges object that represents
// the union of the ranges of the media resources of the slaved media elements that the
// user agent has so far rendered, at the time the attribute is evaluated.
- RefPtr<TimeRanges> playedRanges = m_mediaElements.first()->played();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- playedRanges->unionWith(m_mediaElements[index]->played().get());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ RefPtr<TimeRanges> playedRanges = (*it)->played();
+ for (++it; it != m_mediaElements.end(); ++it)
+ playedRanges->unionWith((*it)->played().get());
return playedRanges;
}
@@ -136,11 +135,11 @@ double MediaController::duration() const
// FIXME: Investigate caching the maximum duration and only updating the cached value
// when the slaved media elements' durations change.
double maxDuration = 0;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- double duration = m_mediaElements[index]->duration();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ double duration = (*it)->duration();
if (std::isnan(duration))
continue;
- maxDuration = max(maxDuration, duration);
+ maxDuration = std::max(maxDuration, duration);
}
return maxDuration;
}
@@ -152,8 +151,8 @@ double MediaController::currentTime() const
if (m_position == MediaPlayer::invalidTime()) {
// Some clocks may return times outside the range of [0..duration].
- m_position = max(0.0, min(duration(), m_clock->currentTime()));
- m_clearPositionTimer.startOneShot(0);
+ m_position = std::max(0.0, std::min(duration(), m_clock->currentTime()));
+ m_clearPositionTimer.startOneShot(0, FROM_HERE);
}
return m_position;
@@ -164,18 +163,19 @@ void MediaController::setCurrentTime(double time, ExceptionState& exceptionState
// When the user agent is to seek the media controller to a particular new playback position,
// it must follow these steps:
// If the new playback position is less than zero, then set it to zero.
- time = max(0.0, time);
+ time = std::max(0.0, time);
// If the new playback position is greater than the media controller duration, then set it
// to the media controller duration.
- time = min(time, duration());
+ time = std::min(time, duration());
// Set the media controller position to the new playback position.
+ m_position = time;
m_clock->setCurrentTime(time);
// Seek each slaved media element to the new playback position relative to the media element timeline.
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->seek(time, exceptionState);
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->seek(time, exceptionState);
scheduleTimeupdateEvent();
}
@@ -198,8 +198,8 @@ void MediaController::play()
{
// When the play() method is invoked, the user agent must invoke the play method of each
// slaved media element in turn,
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->play();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->play();
// and then invoke the unpause method of the MediaController.
unpause();
@@ -246,8 +246,8 @@ void MediaController::setPlaybackRate(double rate)
// playback rate to the new value,
m_clock->setPlayRate(rate);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updatePlaybackRate();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updatePlaybackRate();
// then queue a task to fire a simple event named ratechange at the MediaController.
scheduleEvent(EventTypeNames::ratechange);
@@ -261,7 +261,7 @@ void MediaController::setVolume(double level, ExceptionState& exceptionState)
// If the new value is outside the range 0.0 to 1.0 inclusive, then, on setting, an
// IndexSizeError exception must be raised instead.
if (level < 0 || level > 1) {
- exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("volume", "MediaController", "The value provided (" + String::number(level) + ") is not in the range [0.0, 1.0]."));
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", level, 0.0, ExceptionMessages::InclusiveBound, 1.0, ExceptionMessages::InclusiveBound));
return;
}
@@ -272,8 +272,8 @@ void MediaController::setVolume(double level, ExceptionState& exceptionState)
// and queue a task to fire a simple event named volumechange at the MediaController.
scheduleEvent(EventTypeNames::volumechange);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updateVolume();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updateVolume();
}
void MediaController::setMuted(bool flag)
@@ -288,8 +288,8 @@ void MediaController::setMuted(bool flag)
// and queue a task to fire a simple event named volumechange at the MediaController.
scheduleEvent(EventTypeNames::volumechange);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updateVolume();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updateVolume();
}
static const AtomicString& playbackStateWaiting()
@@ -331,18 +331,18 @@ void MediaController::reportControllerState()
updatePlaybackState();
}
-static AtomicString eventNameForReadyState(MediaControllerInterface::ReadyState state)
+static const AtomicString& eventNameForReadyState(HTMLMediaElement::ReadyState state)
{
switch (state) {
- case MediaControllerInterface::HAVE_NOTHING:
+ case HTMLMediaElement::HAVE_NOTHING:
return EventTypeNames::emptied;
- case MediaControllerInterface::HAVE_METADATA:
+ case HTMLMediaElement::HAVE_METADATA:
return EventTypeNames::loadedmetadata;
- case MediaControllerInterface::HAVE_CURRENT_DATA:
+ case HTMLMediaElement::HAVE_CURRENT_DATA:
return EventTypeNames::loadeddata;
- case MediaControllerInterface::HAVE_FUTURE_DATA:
+ case HTMLMediaElement::HAVE_FUTURE_DATA:
return EventTypeNames::canplay;
- case MediaControllerInterface::HAVE_ENOUGH_DATA:
+ case HTMLMediaElement::HAVE_ENOUGH_DATA:
return EventTypeNames::canplaythrough;
default:
ASSERT_NOT_REACHED();
@@ -357,13 +357,14 @@ void MediaController::updateReadyState()
if (m_mediaElements.isEmpty()) {
// If the MediaController has no slaved media elements, let new readiness state be 0.
- newReadyState = HAVE_NOTHING;
+ newReadyState = HTMLMediaElement::HAVE_NOTHING;
} else {
// Otherwise, let it have the lowest value of the readyState IDL attributes of all of its
// slaved media elements.
- newReadyState = m_mediaElements.first()->readyState();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- newReadyState = min(newReadyState, m_mediaElements[index]->readyState());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ newReadyState = (*it)->readyState();
+ for (++it; it != m_mediaElements.end(); ++it)
+ newReadyState = std::min(newReadyState, (*it)->readyState());
}
if (newReadyState == oldReadyState)
@@ -471,8 +472,8 @@ void MediaController::updatePlaybackState()
void MediaController::updateMediaElements()
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updatePlayState();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updatePlayState();
}
void MediaController::bringElementUpToSpeed(HTMLMediaElement* element)
@@ -486,20 +487,51 @@ void MediaController::bringElementUpToSpeed(HTMLMediaElement* element)
element->seek(currentTime(), IGNORE_EXCEPTION);
}
+bool MediaController::isRestrained() const
+{
+ ASSERT(!m_mediaElements.isEmpty());
+
+ // A MediaController is a restrained media controller if the MediaController is a playing media
+ // controller,
+ if (m_paused)
+ return false;
+
+ bool anyAutoplayingAndPaused = false;
+ bool allPaused = true;
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ HTMLMediaElement* element = *it;
+
+ // and none of its slaved media elements are blocked media elements,
+ if (element->isBlocked())
+ return false;
+
+ if (element->isAutoplaying() && element->paused())
+ anyAutoplayingAndPaused = true;
+
+ if (!element->paused())
+ allPaused = false;
+ }
+
+ // but either at least one of its slaved media elements whose autoplaying flag is true still has
+ // its paused attribute set to true, or, all of its slaved media elements have their paused
+ // attribute set to true.
+ return anyAutoplayingAndPaused || allPaused;
+}
+
bool MediaController::isBlocked() const
{
+ ASSERT(!m_mediaElements.isEmpty());
+
// A MediaController is a blocked media controller if the MediaController is a paused media
// controller,
if (m_paused)
return true;
- if (m_mediaElements.isEmpty())
- return false;
-
bool allPaused = true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- HTMLMediaElement* element = m_mediaElements[index];
- // or if any of its slaved media elements are blocked media elements,
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ HTMLMediaElement* element = *it;
+
+ // or if any of its slaved media elements are blocked media elements,
if (element->isBlocked())
return true;
@@ -528,8 +560,8 @@ bool MediaController::hasEnded() const
return false;
bool allHaveEnded = true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->ended())
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ if (!(*it)->ended())
allHaveEnded = false;
}
return allHaveEnded;
@@ -537,19 +569,7 @@ bool MediaController::hasEnded() const
void MediaController::scheduleEvent(const AtomicString& eventName)
{
- m_pendingEvents.append(Event::createCancelable(eventName));
- if (!m_asyncEventTimer.isActive())
- m_asyncEventTimer.startOneShot(0);
-}
-
-void MediaController::asyncEventTimerFired(Timer<MediaController>*)
-{
- Vector<RefPtr<Event> > pendingEvents;
-
- m_pendingEvents.swap(pendingEvents);
- size_t count = pendingEvents.size();
- for (size_t index = 0; index < count; ++index)
- dispatchEvent(pendingEvents[index].release(), IGNORE_EXCEPTION);
+ m_pendingEventsQueue->enqueueEvent(Event::createCancelable(eventName));
}
void MediaController::clearPositionTimerFired(Timer<MediaController>*)
@@ -557,77 +577,6 @@ void MediaController::clearPositionTimerFired(Timer<MediaController>*)
m_position = MediaPlayer::invalidTime();
}
-bool MediaController::hasAudio() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasAudio())
- return true;
- }
- return false;
-}
-
-bool MediaController::hasVideo() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasVideo())
- return true;
- }
- return false;
-}
-
-bool MediaController::hasClosedCaptions() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasClosedCaptions())
- return true;
- }
- return false;
-}
-
-void MediaController::setClosedCaptionsVisible(bool visible)
-{
- m_closedCaptionsVisible = visible;
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->setClosedCaptionsVisible(visible);
-}
-
-void MediaController::beginScrubbing()
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->beginScrubbing();
- if (m_playbackState == PLAYING)
- m_clock->stop();
-}
-
-void MediaController::endScrubbing()
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->endScrubbing();
- if (m_playbackState == PLAYING)
- m_clock->start();
-}
-
-bool MediaController::canPlay() const
-{
- if (m_paused)
- return true;
-
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->canPlay())
- return false;
- }
- return true;
-}
-
-bool MediaController::hasCurrentSrc() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->hasCurrentSrc())
- return false;
- }
- return true;
-}
-
const AtomicString& MediaController::interfaceName() const
{
return EventTargetNames::MediaController;
@@ -642,7 +591,7 @@ void MediaController::startTimeupdateTimer()
if (m_timeupdateTimer.isActive())
return;
- m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency);
+ m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HERE);
}
void MediaController::timeupdateTimerFired(Timer<MediaController>*)
@@ -661,3 +610,13 @@ void MediaController::scheduleTimeupdateEvent()
scheduleEvent(EventTypeNames::timeupdate);
m_previousTimeupdateTime = now;
}
+
+void MediaController::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaElements);
+ visitor->trace(m_pendingEventsQueue);
+ visitor->trace(m_executionContext);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaController.h b/chromium/third_party/WebKit/Source/core/html/MediaController.h
index 5b31cc24e18..c9311a906d7 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaController.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaController.h
@@ -27,84 +27,68 @@
#define MediaController_h
#include "bindings/v8/ScriptWrappable.h"
-#include "core/events/Event.h"
#include "core/events/EventTarget.h"
-#include "core/html/MediaControllerInterface.h"
-#include "platform/Timer.h"
+#include "core/html/HTMLMediaElement.h"
+#include "wtf/LinkedHashSet.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
namespace WebCore {
class Clock;
-class Event;
class ExceptionState;
-class HTMLMediaElement;
class ExecutionContext;
+class GenericEventQueue;
-class MediaController : public RefCounted<MediaController>, public ScriptWrappable, public MediaControllerInterface, public EventTargetWithInlineData {
+class MediaController FINAL : public RefCountedWillBeRefCountedGarbageCollected<MediaController>, public ScriptWrappable, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(MediaController);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaController);
public:
- static PassRefPtr<MediaController> create(ExecutionContext*);
+ static PassRefPtrWillBeRawPtr<MediaController> create(ExecutionContext*);
virtual ~MediaController();
void addMediaElement(HTMLMediaElement*);
void removeMediaElement(HTMLMediaElement*);
- bool containsMediaElement(HTMLMediaElement*) const;
- const String& mediaGroup() const { return m_mediaGroup; }
+ PassRefPtr<TimeRanges> buffered() const;
+ PassRefPtr<TimeRanges> seekable() const;
+ PassRefPtr<TimeRanges> played();
- virtual PassRefPtr<TimeRanges> buffered() const;
- virtual PassRefPtr<TimeRanges> seekable() const;
- virtual PassRefPtr<TimeRanges> played();
+ double duration() const;
+ double currentTime() const;
+ void setCurrentTime(double, ExceptionState&);
- virtual double duration() const;
- virtual double currentTime() const;
- virtual void setCurrentTime(double, ExceptionState&);
-
- virtual bool paused() const { return m_paused; }
- virtual void play();
- virtual void pause();
+ bool paused() const { return m_paused; }
+ void play();
+ void pause();
void unpause();
- virtual double defaultPlaybackRate() const { return m_defaultPlaybackRate; }
- virtual void setDefaultPlaybackRate(double);
+ double defaultPlaybackRate() const { return m_defaultPlaybackRate; }
+ void setDefaultPlaybackRate(double);
- virtual double playbackRate() const;
- virtual void setPlaybackRate(double);
+ double playbackRate() const;
+ void setPlaybackRate(double);
- virtual double volume() const { return m_volume; }
- virtual void setVolume(double, ExceptionState&);
+ double volume() const { return m_volume; }
+ void setVolume(double, ExceptionState&);
- virtual bool muted() const { return m_muted; }
- virtual void setMuted(bool);
+ bool muted() const { return m_muted; }
+ void setMuted(bool);
- virtual ReadyState readyState() const { return m_readyState; }
+ typedef HTMLMediaElement::ReadyState ReadyState;
+ ReadyState readyState() const { return m_readyState; }
enum PlaybackState { WAITING, PLAYING, ENDED };
const AtomicString& playbackState() const;
- virtual bool supportsFullscreen() const { return false; }
- virtual bool isFullscreen() const { return false; }
- virtual void enterFullscreen() { }
-
- virtual bool hasAudio() const;
- virtual bool hasVideo() const;
- virtual bool hasClosedCaptions() const;
- virtual void setClosedCaptionsVisible(bool);
- virtual bool closedCaptionsVisible() const { return m_closedCaptionsVisible; }
-
- virtual void beginScrubbing();
- virtual void endScrubbing();
-
- virtual bool canPlay() const;
-
- virtual bool hasCurrentSrc() const;
-
+ bool isRestrained() const;
bool isBlocked() const;
- void clearExecutionContext() { m_executionContext = 0; }
+#if !ENABLE(OILPAN)
+ void clearExecutionContext() { m_executionContext = nullptr; }
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
MediaController(ExecutionContext*);
@@ -114,7 +98,6 @@ private:
void updateMediaElements();
void bringElementUpToSpeed(HTMLMediaElement*);
void scheduleEvent(const AtomicString& eventName);
- void asyncEventTimerFired(Timer<MediaController>*);
void clearPositionTimerFired(Timer<MediaController>*);
bool hasEnded() const;
void scheduleTimeupdateEvent();
@@ -127,7 +110,12 @@ private:
friend class HTMLMediaElement;
friend class MediaControllerEventListener;
- Vector<HTMLMediaElement*> m_mediaElements;
+ // FIXME: A MediaController should ideally keep an otherwise
+ // unreferenced slaved media element alive. When Oilpan is
+ // enabled by default, consider making the hash set references
+ // strong to accomplish that. crbug.com/383072
+ typedef WillBeHeapLinkedHashSet<RawPtrWillBeWeakMember<HTMLMediaElement> > MediaElementSequence;
+ MediaElementSequence m_mediaElements;
bool m_paused;
double m_defaultPlaybackRate;
double m_volume;
@@ -135,13 +123,10 @@ private:
bool m_muted;
ReadyState m_readyState;
PlaybackState m_playbackState;
- Vector<RefPtr<Event> > m_pendingEvents;
- Timer<MediaController> m_asyncEventTimer;
+ OwnPtrWillBeMember<GenericEventQueue> m_pendingEventsQueue;
mutable Timer<MediaController> m_clearPositionTimer;
- String m_mediaGroup;
- bool m_closedCaptionsVisible;
OwnPtr<Clock> m_clock;
- ExecutionContext* m_executionContext;
+ RawPtrWillBeWeakMember<ExecutionContext> m_executionContext;
Timer<MediaController> m_timeupdateTimer;
double m_previousTimeupdateTime;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaController.idl b/chromium/third_party/WebKit/Source/core/html/MediaController.idl
index ad46115d889..8e70a8b0531 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaController.idl
+++ b/chromium/third_party/WebKit/Source/core/html/MediaController.idl
@@ -23,15 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#mediacontroller
+
[
Constructor,
ConstructorCallWith=ExecutionContext,
- RuntimeEnabled=Media,
+ RuntimeEnabled=MediaController,
+ TypeChecking=Unrestricted,
] interface MediaController : EventTarget {
readonly attribute TimeRanges buffered;
readonly attribute TimeRanges seekable;
- readonly attribute double duration;
+ readonly attribute unrestricted double duration;
[RaisesException=Setter] attribute double currentTime;
readonly attribute boolean paused;
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h b/chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h
deleted file mode 100644
index 9f8f7042f39..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED 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 MediaControllerInterface_h
-#define MediaControllerInterface_h
-
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class ExceptionState;
-class TimeRanges;
-
-class MediaControllerInterface {
-public:
- virtual ~MediaControllerInterface() { };
-
- // MediaController IDL:
- virtual PassRefPtr<TimeRanges> buffered() const = 0;
- virtual PassRefPtr<TimeRanges> seekable() const = 0;
- virtual PassRefPtr<TimeRanges> played() = 0;
-
- virtual double duration() const = 0;
- virtual double currentTime() const = 0;
- virtual void setCurrentTime(double, ExceptionState&) = 0;
-
- virtual bool paused() const = 0;
- virtual void play() = 0;
- virtual void pause() = 0;
-
- virtual double defaultPlaybackRate() const = 0;
- virtual void setDefaultPlaybackRate(double) = 0;
-
- virtual double playbackRate() const = 0;
- virtual void setPlaybackRate(double) = 0;
-
- virtual double volume() const = 0;
- virtual void setVolume(double, ExceptionState&) = 0;
-
- virtual bool muted() const = 0;
- virtual void setMuted(bool) = 0;
-
- enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
- virtual ReadyState readyState() const = 0;
-
- // MediaControlElements:
- virtual bool supportsFullscreen() const = 0;
- virtual bool isFullscreen() const = 0;
- virtual void enterFullscreen() = 0;
-
- virtual bool hasAudio() const = 0;
- virtual bool hasVideo() const = 0;
- virtual bool hasClosedCaptions() const = 0;
- virtual void setClosedCaptionsVisible(bool) = 0;
- virtual bool closedCaptionsVisible() const = 0;
-
- virtual void beginScrubbing() = 0;
- virtual void endScrubbing() = 0;
-
- virtual bool canPlay() const = 0;
-
- virtual bool hasCurrentSrc() const = 0;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp b/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp
index ef6207470d6..1a9235d6546 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp
@@ -27,12 +27,12 @@
#include "core/html/MediaDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/RawDataDocumentParser.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLHtmlElement.h"
@@ -41,7 +41,6 @@
#include "core/html/HTMLVideoElement.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "platform/KeyboardCodes.h"
namespace WebCore {
@@ -51,9 +50,9 @@ using namespace HTMLNames;
// FIXME: Share more code with PluginDocumentParser.
class MediaDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<MediaDocumentParser> create(MediaDocument* document)
+ static PassRefPtrWillBeRawPtr<MediaDocumentParser> create(MediaDocument* document)
{
- return adoptRef(new MediaDocumentParser(document));
+ return adoptRefWillBeNoop(new MediaDocumentParser(document));
}
private:
@@ -73,25 +72,25 @@ private:
void MediaDocumentParser::createDocumentStructure()
{
ASSERT(document());
- RefPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
rootElement->insertedByParser();
document()->appendChild(rootElement);
if (document()->frame())
document()->frame()->loader().dispatchDocumentElementAvailable();
- RefPtr<HTMLHeadElement> head = HTMLHeadElement::create(*document());
- RefPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*document());
meta->setAttribute(nameAttr, "viewport");
meta->setAttribute(contentAttr, "width=device-width");
head->appendChild(meta.release());
- RefPtr<HTMLVideoElement> media = HTMLVideoElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLVideoElement> media = HTMLVideoElement::create(*document());
media->setAttribute(controlsAttr, "");
media->setAttribute(autoplayAttr, "");
media->setAttribute(nameAttr, "media");
- RefPtr<HTMLSourceElement> source = HTMLSourceElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLSourceElement> source = HTMLSourceElement::create(*document());
source->setSrc(document()->url());
if (DocumentLoader* loader = document()->loader())
@@ -99,7 +98,7 @@ void MediaDocumentParser::createDocumentStructure()
media->appendChild(source.release());
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
body->appendChild(media.release());
rootElement->appendChild(head.release());
@@ -124,23 +123,11 @@ MediaDocument::MediaDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> MediaDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> MediaDocument::createParser()
{
return MediaDocumentParser::create(this);
}
-static inline HTMLVideoElement* descendentVideoElement(Node* root)
-{
- ASSERT(root);
-
- for (Node* node = root; node; node = NodeTraversal::next(*node, root)) {
- if (isHTMLVideoElement(node))
- return toHTMLVideoElement(node);
- }
-
- return 0;
-}
-
void MediaDocument::defaultEventHandler(Event* event)
{
Node* targetNode = event->target()->toNode();
@@ -148,18 +135,14 @@ void MediaDocument::defaultEventHandler(Event* event)
return;
if (event->type() == EventTypeNames::keydown && event->isKeyboardEvent()) {
- HTMLVideoElement* video = descendentVideoElement(targetNode);
+ HTMLVideoElement* video = Traversal<HTMLVideoElement>::firstWithin(*targetNode);
if (!video)
return;
KeyboardEvent* keyboardEvent = toKeyboardEvent(event);
if (keyboardEvent->keyIdentifier() == "U+0020" || keyboardEvent->keyCode() == VKEY_MEDIA_PLAY_PAUSE) {
// space or media key (play/pause)
- if (video->paused()) {
- if (video->canPlay())
- video->play();
- } else
- video->pause();
+ video->togglePlayState();
event->setDefaultHandled();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaDocument.h b/chromium/third_party/WebKit/Source/core/html/MediaDocument.h
index b5d264ec976..a2b55c5c385 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaDocument.h
@@ -32,15 +32,15 @@ namespace WebCore {
class MediaDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<MediaDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<MediaDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new MediaDocument(initializer));
+ return adoptRefWillBeNoop(new MediaDocument(initializer));
}
private:
MediaDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaError.h b/chromium/third_party/WebKit/Source/core/html/MediaError.h
index 86ace1108bf..0169c759713 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaError.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaError.h
@@ -32,7 +32,7 @@
namespace WebCore {
-class MediaError : public RefCounted<MediaError>, public ScriptWrappable {
+class MediaError FINAL : public RefCountedWillBeGarbageCollectedFinalized<MediaError>, public ScriptWrappable {
public:
enum Code {
MEDIA_ERR_ABORTED = 1,
@@ -42,10 +42,15 @@ public:
MEDIA_ERR_ENCRYPTED
};
- static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
+ static PassRefPtrWillBeRawPtr<MediaError> create(Code code)
+ {
+ return adoptRefWillBeNoop(new MediaError(code));
+ }
Code code() const { return m_code; }
+ void trace(Visitor*) { }
+
private:
MediaError(Code code) : m_code(code)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaError.idl b/chromium/third_party/WebKit/Source/core/html/MediaError.idl
index 4cf13edcef5..aaffbc230d9 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaError.idl
+++ b/chromium/third_party/WebKit/Source/core/html/MediaError.idl
@@ -24,12 +24,13 @@
*/
[
- RuntimeEnabled=Media
+ RuntimeEnabled=Media,
+ WillBeGarbageCollected,
] interface 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;
- [RuntimeEnabled=EncryptedMediaAnyVersion] const unsigned short MEDIA_ERR_ENCRYPTED = 5;
+ [RuntimeEnabled=EncryptedMediaAnyVersion, DeprecateAs=MediaErrorEncrypted] const unsigned short MEDIA_ERR_ENCRYPTED = 5;
readonly attribute unsigned short code;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp b/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp
index f887a05f163..70cd27fe98f 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp
@@ -134,11 +134,11 @@ void MediaFragmentURIParser::parseFragments()
// name or value are not valid UTF-8 strings, then remove the name-value pair from the list.
bool validUTF8 = true;
if (!name.isEmpty()) {
- name = name.utf8(String::StrictConversion).data();
+ name = name.utf8(StrictUTF8Conversion).data();
validUTF8 = !name.isEmpty();
}
if (validUTF8 && !value.isEmpty()) {
- value = value.utf8(String::StrictConversion).data();
+ value = value.utf8(StrictUTF8Conversion).data();
validUTF8 = !value.isEmpty();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp
index 38f02b701bd..270236ec6c0 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/html/MediaKeyEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "wtf/Uint8Array.h"
namespace WebCore {
@@ -63,4 +62,9 @@ const AtomicString& MediaKeyEvent::interfaceName() const
return EventNames::MediaKeyEvent;
}
+void MediaKeyEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h
index 370abafce6b..cf95046f657 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h
@@ -43,21 +43,21 @@ struct MediaKeyEventInit : public EventInit {
unsigned short systemCode;
};
-class MediaKeyEvent : public Event {
+class MediaKeyEvent FINAL : public Event {
public:
virtual ~MediaKeyEvent();
- static PassRefPtr<MediaKeyEvent> create()
+ static PassRefPtrWillBeRawPtr<MediaKeyEvent> create()
{
- return adoptRef(new MediaKeyEvent);
+ return adoptRefWillBeNoop(new MediaKeyEvent);
}
- static PassRefPtr<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
{
- return adoptRef(new MediaKeyEvent(type, initializer));
+ return adoptRefWillBeNoop(new MediaKeyEvent(type, initializer));
}
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
String keySystem() const { return m_keySystem; }
String sessionId() const { return m_sessionId; }
@@ -68,6 +68,8 @@ public:
MediaKeyError* errorCode(bool& isNull) const { isNull = !m_errorCode; return m_errorCode.get(); }
unsigned short systemCode() const { return m_systemCode; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
MediaKeyEvent();
MediaKeyEvent(const AtomicString& type, const MediaKeyEventInit& initializer);
diff --git a/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp b/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp
index 366ee643ba3..15e112713f0 100644
--- a/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp
@@ -25,17 +25,17 @@
#include "config.h"
#include "core/html/PluginDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/RawDataDocumentParser.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLEmbedElement.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/plugins/PluginView.h"
#include "core/rendering/RenderEmbeddedObject.h"
@@ -46,15 +46,21 @@ using namespace HTMLNames;
// FIXME: Share more code with MediaDocumentParser.
class PluginDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<PluginDocumentParser> create(PluginDocument* document)
+ static PassRefPtrWillBeRawPtr<PluginDocumentParser> create(PluginDocument* document)
{
- return adoptRef(new PluginDocumentParser(document));
+ return adoptRefWillBeNoop(new PluginDocumentParser(document));
+ }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_embedElement);
+ RawDataDocumentParser::trace(visitor);
}
private:
PluginDocumentParser(Document* document)
: RawDataDocumentParser(document)
- , m_embedElement(0)
+ , m_embedElement(nullptr)
{
}
@@ -66,7 +72,7 @@ private:
PluginView* pluginView() const;
- RefPtr<HTMLEmbedElement> m_embedElement;
+ RefPtrWillBeMember<HTMLEmbedElement> m_embedElement;
};
void PluginDocumentParser::createDocumentStructure()
@@ -76,7 +82,7 @@ void PluginDocumentParser::createDocumentStructure()
ASSERT(document());
RELEASE_ASSERT(document()->loader());
- Frame* frame = document()->frame();
+ LocalFrame* frame = document()->frame();
if (!frame)
return;
@@ -84,12 +90,12 @@ void PluginDocumentParser::createDocumentStructure()
if (!frame->settings() || !frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
return;
- RefPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
rootElement->insertedByParser();
document()->appendChild(rootElement);
frame->loader().dispatchDocumentElementAvailable();
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
body->setAttribute(marginwidthAttr, "0");
body->setAttribute(marginheightAttr, "0");
body->setAttribute(styleAttr, "background-color: rgb(38,38,38)");
@@ -134,7 +140,7 @@ void PluginDocumentParser::finish()
view->didFinishLoading();
else
view->didFailLoading(error);
- m_embedElement = 0;
+ m_embedElement = nullptr;
}
RawDataDocumentParser::finish();
}
@@ -156,7 +162,7 @@ PluginDocument::PluginDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> PluginDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> PluginDocument::createParser()
{
return PluginDocumentParser::create(this);
}
@@ -178,20 +184,14 @@ Node* PluginDocument::pluginNode()
void PluginDocument::detach(const AttachContext& context)
{
// Release the plugin node so that we don't have a circular reference.
- m_pluginNode = 0;
+ m_pluginNode = nullptr;
HTMLDocument::detach(context);
}
-void PluginDocument::cancelManualPluginLoad()
+void PluginDocument::trace(Visitor* visitor)
{
- // 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;
-
- DocumentLoader* documentLoader = frame()->loader().activeDocumentLoader();
- documentLoader->cancelMainResourceLoad(ResourceError::cancelledError(documentLoader->request().url()));
- setShouldLoadPluginManually(false);
+ visitor->trace(m_pluginNode);
+ HTMLDocument::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/PluginDocument.h b/chromium/third_party/WebKit/Source/core/html/PluginDocument.h
index 590cb30303f..021e5c100ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/PluginDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/PluginDocument.h
@@ -34,9 +34,9 @@ class Widget;
class PluginDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<PluginDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<PluginDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new PluginDocument(initializer));
+ return adoptRefWillBeNoop(new PluginDocument(initializer));
}
void setPluginNode(Node* pluginNode) { m_pluginNode = pluginNode; }
@@ -46,19 +46,19 @@ public:
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- void cancelManualPluginLoad();
-
bool shouldLoadPluginManually() { return m_shouldLoadPluginManually; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- PluginDocument(const DocumentInit&);
+ explicit PluginDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
void setShouldLoadPluginManually(bool loadManually) { m_shouldLoadPluginManually = loadManually; }
bool m_shouldLoadPluginManually;
- RefPtr<Node> m_pluginNode;
+ RefPtrWillBeMember<Node> m_pluginNode;
};
DEFINE_DOCUMENT_TYPE_CASTS(PluginDocument);
diff --git a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp
index 09157de9df7..f084b7cae8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp
@@ -27,8 +27,10 @@
#include "config.h"
#include "core/html/PublicURLManager.h"
+#include "core/fetch/MemoryCache.h"
#include "core/html/URLRegistry.h"
#include "platform/weborigin/KURL.h"
+#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"
namespace WebCore {
@@ -46,14 +48,14 @@ PublicURLManager::PublicURLManager(ExecutionContext* context)
{
}
-void PublicURLManager::registerURL(SecurityOrigin* origin, const KURL& url, URLRegistrable* registrable)
+void PublicURLManager::registerURL(SecurityOrigin* origin, const KURL& url, URLRegistrable* registrable, const String& uuid)
{
if (m_isStopped)
return;
- RegistryURLMap::iterator found = m_registryToURL.add(&registrable->registry(), URLSet()).iterator;
+ RegistryURLMap::ValueType* found = m_registryToURL.add(&registrable->registry(), URLMap()).storedValue;
found->key->registerURL(origin, url, registrable);
- found->value.add(url.string());
+ found->value.add(url.string(), uuid);
}
void PublicURLManager::revoke(const KURL& url)
@@ -67,6 +69,27 @@ void PublicURLManager::revoke(const KURL& url)
}
}
+void PublicURLManager::revoke(const String& uuid)
+{
+ // A linear scan; revoking by UUID is assumed rare.
+ Vector<String> urlsToRemove;
+ for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
+ URLRegistry* registry = i->key;
+ URLMap& registeredURLs = i->value;
+ for (URLMap::iterator j = registeredURLs.begin(); j != registeredURLs.end(); ++j) {
+ if (uuid == j->value) {
+ KURL url(ParsedURLString, j->key);
+ MemoryCache::removeURLFromCache(executionContext(), url);
+ registry->unregisterURL(url);
+ urlsToRemove.append(j->key);
+ }
+ }
+ for (unsigned j = 0; j < urlsToRemove.size(); j++)
+ registeredURLs.remove(urlsToRemove[j]);
+ urlsToRemove.clear();
+ }
+}
+
void PublicURLManager::stop()
{
if (m_isStopped)
@@ -74,8 +97,8 @@ void PublicURLManager::stop()
m_isStopped = true;
for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
- for (URLSet::iterator j = i->value.begin(); j != i->value.end(); ++j)
- i->key->unregisterURL(KURL(ParsedURLString, *j));
+ for (URLMap::iterator j = i->value.begin(); j != i->value.end(); ++j)
+ i->key->unregisterURL(KURL(ParsedURLString, j->key));
}
m_registryToURL.clear();
diff --git a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h
index 08848772701..094d42b4204 100644
--- a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h
+++ b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h
@@ -40,13 +40,14 @@ class SecurityOrigin;
class URLRegistry;
class URLRegistrable;
-class PublicURLManager : public ActiveDOMObject {
+class PublicURLManager FINAL : public ActiveDOMObject {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassOwnPtr<PublicURLManager> create(ExecutionContext*);
- void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*);
+ void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*, const String& uuid = String());
void revoke(const KURL&);
+ void revoke(const String& uuid);
// ActiveDOMObject interface.
virtual void stop() OVERRIDE;
@@ -54,12 +55,16 @@ public:
private:
PublicURLManager(ExecutionContext*);
- typedef HashSet<String> URLSet;
- typedef HashMap<URLRegistry*, URLSet > RegistryURLMap;
+ // One or more URLs can be associated with the same unique ID.
+ // Objects need be revoked by unique ID in some cases.
+ typedef String URLString;
+ typedef HashMap<URLString, String> URLMap;
+ typedef HashMap<URLRegistry*, URLMap> RegistryURLMap;
+
RegistryURLMap m_registryToURL;
bool m_isStopped;
};
} // namespace WebCore
-#endif // PUBLICURLMANAGER_h
+#endif // PublicURLManager_h
diff --git a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp
index f7cbfa982a2..423badc97c1 100644
--- a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/RadioNodeList.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/dom/NodeRareData.h"
#include "core/html/HTMLFormElement.h"
@@ -37,34 +37,38 @@ namespace WebCore {
using namespace HTMLNames;
-RadioNodeList::RadioNodeList(Node* rootNode, const AtomicString& name)
- : LiveNodeList(rootNode, RadioNodeListType, InvalidateForFormControls, rootNode->hasTagName(formTag) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
+RadioNodeList::RadioNodeList(ContainerNode& rootNode, const AtomicString& name, CollectionType type)
+ : LiveNodeList(rootNode, type, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
, m_name(name)
+ , m_onlyMatchImgElements(type == RadioImgNodeListType)
{
ScriptWrappable::init(this);
}
RadioNodeList::~RadioNodeList()
{
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, RadioNodeListType, m_name);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, m_onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType, m_name);
+#endif
}
-static inline HTMLInputElement* toRadioButtonInputElement(Node* node)
+static inline HTMLInputElement* toRadioButtonInputElement(Element& element)
{
- ASSERT(node->isElementNode());
- if (!node->hasTagName(inputTag))
+ if (!isHTMLInputElement(element))
return 0;
- HTMLInputElement* inputElement = toHTMLInputElement(node);
- if (!inputElement->isRadioButton() || inputElement->value().isEmpty())
+ HTMLInputElement& inputElement = toHTMLInputElement(element);
+ if (!inputElement.isRadioButton() || inputElement.value().isEmpty())
return 0;
- return inputElement;
+ return &inputElement;
}
String RadioNodeList::value() const
{
- for (unsigned i = 0; i < length(); ++i) {
- Node* node = item(i);
- const HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+ if (m_onlyMatchImgElements)
+ return String();
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ const HTMLInputElement* inputElement = toRadioButtonInputElement(*item(i));
if (!inputElement || !inputElement->checked())
continue;
return inputElement->value();
@@ -74,9 +78,11 @@ String RadioNodeList::value() const
void RadioNodeList::setValue(const String& value)
{
- for (unsigned i = 0; i < length(); ++i) {
- Node* node = item(i);
- HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+ if (m_onlyMatchImgElements)
+ return;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ HTMLInputElement* inputElement = toRadioButtonInputElement(*item(i));
if (!inputElement || inputElement->value() != value)
continue;
inputElement->setChecked(true);
@@ -84,28 +90,43 @@ void RadioNodeList::setValue(const String& value)
}
}
-bool RadioNodeList::checkElementMatchesRadioNodeListFilter(Element* testElement) const
+bool RadioNodeList::matchesByIdOrName(const Element& testElement) const
+{
+ return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
+}
+
+bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
{
- ASSERT(testElement->hasTagName(objectTag) || testElement->isFormControlElement());
- if (ownerNode()->hasTagName(formTag)) {
- HTMLFormElement* formElement = toHTMLElement(testElement)->formOwner();
+ ASSERT(!m_onlyMatchImgElements);
+ ASSERT(isHTMLObjectElement(testElement) || testElement.isFormControlElement());
+ if (isHTMLFormElement(ownerNode())) {
+ HTMLFormElement* formElement = toHTMLElement(testElement).formOwner();
if (!formElement || formElement != ownerNode())
return false;
}
- return testElement->getIdAttribute() == m_name || testElement->getNameAttribute() == m_name;
+ return matchesByIdOrName(testElement);
}
-bool RadioNodeList::nodeMatches(Element* testElement) const
+bool RadioNodeList::elementMatches(const Element& element) const
{
- if (!testElement->hasTagName(objectTag) && !testElement->isFormControlElement())
+ if (m_onlyMatchImgElements) {
+ if (!isHTMLImageElement(element))
+ return false;
+
+ if (toHTMLElement(element).formOwner() != ownerNode())
+ return false;
+
+ return matchesByIdOrName(element);
+ }
+
+ if (!isHTMLObjectElement(element) && !element.isFormControlElement())
return false;
- if (testElement->hasTagName(inputTag) && toHTMLInputElement(testElement)->isImageButton())
+ if (isHTMLInputElement(element) && toHTMLInputElement(element).isImageButton())
return false;
- return checkElementMatchesRadioNodeListFilter(testElement);
+ return checkElementMatchesRadioNodeListFilter(element);
}
-} // namspace
-
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h
index b735b0c3377..5dbd7b6ce6b 100644
--- a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h
@@ -34,10 +34,10 @@ namespace WebCore {
class RadioNodeList FINAL : public LiveNodeList {
public:
- static PassRefPtr<RadioNodeList> create(Node* ownerNode, CollectionType type, const AtomicString& name)
+ static PassRefPtrWillBeRawPtr<RadioNodeList> create(ContainerNode& ownerNode, CollectionType type, const AtomicString& name)
{
- ASSERT_UNUSED(type, type == RadioNodeListType);
- return adoptRef(new RadioNodeList(ownerNode, name));
+ ASSERT_UNUSED(type, type == RadioNodeListType || type == RadioImgNodeListType);
+ return adoptRefWillBeNoop(new RadioNodeList(ownerNode, name, type));
}
virtual ~RadioNodeList();
@@ -46,15 +46,18 @@ public:
void setValue(const String&);
private:
- RadioNodeList(Node*, const AtomicString& name);
- bool checkElementMatchesRadioNodeListFilter(Element*) const;
+ RadioNodeList(ContainerNode&, const AtomicString& name, CollectionType);
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ bool checkElementMatchesRadioNodeListFilter(const Element&) const;
+
+ bool matchesByIdOrName(const Element&) const;
+
+ virtual bool elementMatches(const Element&) const OVERRIDE;
AtomicString m_name;
+ const bool m_onlyMatchImgElements;
};
-} // namepsace
+} // namespace
#endif
-
diff --git a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl
index 47beea06be2..057ad06c0ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl
@@ -24,8 +24,8 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
] interface RadioNodeList : NodeList {
attribute DOMString value;
- [ImplementedAs=item] getter Node(unsigned long index);
+ [ImplementedAs=item] getter Node (unsigned long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp b/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp
index acff1d92f70..742339679db 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp
@@ -36,9 +36,9 @@ TextDocument::TextDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> TextDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> TextDocument::createParser()
{
- return TextDocumentParser::create(this);
+ return TextDocumentParser::create(*this);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/TextDocument.h b/chromium/third_party/WebKit/Source/core/html/TextDocument.h
index a36617db0bf..a7961f6fc8c 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/TextDocument.h
@@ -31,15 +31,15 @@ namespace WebCore {
class TextDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<TextDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<TextDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new TextDocument(initializer));
+ return adoptRefWillBeNoop(new TextDocument(initializer));
}
private:
TextDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser();
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/TextMetrics.h b/chromium/third_party/WebKit/Source/core/html/TextMetrics.h
index 9925831e009..f936067b7e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextMetrics.h
+++ b/chromium/third_party/WebKit/Source/core/html/TextMetrics.h
@@ -39,14 +39,72 @@ public:
float width() const { return m_width; }
void setWidth(float w) { m_width = w; }
+ float actualBoundingBoxLeft() const { return m_actualBoundingBoxLeft; }
+ void setActualBoundingBoxLeft(float actualBoundingBoxLeft) { m_actualBoundingBoxLeft = actualBoundingBoxLeft; }
+
+ float actualBoundingBoxRight() const { return m_actualBoundingBoxRight; }
+ void setActualBoundingBoxRight(float actualBoundingBoxRight) { m_actualBoundingBoxRight = actualBoundingBoxRight; }
+
+ float fontBoundingBoxAscent() const { return m_fontBoundingBoxAscent; }
+ void setFontBoundingBoxAscent(float fontBoundingBoxAscent) { m_fontBoundingBoxAscent = fontBoundingBoxAscent; }
+
+ float fontBoundingBoxDescent() const { return m_fontBoundingBoxDescent; }
+ void setFontBoundingBoxDescent(float fontBoundingBoxDescent) { m_fontBoundingBoxDescent = fontBoundingBoxDescent; }
+
+ float actualBoundingBoxAscent() const { return m_actualBoundingBoxAscent; }
+ void setActualBoundingBoxAscent(float actualBoundingBoxAscent) { m_actualBoundingBoxAscent = actualBoundingBoxAscent; }
+
+ float actualBoundingBoxDescent() const { return m_actualBoundingBoxDescent; }
+ void setActualBoundingBoxDescent(float actualBoundingBoxDescent) { m_actualBoundingBoxDescent = actualBoundingBoxDescent; }
+
+ float emHeightAscent() const { return m_emHeightAscent; }
+ void setEmHeightAscent(float emHeightAscent) { m_emHeightAscent = emHeightAscent; }
+
+ float emHeightDescent() const { return m_emHeightDescent; }
+ void setEmHeightDescent(float emHeightDescent) { m_emHeightDescent = emHeightDescent; }
+
+ float hangingBaseline() const { return m_hangingBaseline; }
+ void setHangingBaseline(float hangingBaseline) { m_hangingBaseline = hangingBaseline; }
+
+ float alphabeticBaseline() const { return m_alphabeticBaseline; }
+ void setAlphabeticBaseline(float alphabeticBaseline) { m_alphabeticBaseline = alphabeticBaseline; }
+
+ float ideographicBaseline() const { return m_ideographicBaseline; }
+ void setIdeographicBaseline(float ideographicBaseline) { m_ideographicBaseline = ideographicBaseline; }
+
private:
TextMetrics()
: m_width(0)
+ , m_actualBoundingBoxLeft(0)
+ , m_actualBoundingBoxRight(0)
+ , m_fontBoundingBoxAscent(0)
+ , m_fontBoundingBoxDescent(0)
+ , m_actualBoundingBoxAscent(0)
+ , m_actualBoundingBoxDescent(0)
+ , m_emHeightAscent(0)
+ , m_emHeightDescent(0)
+ , m_hangingBaseline(0)
+ , m_alphabeticBaseline(0)
+ , m_ideographicBaseline(0)
{
ScriptWrappable::init(this);
}
+ // x-direction
float m_width;
+ float m_actualBoundingBoxLeft;
+ float m_actualBoundingBoxRight;
+
+ // y-direction
+ float m_fontBoundingBoxAscent;
+ float m_fontBoundingBoxDescent;
+ float m_actualBoundingBoxAscent;
+ float m_actualBoundingBoxDescent;
+ float m_emHeightAscent;
+ float m_emHeightDescent;
+ float m_hangingBaseline;
+ float m_alphabeticBaseline;
+ float m_ideographicBaseline;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl b/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl
index fc37998bda6..14f11483dd2 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl
+++ b/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl
@@ -24,6 +24,20 @@
*/
[
] interface TextMetrics {
+ // x-direction
readonly attribute float width;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxLeft;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxRight;
+
+ // y-direction
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxAscent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxDescent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxAscent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxDescent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightAscent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightDescent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float hangingBaseline;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float alphabeticBaseline;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float ideographicBaseline;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp b/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp
index 407ff32353b..c8fa279edad 100644
--- a/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp
@@ -26,13 +26,13 @@
#include "config.h"
#include "core/html/TimeRanges.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
#include <math.h>
using namespace WebCore;
-using namespace std;
TimeRanges::TimeRanges(double start, double end)
{
@@ -116,7 +116,7 @@ void TimeRanges::unionWith(const TimeRanges* other)
double TimeRanges::start(unsigned index, ExceptionState& exceptionState) const
{
if (index >= length()) {
- exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, length()));
return 0;
}
return m_ranges[index].m_start;
@@ -125,7 +125,7 @@ double TimeRanges::start(unsigned index, ExceptionState& exceptionState) const
double TimeRanges::end(unsigned index, ExceptionState& exceptionState) const
{
if (index >= length()) {
- exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, length()));
return 0;
}
return m_ranges[index].m_end;
@@ -134,7 +134,7 @@ double TimeRanges::end(unsigned index, ExceptionState& exceptionState) const
void TimeRanges::add(double start, double end)
{
ASSERT(start <= end);
- unsigned int overlappingArcIndex;
+ unsigned overlappingArcIndex;
Range addedRange(start, end);
// For each present range check if we need to:
@@ -193,9 +193,9 @@ double TimeRanges::nearest(double time) const
if (time >= startTime && time <= endTime)
return time;
if (fabs(startTime - time) < closest)
- closest = fabsf(startTime - time);
+ closest = fabs(startTime - time);
else if (fabs(endTime - time) < closest)
- closest = fabsf(endTime - time);
+ closest = fabs(endTime - time);
}
return closest;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/URLRegistry.h b/chromium/third_party/WebKit/Source/core/html/URLRegistry.h
index 660acb92852..f6f2c3bcbf0 100644
--- a/chromium/third_party/WebKit/Source/core/html/URLRegistry.h
+++ b/chromium/third_party/WebKit/Source/core/html/URLRegistry.h
@@ -52,8 +52,9 @@ public:
virtual void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*) = 0;
virtual void unregisterURL(const KURL&) = 0;
- // This is an optional API
+ // These are optional APIs
virtual URLRegistrable* lookup(const String&) { ASSERT_NOT_REACHED(); return 0; }
+ virtual bool contains(const String&) { ASSERT_NOT_REACHED(); return false; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ValidityState.h b/chromium/third_party/WebKit/Source/core/html/ValidityState.h
index 44d05b8cc8c..829cc4e97a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/ValidityState.h
+++ b/chromium/third_party/WebKit/Source/core/html/ValidityState.h
@@ -30,16 +30,20 @@
namespace WebCore {
-class ValidityState : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(ValidityState); WTF_MAKE_FAST_ALLOCATED;
+class ValidityState : public NoBaseWillBeGarbageCollectedFinalized<ValidityState>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(ValidityState);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ValidityState> create(FormAssociatedElement* control)
+ static PassOwnPtrWillBeRawPtr<ValidityState> create(FormAssociatedElement* control)
{
- return adoptPtr(new ValidityState(control));
+ return adoptPtrWillBeNoop(new ValidityState(control));
}
+ void trace(Visitor* visitor) { visitor->trace(m_control); }
+#if !ENABLE(OILPAN)
void ref() { m_control->ref(); }
void deref() { m_control->deref(); }
+#endif
String validationMessage() const;
@@ -57,12 +61,12 @@ public:
bool valid() const;
private:
- ValidityState(FormAssociatedElement* control) : m_control(control)
+ explicit ValidityState(FormAssociatedElement* control) : m_control(control)
{
ScriptWrappable::init(this);
}
- FormAssociatedElement* m_control;
+ RawPtrWillBeMember<FormAssociatedElement> m_control;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ValidityState.idl b/chromium/third_party/WebKit/Source/core/html/ValidityState.idl
index 582baf9a4a3..d4f72538d3a 100644
--- a/chromium/third_party/WebKit/Source/core/html/ValidityState.idl
+++ b/chromium/third_party/WebKit/Source/core/html/ValidityState.idl
@@ -21,6 +21,7 @@
*/
[
+ WillBeGarbageCollected
] interface ValidityState {
readonly attribute boolean valueMissing;
readonly attribute boolean typeMismatch;
diff --git a/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp
new file mode 100644
index 00000000000..7321f853f29
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/WindowNameCollection.h"
+
+#include "core/html/HTMLImageElement.h"
+
+namespace WebCore {
+
+WindowNameCollection::WindowNameCollection(ContainerNode& document, const AtomicString& name)
+ : HTMLNameCollection(document, WindowNamedItems, name)
+{
+}
+
+bool WindowNameCollection::elementMatches(const Element& element) const
+{
+ // Match only images, forms, applets, embeds and objects by name,
+ // but anything by id
+ if (isHTMLImageElement(element)
+ || isHTMLFormElement(element)
+ || isHTMLAppletElement(element)
+ || isHTMLEmbedElement(element)
+ || isHTMLObjectElement(element)) {
+ if (element.getNameAttribute() == m_name)
+ return true;
+ }
+ return element.getIdAttribute() == m_name;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h
new file mode 100644
index 00000000000..fc9408707c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WindowNameCollection_h
+#define WindowNameCollection_h
+
+#include "core/html/HTMLNameCollection.h"
+
+namespace WebCore {
+
+class WindowNameCollection FINAL : public HTMLNameCollection {
+public:
+ static PassRefPtrWillBeRawPtr<WindowNameCollection> create(ContainerNode& document, CollectionType type, const AtomicString& name)
+ {
+ ASSERT_UNUSED(type, type == WindowNamedItems);
+ return adoptRefWillBeNoop(new WindowNameCollection(document, name));
+ }
+
+ bool elementMatches(const Element&) const;
+
+private:
+ WindowNameCollection(ContainerNode& document, const AtomicString& name);
+};
+
+DEFINE_TYPE_CASTS(WindowNameCollection, LiveNodeListBase, collection, collection->type() == WindowNamedItems, collection.type() == WindowNamedItems);
+
+} // namespace WebCore
+
+#endif // WindowNameCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp
index c7e5c9301b6..bc7f5932d0f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp
@@ -32,36 +32,34 @@
#include "core/html/canvas/ANGLEInstancedArrays.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContext* context)
+ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_ANGLE_instanced_arrays");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_ANGLE_instanced_arrays");
}
ANGLEInstancedArrays::~ANGLEInstancedArrays()
{
}
-WebGLExtension::ExtensionName ANGLEInstancedArrays::name() const
+WebGLExtensionName ANGLEInstancedArrays::name() const
{
return ANGLEInstancedArraysName;
}
-PassRefPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContext* context)
+PassRefPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContextBase* context)
{
return adoptRef(new ANGLEInstancedArrays(context));
}
-bool ANGLEInstancedArrays::supported(WebGLRenderingContext* context)
+bool ANGLEInstancedArrays::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_ANGLE_instanced_arrays");
+ return context->extensionsUtil()->supportsExtension("GL_ANGLE_instanced_arrays");
}
const char* ANGLEInstancedArrays::extensionName()
@@ -69,7 +67,7 @@ const char* ANGLEInstancedArrays::extensionName()
return "ANGLE_instanced_arrays";
}
-void ANGLEInstancedArrays::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+void ANGLEInstancedArrays::drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
if (isLost())
return;
@@ -77,7 +75,7 @@ void ANGLEInstancedArrays::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first
m_context->drawArraysInstancedANGLE(mode, first, count, primcount);
}
-void ANGLEInstancedArrays::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
+void ANGLEInstancedArrays::drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount)
{
if (isLost())
return;
@@ -85,7 +83,7 @@ void ANGLEInstancedArrays::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei c
m_context->drawElementsInstancedANGLE(mode, count, type, offset, primcount);
}
-void ANGLEInstancedArrays::vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor)
+void ANGLEInstancedArrays::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
if (isLost())
return;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h
index 0b9f53119e0..7141e82de09 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h
@@ -32,28 +32,27 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/WebGLExtension.h"
-#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-class ANGLEInstancedArrays : public WebGLExtension, public ScriptWrappable {
+class ANGLEInstancedArrays FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<ANGLEInstancedArrays> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<ANGLEInstancedArrays> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~ANGLEInstancedArrays();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
- void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount);
- void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
+ void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+ void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount);
+ void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
private:
- ANGLEInstancedArrays(WebGLRenderingContext*);
+ ANGLEInstancedArrays(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl
index 2d257cce1b9..4e63430ade0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl
@@ -29,12 +29,13 @@
*/
[
+ DoNotCheckConstants,
NoInterfaceObject,
- DoNotCheckConstants
+ TypeChecking=Interface|Nullable,
] interface ANGLEInstancedArrays {
const unsigned long VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
- [StrictTypeChecking] void drawArraysInstancedANGLE(unsigned long mode, long first, long count, long primcount);
- [StrictTypeChecking] void drawElementsInstancedANGLE(unsigned long mode, long count, unsigned long type, long long offset, long primcount);
- [StrictTypeChecking] void vertexAttribDivisorANGLE(unsigned long index, long divisor);
+ void drawArraysInstancedANGLE(unsigned long mode, long first, long count, long primcount);
+ void drawElementsInstancedANGLE(unsigned long mode, long count, unsigned long type, long long offset, long primcount);
+ void vertexAttribDivisorANGLE(unsigned long index, long divisor);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp
index 66429f5af14..3ff9b1ac9ee 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp
@@ -26,12 +26,15 @@
#include "config.h"
-#include "Canvas2DContextAttributes.h"
+#include "core/html/canvas/Canvas2DContextAttributes.h"
+
+#include "wtf/text/WTFString.h"
namespace WebCore {
Canvas2DContextAttributes::Canvas2DContextAttributes()
: m_alpha(true)
+ , m_storage(PersistentStorage)
{
ScriptWrappable::init(this);
}
@@ -55,4 +58,22 @@ void Canvas2DContextAttributes::setAlpha(bool alpha)
m_alpha = alpha;
}
+String Canvas2DContextAttributes::storage() const
+{
+ return m_storage == PersistentStorage ? "persistent" : "discardable";
+}
+
+void Canvas2DContextAttributes::setStorage(const String& storage)
+{
+ if (storage == "persistent")
+ m_storage = PersistentStorage;
+ else if (storage == "discardable")
+ m_storage = DiscardableStorage;
+}
+
+Canvas2DContextStorage Canvas2DContextAttributes::parsedStorage() const
+{
+ return m_storage;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h
index e777ef80778..dab44564297 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h
@@ -33,6 +33,11 @@
namespace WebCore {
+enum Canvas2DContextStorage {
+ PersistentStorage,
+ DiscardableStorage
+};
+
class Canvas2DContextAttributes : public CanvasContextAttributes, public ScriptWrappable {
public:
virtual ~Canvas2DContextAttributes();
@@ -44,10 +49,15 @@ public:
bool alpha() const;
void setAlpha(bool);
+ String storage() const;
+ void setStorage(const String&);
+ Canvas2DContextStorage parsedStorage() const;
+
protected:
Canvas2DContextAttributes();
bool m_alpha;
+ Canvas2DContextStorage m_storage;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl
index 72e01914f14..f6017b3c86f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl
@@ -28,4 +28,5 @@
NoInterfaceObject
] interface Canvas2DContextAttributes {
attribute boolean alpha;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] attribute DOMString storage;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp
index 07e62a07e10..c63aa7d85b0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp
@@ -49,13 +49,13 @@ CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint&
void CanvasGradient::addColorStop(float value, const String& color, ExceptionState& exceptionState)
{
if (!(value >= 0 && value <= 1.0f)) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided value (" + String::number(value) + ") is outside the range (0.0, 1.0).");
return;
}
RGBA32 rgba = 0;
if (!parseColorOrCurrentColor(rgba, color, 0 /*canvas*/)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + color + "') could not be parsed as a color.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl
index 35a4e2a31d0..3da025a744c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl
@@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
+ TypeChecking=Unrestricted,
] interface CanvasGradient {
[RaisesException] void addColorStop(float offset, DOMString color);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
new file mode 100644
index 00000000000..10e3b958b6c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
@@ -0,0 +1,77 @@
+/*
+ * 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 CanvasImageSource_h
+#define CanvasImageSource_h
+
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class Image;
+class SecurityOrigin;
+
+enum SourceImageMode {
+ CopySourceImageIfVolatile,
+ DontCopySourceImage
+};
+
+enum SourceImageStatus {
+ NormalSourceImageStatus,
+ ExternalSourceImageStatus, // Shared with another GPU context
+ UndecodableSourceImageStatus, // Image element with a 'broken' image
+ ZeroSizeCanvasSourceImageStatus, // Source is a canvas with width or heigh of zero
+ IncompleteSourceImageStatus, // Image element with no source media
+ InvalidSourceImageStatus,
+};
+
+class CanvasImageSource {
+public:
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus* = 0) const = 0;
+
+ // IMPORTANT: Result must be independent of whether destinationContext is
+ // already tainted because this function may be used to determine whether
+ // a CanvasPattern is "origin clean", and that pattern may be used on
+ // another canvas, which may not be already tainted.
+ virtual bool wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const = 0;
+
+ virtual bool isVideoElement() const { return false; }
+
+ // Adjusts the source and destination rectangles for cases where the actual
+ // source image is a subregion of the image returned by getSourceImageForCanvas.
+ virtual void adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const { }
+
+ virtual FloatSize sourceSize() const = 0;
+ virtual FloatSize defaultDestinationSize() const { return sourceSize(); }
+ virtual const KURL& sourceURL() const { return blankURL(); }
+
+protected:
+ virtual ~CanvasImageSource() { }
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp
index 66a1ac99fa4..879487b14d3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp
@@ -113,7 +113,7 @@ void CanvasPathMethods::arcTo(float x1, float y1, float x2, float y2, float r, E
return;
if (r < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The radius provided (" + String::number(r) + ") is negative.");
return;
}
@@ -135,7 +135,6 @@ namespace {
float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
{
- float twoPi = 2 * piFloat;
float newEndAngle = endAngle;
/* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc
* If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2pi, or,
@@ -143,10 +142,10 @@ float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
* then the arc is the whole circumference of this ellipse, and the point at startAngle along this circle's circumference,
* measured in radians clockwise from the ellipse's semi-major axis, acts as both the start point and the end point.
*/
- if (!anticlockwise && endAngle - startAngle >= twoPi)
- newEndAngle = startAngle + twoPi;
- else if (anticlockwise && startAngle - endAngle >= twoPi)
- newEndAngle = startAngle - twoPi;
+ if (!anticlockwise && endAngle - startAngle >= twoPiFloat)
+ newEndAngle = startAngle + twoPiFloat;
+ else if (anticlockwise && startAngle - endAngle >= twoPiFloat)
+ newEndAngle = startAngle - twoPiFloat;
/*
* Otherwise, the arc is the path along the circumference of this ellipse from the start point to the end point,
@@ -159,9 +158,9 @@ float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
* We preserve backward-compatibility.
*/
else if (!anticlockwise && startAngle > endAngle)
- newEndAngle = startAngle + (twoPi - fmodf(startAngle - endAngle, twoPi));
+ newEndAngle = startAngle + (twoPiFloat - fmodf(startAngle - endAngle, twoPiFloat));
else if (anticlockwise && startAngle < endAngle)
- newEndAngle = startAngle - (twoPi - fmodf(endAngle - startAngle, twoPi));
+ newEndAngle = startAngle - (twoPiFloat - fmodf(endAngle - startAngle, twoPiFloat));
ASSERT(ellipseIsRenderable(startAngle, newEndAngle));
return newEndAngle;
@@ -180,17 +179,16 @@ inline FloatPoint getPointOnEllipse(float radiusX, float radiusY, float theta)
void canonicalizeAngle(float* startAngle, float* endAngle)
{
// Make 0 <= startAngle < 2*PI
- float twoPi = 2 * piFloat;
float newStartAngle = *startAngle;
if (newStartAngle < 0)
- newStartAngle = twoPi + fmodf(newStartAngle, -twoPi);
+ newStartAngle = twoPiFloat + fmodf(newStartAngle, -twoPiFloat);
else
- newStartAngle = fmodf(newStartAngle, twoPi);
+ newStartAngle = fmodf(newStartAngle, twoPiFloat);
float delta = newStartAngle - *startAngle;
*startAngle = newStartAngle;
*endAngle = *endAngle + delta;
- ASSERT(newStartAngle >= 0 && newStartAngle < twoPi);
+ ASSERT(newStartAngle >= 0 && newStartAngle < twoPiFloat);
}
/*
@@ -227,25 +225,24 @@ void canonicalizeAngle(float* startAngle, float* endAngle)
void degenerateEllipse(CanvasPathMethods* path, float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise)
{
ASSERT(ellipseIsRenderable(startAngle, endAngle));
- ASSERT(startAngle >= 0 && startAngle < 2 * piFloat);
+ ASSERT(startAngle >= 0 && startAngle < twoPiFloat);
ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || (!anticlockwise && (endAngle - startAngle) >= 0));
FloatPoint center(x, y);
AffineTransform rotationMatrix;
- rotationMatrix.rotate(rad2deg(rotation));
+ rotationMatrix.rotateRadians(rotation);
// First, if the object's path has any subpaths, then the method must add a straight line from the last point in the subpath to the start point of the arc.
lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, startAngle)));
if ((!radiusX && !radiusY) || startAngle == endAngle)
return;
- float halfPiFloat = piFloat * 0.5;
if (!anticlockwise) {
- // startAngle - fmodf(startAngle, halfPiFloat) + halfPiFloat is the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi)
+ // startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat is the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi)
// that is the closest to startAngle on the clockwise direction.
- for (float angle = startAngle - fmodf(startAngle, halfPiFloat) + halfPiFloat; angle < endAngle; angle += halfPiFloat)
+ for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; angle < endAngle; angle += piOverTwoFloat)
lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, angle)));
} else {
- for (float angle = startAngle - fmodf(startAngle, halfPiFloat); angle > endAngle; angle -= halfPiFloat)
+ for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); angle > endAngle; angle -= piOverTwoFloat)
lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, angle)));
}
@@ -260,7 +257,7 @@ void CanvasPathMethods::arc(float x, float y, float radius, float startAngle, fl
return;
if (radius < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The radius provided (" + String::number(radius) + ") is negative.");
return;
}
@@ -283,8 +280,12 @@ void CanvasPathMethods::ellipse(float x, float y, float radiusX, float radiusY,
if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radiusX) || !std::isfinite(radiusY) || !std::isfinite(rotation) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
return;
- if (radiusX < 0 || radiusY < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ if (radiusX < 0) {
+ exceptionState.throwDOMException(IndexSizeError, "The major-axis radius provided (" + String::number(radiusX) + ") is negative.");
+ return;
+ }
+ if (radiusY < 0) {
+ exceptionState.throwDOMException(IndexSizeError, "The minor-axis radius provided (" + String::number(radiusY) + ") is negative.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h
index 100f95cf055..2f0160ea1bf 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h
@@ -54,6 +54,7 @@ public:
protected:
CanvasPathMethods() { }
+ CanvasPathMethods(const Path& path) : m_path(path) { }
Path m_path;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl
new file mode 100644
index 00000000000..2c37810cef7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl
@@ -0,0 +1,20 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspathmethods
+
+[
+ NoInterfaceObject, // Always used on target of 'implements'
+] interface CanvasPathMethods {
+ // shared path API methods
+ void closePath();
+ void moveTo(unrestricted float x, unrestricted float y);
+ void lineTo(unrestricted float x, unrestricted float y);
+ void quadraticCurveTo(unrestricted float cpx, unrestricted float cpy, unrestricted float x, unrestricted float y);
+ void bezierCurveTo(unrestricted float cp1x, unrestricted float cp1y, unrestricted float cp2x, unrestricted float cp2y, unrestricted float x, unrestricted float y);
+ [RaisesException] void arcTo(unrestricted float x1, unrestricted float y1, unrestricted float x2, unrestricted float y2, unrestricted float radius);
+ void rect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void arc(unrestricted float x, unrestricted float y, unrestricted float radius, unrestricted float startAngle, unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
+ [RaisesException] void ellipse(unrestricted float x, unrestricted float y, unrestricted float radiusX, unrestricted float radiusY, unrestricted float rotation, unrestricted float startAngle, unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp
index f7ee0da4388..e011ff082a3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp
@@ -54,7 +54,7 @@ void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool&
repeatY = true;
return;
}
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The provided type ('" + type + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'.");
}
CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
index 47a0e616efb..9e5dd350d8f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -26,10 +26,7 @@
#include "config.h"
#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/canvas/CanvasPattern.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
@@ -37,72 +34,30 @@ namespace WebCore {
CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas)
: m_canvas(canvas)
{
- ScriptWrappable::init(this);
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
-{
- if (canvas()->originClean() && pattern && !pattern->originClean())
- return true;
- return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
-{
- if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
- return true;
- return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
-{
- if (!image || !canvas()->originClean())
- return false;
-
- ImageResource* cachedImage = image->cachedImage();
- if (!cachedImage->image()->currentFrameHasSingleSecurityOrigin())
- return true;
-
- return wouldTaintOrigin(cachedImage->response().url()) && !cachedImage->passesAccessControlCheck(canvas()->securityOrigin());
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
-{
- // FIXME: This check is likely wrong when a redirect is involved. We need
- // to test the finalURL. Please be careful when fixing this issue not to
- // make currentSrc be the final URL because then the
- // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
- if (!video || !canvas()->originClean())
- return false;
-
- if (!video->hasSingleSecurityOrigin())
- return true;
-
- if (!(video->player() && video->player()->didPassCORSAccessCheck()) && wouldTaintOrigin(video->currentSrc()))
- return true;
-
- return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
-{
- if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
- return false;
-
- if (canvas()->securityOrigin()->taintsCanvas(url))
- return true;
-
- if (url.protocolIsData())
- return false;
- m_cleanURLs.add(url.string());
- return false;
}
-void CanvasRenderingContext::checkOrigin(const KURL& url)
+bool CanvasRenderingContext::wouldTaintOrigin(CanvasImageSource* imageSource)
{
- if (wouldTaintOrigin(url))
- canvas()->setOriginTainted();
+ const KURL& sourceURL = imageSource->sourceURL();
+ bool hasURL = (sourceURL.isValid() && !sourceURL.isAboutBlankURL());
+
+ if (hasURL) {
+ if (sourceURL.protocolIsData() || m_cleanURLs.contains(sourceURL.string()))
+ return false;
+ if (m_dirtyURLs.contains(sourceURL.string()))
+ return true;
+ }
+
+ bool taintOrigin = imageSource->wouldTaintOrigin(canvas()->securityOrigin());
+
+ if (hasURL) {
+ if (taintOrigin)
+ m_dirtyURLs.add(sourceURL.string());
+ else
+ m_cleanURLs.add(sourceURL.string());
+ }
+ return taintOrigin;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
index 2f5cd637991..0999d334bf7 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -26,8 +26,8 @@
#ifndef CanvasRenderingContext_h
#define CanvasRenderingContext_h
-#include "bindings/v8/ScriptWrappable.h"
#include "core/html/HTMLCanvasElement.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/Noncopyable.h"
#include "wtf/text/StringHash.h"
@@ -36,20 +36,22 @@ namespace blink { class WebLayer; }
namespace WebCore {
-class CanvasPattern;
+class CanvasImageSource;
class HTMLCanvasElement;
-class HTMLImageElement;
-class HTMLVideoElement;
class KURL;
class WebGLObject;
-class CanvasRenderingContext : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
+class CanvasRenderingContext : public NoBaseWillBeGarbageCollectedFinalized<CanvasRenderingContext> {
+ WTF_MAKE_NONCOPYABLE(CanvasRenderingContext);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
virtual ~CanvasRenderingContext() { }
+#if !ENABLE(OILPAN)
void ref() { m_canvas->ref(); }
void deref() { m_canvas->deref(); }
+#endif
+
HTMLCanvasElement* canvas() const { return m_canvas; }
virtual bool is2d() const { return false; }
@@ -61,24 +63,17 @@ public:
virtual blink::WebLayer* platformLayer() const { return 0; }
+ virtual void trace(Visitor* visitor) { visitor->trace(m_canvas); }
+
+ bool wouldTaintOrigin(CanvasImageSource*);
+
protected:
CanvasRenderingContext(HTMLCanvasElement*);
- bool wouldTaintOrigin(const CanvasPattern*);
- bool wouldTaintOrigin(const HTMLCanvasElement*);
- bool wouldTaintOrigin(const HTMLImageElement*);
- bool wouldTaintOrigin(const HTMLVideoElement*);
- bool wouldTaintOrigin(const KURL&);
-
- template<class T> void checkOrigin(const T* arg)
- {
- if (wouldTaintOrigin(arg))
- canvas()->setOriginTainted();
- }
- void checkOrigin(const KURL&);
private:
- HTMLCanvasElement* m_canvas;
+ RawPtrWillBeMember<HTMLCanvasElement> m_canvas;
HashSet<String> m_cleanURLs;
+ HashSet<String> m_dirtyURLs;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl
deleted file mode 100644
index ae89a5fcd56..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-[
- Custom=Wrap,
- NoInterfaceObject,
-] interface CanvasRenderingContext {
- readonly attribute HTMLCanvasElement canvas;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp
index 68f213b18ae..ccca4ddd03f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp
@@ -33,16 +33,18 @@
#include "config.h"
#include "core/html/canvas/CanvasRenderingContext2D.h"
-#include "CSSPropertyNames.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/css/CSSFontSelector.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ExceptionCode.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/ImageBitmap.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLMediaElement.h"
@@ -52,46 +54,52 @@
#include "core/html/canvas/CanvasGradient.h"
#include "core/html/canvas/CanvasPattern.h"
#include "core/html/canvas/CanvasStyle.h"
-#include "core/html/canvas/DOMPath.h"
-#include "core/frame/ImageBitmap.h"
+#include "core/html/canvas/Path2D.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderTheme.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatQuad.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
-#include "platform/graphics/DrawLooper.h"
#include "platform/text/TextRun.h"
-#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/CheckedArithmetic.h"
#include "wtf/MathExtras.h"
#include "wtf/OwnPtr.h"
#include "wtf/Uint8ClampedArray.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
static const int defaultFontSize = 10;
static const char defaultFontFamily[] = "sans-serif";
static const char defaultFont[] = "10px sans-serif";
+static const double TryRestoreContextInterval = 0.5;
+static const unsigned MaxTryRestoreContextAttempts = 4;
+
+static bool contextLostRestoredEventsEnabled()
+{
+ return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
+}
CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
: CanvasRenderingContext(canvas)
- , m_stateStack(1)
- , m_unrealizedSaveCount(0)
, m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode)
, m_hasAlpha(!attrs || attrs->alpha())
-{
+ , m_isContextLost(false)
+ , m_contextRestorable(true)
+ , m_storageMode(!attrs ? PersistentStorage : attrs->parsedStorage())
+ , m_tryRestoreContextAttemptCount(0)
+ , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchContextLostEvent)
+ , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispatchContextRestoredEvent)
+ , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreContextEvent)
+{
+ m_stateStack.append(adoptPtrWillBeNoop(new State()));
ScriptWrappable::init(this);
}
void CanvasRenderingContext2D::unwindStateStack()
{
- // Ensure that the state stack in the ImageBuffer's context
- // is cleared before destruction, to avoid assertions in the
- // GraphicsContext dtor.
if (size_t stackSize = m_stateStack.size()) {
if (GraphicsContext* context = canvas()->existingDrawingContext()) {
while (--stackSize)
@@ -102,8 +110,14 @@ void CanvasRenderingContext2D::unwindStateStack()
CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
-#if !ASSERT_DISABLED
- unwindStateStack();
+}
+
+void CanvasRenderingContext2D::validateStateStack()
+{
+#if ASSERT_ENABLED
+ GraphicsContext* context = canvas()->existingDrawingContext();
+ if (context && !context->contextDisabled())
+ ASSERT(context->saveCount() == m_stateStack.size());
#endif
}
@@ -115,13 +129,108 @@ bool CanvasRenderingContext2D::isAccelerated() const
return context && context->isAccelerated();
}
+bool CanvasRenderingContext2D::isContextLost() const
+{
+ return m_isContextLost;
+}
+
+void CanvasRenderingContext2D::loseContext()
+{
+ if (m_isContextLost)
+ return;
+ m_isContextLost = true;
+ m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE);
+}
+
+void CanvasRenderingContext2D::restoreContext()
+{
+ if (!m_contextRestorable)
+ return;
+ // This code path is for restoring from an eviction
+ // Restoring from surface failure is handled internally
+ ASSERT(m_isContextLost && !canvas()->hasImageBuffer());
+
+ if (canvas()->buffer()) {
+ if (contextLostRestoredEventsEnabled()) {
+ m_dispatchContextRestoredEventTimer.startOneShot(0, FROM_HERE);
+ } else {
+ // legacy synchronous context restoration.
+ reset();
+ m_isContextLost = false;
+ }
+ }
+}
+
+void CanvasRenderingContext2D::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_stateStack);
+ visitor->trace(m_fetchedFonts);
+#endif
+ CanvasRenderingContext::trace(visitor);
+}
+
+void CanvasRenderingContext2D::dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*)
+{
+ if (contextLostRestoredEventsEnabled()) {
+ RefPtrWillBeRawPtr<Event> event = Event::createCancelable(EventTypeNames::contextlost);
+ canvas()->dispatchEvent(event);
+ if (event->defaultPrevented()) {
+ m_contextRestorable = false;
+ }
+ }
+
+ // If an image buffer is present, it means the context was not lost due to
+ // an eviction, but rather due to a surface failure (gpu context lost?)
+ if (m_contextRestorable && canvas()->hasImageBuffer()) {
+ m_tryRestoreContextAttemptCount = 0;
+ m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval, FROM_HERE);
+ }
+}
+
+void CanvasRenderingContext2D::tryRestoreContextEvent(Timer<CanvasRenderingContext2D>* timer)
+{
+ if (!m_isContextLost) {
+ // Canvas was already restored (possibly thanks to a resize), so stop trying.
+ m_tryRestoreContextEventTimer.stop();
+ return;
+ }
+ if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) {
+ m_tryRestoreContextEventTimer.stop();
+ dispatchContextRestoredEvent(0);
+ }
+
+ if (++m_tryRestoreContextAttemptCount > MaxTryRestoreContextAttempts)
+ canvas()->discardImageBuffer();
+
+ if (!canvas()->hasImageBuffer()) {
+ // final attempt: allocate a brand new image buffer instead of restoring
+ timer->stop();
+ if (canvas()->buffer())
+ dispatchContextRestoredEvent(0);
+ }
+}
+
+void CanvasRenderingContext2D::dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*)
+{
+ if (!m_isContextLost)
+ return;
+ reset();
+ m_isContextLost = false;
+ if (contextLostRestoredEventsEnabled()) {
+ RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextrestored));
+ canvas()->dispatchEvent(event);
+ }
+}
+
void CanvasRenderingContext2D::reset()
{
+ validateStateStack();
unwindStateStack();
m_stateStack.resize(1);
- m_stateStack.first() = State();
+ m_stateStack.first() = adoptPtrWillBeNoop(new State());
m_path.clear();
- m_unrealizedSaveCount = 0;
+ validateStateStack();
}
// Important: Several of these properties are also stored in GraphicsContext's
@@ -129,7 +238,8 @@ void CanvasRenderingContext2D::reset()
// that the canvas 2d spec specifies. Make sure to sync the initial state of the
// GraphicsContext in HTMLCanvasElement::createImageBuffer()!
CanvasRenderingContext2D::State::State()
- : m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
+ : m_unrealizedSaveCount(0)
+ , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
, m_fillStyle(CanvasStyle::createFromRGBA(Color::black))
, m_lineWidth(1)
, m_lineCap(ButtCap)
@@ -151,7 +261,8 @@ CanvasRenderingContext2D::State::State()
}
CanvasRenderingContext2D::State::State(const State& other)
- : FontSelectorClient()
+ : CSSFontSelectorClient()
+ , m_unrealizedSaveCount(other.m_unrealizedSaveCount)
, m_unparsedStrokeColor(other.m_unparsedStrokeColor)
, m_unparsedFillColor(other.m_unparsedFillColor)
, m_strokeStyle(other.m_strokeStyle)
@@ -177,7 +288,7 @@ CanvasRenderingContext2D::State::State(const State& other)
, m_realizedFont(other.m_realizedFont)
{
if (m_realizedFont)
- m_font.fontSelector()->registerForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalidationCallbacks(this);
}
CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
@@ -185,9 +296,12 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
if (this == &other)
return *this;
+#if !ENABLE(OILPAN)
if (m_realizedFont)
- m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInvalidationCallbacks(this);
+#endif
+ m_unrealizedSaveCount = other.m_unrealizedSaveCount;
m_unparsedStrokeColor = other.m_unparsedStrokeColor;
m_unparsedFillColor = other.m_unparsedFillColor;
m_strokeStyle = other.m_strokeStyle;
@@ -212,18 +326,20 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
m_realizedFont = other.m_realizedFont;
if (m_realizedFont)
- m_font.fontSelector()->registerForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalidationCallbacks(this);
return *this;
}
CanvasRenderingContext2D::State::~State()
{
+#if !ENABLE(OILPAN)
if (m_realizedFont)
- m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInvalidationCallbacks(this);
+#endif
}
-void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
+void CanvasRenderingContext2D::State::fontsNeedUpdate(CSSFontSelector* fontSelector)
{
ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
ASSERT(m_realizedFont);
@@ -231,22 +347,33 @@ void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector
m_font.update(fontSelector);
}
-void CanvasRenderingContext2D::realizeSavesLoop()
-{
- ASSERT(m_unrealizedSaveCount);
- ASSERT(m_stateStack.size() >= 1);
- GraphicsContext* context = drawingContext();
- do {
- m_stateStack.append(state());
+void CanvasRenderingContext2D::realizeSaves()
+{
+ validateStateStack();
+ if (state().m_unrealizedSaveCount) {
+ ASSERT(m_stateStack.size() >= 1);
+ // Reduce the current state's unrealized count by one now,
+ // to reflect the fact we are saving one state.
+ m_stateStack.last()->m_unrealizedSaveCount--;
+ m_stateStack.append(adoptPtrWillBeNoop(new State(state())));
+ // Set the new state's unrealized count to 0, because it has no outstanding saves.
+ // We need to do this explicitly because the copy constructor and operator= used
+ // by the Vector operations copy the unrealized count from the previous state (in
+ // turn necessary to support correct resizing and unwinding of the stack).
+ m_stateStack.last()->m_unrealizedSaveCount = 0;
+ GraphicsContext* context = drawingContext();
if (context)
context->save();
- } while (--m_unrealizedSaveCount);
+ validateStateStack();
+ }
}
void CanvasRenderingContext2D::restore()
{
- if (m_unrealizedSaveCount) {
- --m_unrealizedSaveCount;
+ validateStateStack();
+ if (state().m_unrealizedSaveCount) {
+ // We never realized the save, so just record that it was unnecessary.
+ --m_stateStack.last()->m_unrealizedSaveCount;
return;
}
ASSERT(m_stateStack.size() >= 1);
@@ -256,9 +383,9 @@ void CanvasRenderingContext2D::restore()
m_stateStack.removeLast();
m_path.transform(state().m_transform.inverse());
GraphicsContext* c = drawingContext();
- if (!c)
- return;
- c->restore();
+ if (c)
+ c->restore();
+ validateStateStack();
}
CanvasStyle* CanvasRenderingContext2D::strokeStyle() const
@@ -281,8 +408,9 @@ void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> prpStyle)
style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
else
style = CanvasStyle::createFromRGBA(currentColor(canvas()));
- } else
- checkOrigin(style->canvasPattern());
+ } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+ canvas()->setOriginTainted();
+ }
realizeSaves();
modifiableState().m_strokeStyle = style.release();
@@ -313,8 +441,9 @@ void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> prpStyle)
style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
else
style = CanvasStyle::createFromRGBA(currentColor(canvas()));
- } else
- checkOrigin(style->canvasPattern());
+ } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+ canvas()->setOriginTainted();
+ }
realizeSaves();
modifiableState().m_fillStyle = style.release();
@@ -492,18 +621,7 @@ void CanvasRenderingContext2D::setLineDash(const Vector<float>& dash)
// Spec requires the concatenation of two copies the dash list when the
// number of elements is odd
if (dash.size() % 2)
- modifiableState().m_lineDash.append(dash);
-
- applyLineDash();
-}
-
-void CanvasRenderingContext2D::setWebkitLineDash(const Vector<float>& dash)
-{
- if (!lineDashSequenceIsValid(dash))
- return;
-
- realizeSaves();
- modifiableState().m_lineDash = dash;
+ modifiableState().m_lineDash.appendVector(dash);
applyLineDash();
}
@@ -523,16 +641,6 @@ void CanvasRenderingContext2D::setLineDashOffset(float offset)
applyLineDash();
}
-float CanvasRenderingContext2D::webkitLineDashOffset() const
-{
- return lineDashOffset();
-}
-
-void CanvasRenderingContext2D::setWebkitLineDashOffset(float offset)
-{
- setLineDashOffset(offset);
-}
-
void CanvasRenderingContext2D::applyLineDash() const
{
GraphicsContext* c = drawingContext();
@@ -560,7 +668,7 @@ void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
GraphicsContext* c = drawingContext();
if (!c)
return;
- c->setAlpha(alpha);
+ c->setAlphaAsFloat(alpha);
}
String CanvasRenderingContext2D::globalCompositeOperation() const
@@ -585,9 +693,11 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
c->setCompositeOperation(op, blendMode);
}
-void CanvasRenderingContext2D::setCurrentTransform(const SVGMatrix& matrix)
+void CanvasRenderingContext2D::setCurrentTransform(PassRefPtr<SVGMatrixTearOff> passMatrixTearOff)
{
- setTransform(matrix.a(), matrix.b(), matrix.c(), matrix.d(), matrix.e(), matrix.f());
+ RefPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
+ const AffineTransform& transform = matrixTearOff->value();
+ setTransform(transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
}
void CanvasRenderingContext2D::scale(float sx, float sy)
@@ -614,7 +724,7 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
}
modifiableState().m_transform = newTransform;
- c->scale(FloatSize(sx, sy));
+ c->scale(sx, sy);
m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
}
@@ -630,7 +740,7 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
return;
AffineTransform newTransform = state().m_transform;
- newTransform.rotate(angleInRadians / piDouble * 180.0);
+ newTransform.rotateRadians(angleInRadians);
if (state().m_transform == newTransform)
return;
@@ -643,7 +753,7 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
modifiableState().m_transform = newTransform;
c->rotate(angleInRadians);
- m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
+ m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
}
void CanvasRenderingContext2D::translate(float tx, float ty)
@@ -745,7 +855,7 @@ void CanvasRenderingContext2D::setStrokeColor(const String& color)
if (color == state().m_unparsedStrokeColor)
return;
realizeSaves();
- setStrokeStyle(CanvasStyle::createFromString(color, &canvas()->document()));
+ setStrokeStyle(CanvasStyle::createFromString(color));
modifiableState().m_unparsedStrokeColor = color;
}
@@ -787,7 +897,7 @@ void CanvasRenderingContext2D::setFillColor(const String& color)
if (color == state().m_unparsedFillColor)
return;
realizeSaves();
- setFillStyle(CanvasStyle::createFromString(color, &canvas()->document()));
+ setFillStyle(CanvasStyle::createFromString(color));
modifiableState().m_unparsedFillColor = color;
}
@@ -829,18 +939,6 @@ void CanvasRenderingContext2D::beginPath()
m_path.clear();
}
-PassRefPtr<DOMPath> CanvasRenderingContext2D::currentPath()
-{
- return DOMPath::create(m_path);
-}
-
-void CanvasRenderingContext2D::setCurrentPath(DOMPath* path)
-{
- if (!path)
- return;
- m_path = path->path();
-}
-
static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
{
if (!std::isfinite(x) | !std::isfinite(y) | !std::isfinite(width) | !std::isfinite(height))
@@ -870,102 +968,157 @@ static bool isFullCanvasCompositeMode(CompositeOperator op)
return op == CompositeSourceIn || op == CompositeSourceOut || op == CompositeDestinationIn || op == CompositeDestinationAtop;
}
-static bool parseWinding(const String& windingRuleString, WindRule& windRule)
+static WindRule parseWinding(const String& windingRuleString)
{
if (windingRuleString == "nonzero")
- windRule = RULE_NONZERO;
- else if (windingRuleString == "evenodd")
- windRule = RULE_EVENODD;
- else
- return false;
+ return RULE_NONZERO;
+ if (windingRuleString == "evenodd")
+ return RULE_EVENODD;
- return true;
+ ASSERT_NOT_REACHED();
+ return RULE_EVENODD;
}
-void CanvasRenderingContext2D::fill(const String& windingRuleString)
+void CanvasRenderingContext2D::fillInternal(const Path& path, const String& windingRuleString)
{
+ if (path.isEmpty()) {
+ return;
+ }
GraphicsContext* c = drawingContext();
- if (!c)
+ if (!c) {
return;
- if (!state().m_invertibleCTM)
+ }
+ if (!state().m_invertibleCTM) {
return;
+ }
FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+ if (!c->getTransformedClipBounds(&clipBounds)) {
return;
+ }
// If gradient size is zero, then paint nothing.
Gradient* gradient = c->fillGradient();
- if (gradient && gradient->isZeroSize())
+ if (gradient && gradient->isZeroSize()) {
return;
+ }
- if (!m_path.isEmpty()) {
- WindRule windRule = c->fillRule();
- WindRule newWindRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, newWindRule))
- return;
- c->setFillRule(newWindRule);
+ WindRule windRule = c->fillRule();
+ c->setFillRule(parseWinding(windingRuleString));
- if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedFill(m_path);
- didDraw(clipBounds);
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->fillPath(m_path);
- didDraw(clipBounds);
- } else {
- FloatRect dirtyRect;
- if (computeDirtyRect(m_path.boundingRect(), clipBounds, &dirtyRect)) {
- c->fillPath(m_path);
- didDraw(dirtyRect);
- }
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedFill(path);
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->fillPath(path);
+ didDraw(clipBounds);
+ } else {
+ FloatRect dirtyRect;
+ if (computeDirtyRect(path.boundingRect(), clipBounds, &dirtyRect)) {
+ c->fillPath(path);
+ didDraw(dirtyRect);
}
-
- c->setFillRule(windRule);
}
+
+ c->setFillRule(windRule);
}
-void CanvasRenderingContext2D::stroke()
+void CanvasRenderingContext2D::fill(const String& windingRuleString)
+{
+ fillInternal(m_path, windingRuleString);
+}
+
+void CanvasRenderingContext2D::fill(Path2D* domPath, const String& windingRuleString)
{
+ fillInternal(domPath->path(), windingRuleString);
+}
+
+void CanvasRenderingContext2D::strokeInternal(const Path& path)
+{
+ if (path.isEmpty()) {
+ return;
+ }
GraphicsContext* c = drawingContext();
- if (!c)
+ if (!c) {
return;
- if (!state().m_invertibleCTM)
+ }
+ if (!state().m_invertibleCTM) {
+ return;
+ }
+ FloatRect clipBounds;
+ if (!c->getTransformedClipBounds(&clipBounds))
return;
// If gradient size is zero, then paint nothing.
Gradient* gradient = c->strokeGradient();
- if (gradient && gradient->isZeroSize())
+ if (gradient && gradient->isZeroSize()) {
return;
+ }
- if (!m_path.isEmpty()) {
- FloatRect bounds = m_path.boundingRect();
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedStroke(path);
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->strokePath(path);
+ didDraw(clipBounds);
+ } else {
+ FloatRect bounds = path.boundingRect();
inflateStrokeRect(bounds);
FloatRect dirtyRect;
- if (computeDirtyRect(bounds, &dirtyRect)) {
- c->strokePath(m_path);
+ if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
+ c->strokePath(path);
didDraw(dirtyRect);
}
}
}
-void CanvasRenderingContext2D::clip(const String& windingRuleString)
+void CanvasRenderingContext2D::stroke()
+{
+ strokeInternal(m_path);
+}
+
+void CanvasRenderingContext2D::stroke(Path2D* domPath)
+{
+ strokeInternal(domPath->path());
+}
+
+void CanvasRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
{
GraphicsContext* c = drawingContext();
- if (!c)
+ if (!c) {
return;
- if (!state().m_invertibleCTM)
- return;
-
- WindRule newWindRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, newWindRule))
+ }
+ if (!state().m_invertibleCTM) {
return;
+ }
realizeSaves();
- c->canvasClip(m_path, newWindRule);
+ c->canvasClip(path, parseWinding(windingRuleString));
+}
+
+void CanvasRenderingContext2D::clip(const String& windingRuleString)
+{
+ clipInternal(m_path, windingRuleString);
+}
+
+void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleString)
+{
+ clipInternal(domPath->path(), windingRuleString);
}
bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString)
{
+ return isPointInPathInternal(m_path, x, y, windingRuleString);
+}
+
+bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, const float y, const String& windingRuleString)
+{
+ return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
+}
+
+bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const float x, const float y, const String& windingRuleString)
+{
GraphicsContext* c = drawingContext();
if (!c)
return false;
@@ -978,15 +1131,20 @@ bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const
if (!std::isfinite(transformedPoint.x()) || !std::isfinite(transformedPoint.y()))
return false;
- WindRule windRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, windRule))
- return false;
+ return path.contains(transformedPoint, parseWinding(windingRuleString));
+}
- return m_path.contains(transformedPoint, windRule);
+bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
+{
+ return isPointInStrokeInternal(m_path, x, y);
}
+bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, const float y)
+{
+ return isPointInStrokeInternal(domPath->path(), x, y);
+}
-bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
+bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, const float x, const float y)
{
GraphicsContext* c = drawingContext();
if (!c)
@@ -1006,7 +1164,46 @@ bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
strokeData.setLineJoin(getLineJoin());
strokeData.setMiterLimit(miterLimit());
strokeData.setLineDash(getLineDash(), lineDashOffset());
- return m_path.strokeContains(transformedPoint, strokeData);
+ return path.strokeContains(transformedPoint, strokeData);
+}
+
+void CanvasRenderingContext2D::scrollPathIntoView()
+{
+ scrollPathIntoViewInternal(m_path);
+}
+
+void CanvasRenderingContext2D::scrollPathIntoView(Path2D* path2d)
+{
+ scrollPathIntoViewInternal(path2d->path());
+}
+
+void CanvasRenderingContext2D::scrollPathIntoViewInternal(const Path& path)
+{
+ if (!state().m_invertibleCTM || path.isEmpty())
+ return;
+
+ canvas()->document().updateLayoutIgnorePendingStylesheets();
+
+ // Apply transformation and get the bounding rect
+ Path transformedPath = path;
+ transformedPath.transform(state().m_transform);
+ FloatRect boundingRect = transformedPath.boundingRect();
+
+ // Offset by the canvas rect (We should take border and padding into account).
+ RenderBoxModelObject* rbmo = canvas()->renderBoxModelObject();
+ IntRect canvasRect = canvas()->renderer()->absoluteBoundingBoxRect();
+ canvasRect.move(rbmo->borderLeft() + rbmo->paddingLeft(),
+ rbmo->borderTop() + rbmo->paddingTop());
+ LayoutRect pathRect = enclosingLayoutRect(boundingRect);
+ pathRect.moveBy(canvasRect.location());
+
+ if (canvas()->renderer()) {
+ canvas()->renderer()->scrollRectToVisible(
+ pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopAlways);
+ }
+
+ // TODO: should implement "inform the user" that the caret and/or
+ // selection the specified rectangle of the canvas. See http://crbug.com/357987
}
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
@@ -1035,7 +1232,7 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
context->save();
saved = true;
}
- context->setAlpha(1);
+ context->setAlphaAsFloat(1);
}
if (state().m_globalComposite != CompositeSourceOver) {
if (!saved) {
@@ -1048,6 +1245,7 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
if (saved)
context->restore();
+ validateStateStack();
didDraw(dirtyRect);
}
@@ -1062,7 +1260,7 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
if (!state().m_invertibleCTM)
return;
FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+ if (!c->getTransformedClipBounds(&clipBounds))
return;
// from the HTML5 Canvas spec:
@@ -1105,6 +1303,9 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
return;
if (!state().m_invertibleCTM)
return;
+ FloatRect clipBounds;
+ if (!c->getTransformedClipBounds(&clipBounds))
+ return;
// If gradient size is zero, then paint nothing.
Gradient* gradient = c->strokeGradient();
@@ -1113,12 +1314,21 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
FloatRect rect(x, y, width, height);
- FloatRect boundingRect = rect;
- boundingRect.inflate(state().m_lineWidth / 2);
- FloatRect dirtyRect;
- if (computeDirtyRect(boundingRect, &dirtyRect)) {
- c->strokeRect(rect, state().m_lineWidth);
- didDraw(dirtyRect);
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedStroke(rect);
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->strokeRect(rect);
+ didDraw(clipBounds);
+ } else {
+ FloatRect boundingRect = rect;
+ boundingRect.inflate(state().m_lineWidth / 2);
+ FloatRect dirtyRect;
+ if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) {
+ c->strokeRect(rect);
+ didDraw(dirtyRect);
+ }
}
}
@@ -1190,7 +1400,7 @@ void CanvasRenderingContext2D::applyShadow()
if (shouldDrawShadows()) {
c->setShadow(state().m_shadowOffset, state().m_shadowBlur, state().m_shadowColor,
- DrawLooper::ShadowIgnoresTransforms);
+ DrawLooperBuilder::ShadowIgnoresTransforms);
} else {
c->clearShadow();
}
@@ -1201,37 +1411,12 @@ bool CanvasRenderingContext2D::shouldDrawShadows() const
return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !state().m_shadowOffset.isZero());
}
-enum ImageSizeType {
- ImageSizeAfterDevicePixelRatio,
- ImageSizeBeforeDevicePixelRatio
-};
-
-static LayoutSize sizeFor(HTMLImageElement* image, ImageSizeType sizeType)
-{
- LayoutSize size;
- ImageResource* cachedImage = image->cachedImage();
- if (cachedImage) {
- size = cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
-
- if (sizeType == ImageSizeAfterDevicePixelRatio && image->renderer() && image->renderer()->isRenderImage() && cachedImage->image() && !cachedImage->image()->hasRelativeWidth())
- size.scale(toRenderImage(image->renderer())->imageDevicePixelRatio());
- }
- return size;
-}
-
-static IntSize sizeFor(HTMLVideoElement* video)
-{
- if (MediaPlayer* player = video->player())
- return player->naturalSize();
- return IntSize();
-}
-
static inline FloatRect normalizeRect(const FloatRect& rect)
{
- return FloatRect(min(rect.x(), rect.maxX()),
- min(rect.y(), rect.maxY()),
- max(rect.width(), -rect.width()),
- max(rect.height(), -rect.height()));
+ return FloatRect(std::min(rect.x(), rect.maxX()),
+ std::min(rect.y(), rect.maxY()),
+ std::max(rect.width(), -rect.width()),
+ std::max(rect.height(), -rect.height()));
}
static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* srcRect, FloatRect* dstRect)
@@ -1253,363 +1438,110 @@ static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s
dstRect->move(offset);
}
-void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode)
-{
- if (!image)
- return;
-
- GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
- FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
- return;
-
- if (rectContainsTransformedRect(dstRect, clipBounds)) {
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(clipBounds);
- } else if (isFullCanvasCompositeMode(op)) {
- fullCanvasCompositedDrawImage(image, dstRect, srcRect, op);
- didDraw(clipBounds);
- } else if (op == CompositeCopy) {
- clearCanvas();
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(clipBounds);
- } else {
- FloatRect dirtyRect;
- if (computeDirtyRect(dstRect, &dirtyRect)) {
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(dirtyRect);
- }
- }
-}
-
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, float x, float y, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, float x, float y, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- drawImage(bitmap, x, y, bitmap->width(), bitmap->height(), exceptionState);
+ FloatSize destRectSize = imageSource->defaultDestinationSize();
+ drawImage(imageSource, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
float x, float y, float width, float height, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- if (!bitmap->bitmapRect().width() || !bitmap->bitmapRect().height())
- return;
-
- drawImage(bitmap, 0, 0, bitmap->width(), bitmap->height(), x, y, width, height, exceptionState);
+ FloatSize sourceRectSize = imageSource->sourceSize();
+ drawImage(imageSource, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, width, height, exceptionState);
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
float sx, float sy, float sw, float sh,
float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- FloatRect srcRect(sx, sy, sw, sh);
- FloatRect dstRect(dx, dy, dw, dh);
- FloatRect bitmapRect = bitmap->bitmapRect();
-
- if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
- || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
- return;
-
- if (!dstRect.width() || !dstRect.height())
- return;
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
- }
-
- ASSERT(bitmap->height() && bitmap->width());
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- // Clip the rects to where the user thinks that the image is situated.
- clipRectsToImageRect(IntRect(IntPoint(), bitmap->size()), &normalizedSrcRect, &normalizedDstRect);
-
- FloatRect intersectRect = intersection(bitmapRect, normalizedSrcRect);
- FloatRect actualSrcRect(intersectRect);
-
- IntPoint bitmapOffset = bitmap->bitmapOffset();
- actualSrcRect.move(bitmapOffset - bitmapRect.location());
- FloatRect imageRect = FloatRect(bitmapOffset, bitmapRect.size());
-
- FloatRect actualDstRect(FloatPoint(intersectRect.location() - normalizedSrcRect.location()), bitmapRect.size());
- actualDstRect.scale(normalizedDstRect.width() / normalizedSrcRect.width() * intersectRect.width() / bitmapRect.width(),
- normalizedDstRect.height() / normalizedSrcRect.height() * intersectRect.height() / bitmapRect.height());
- actualDstRect.moveBy(normalizedDstRect.location());
-
- if (!imageRect.intersects(actualSrcRect))
- return;
-
- RefPtr<Image> imageForRendering = bitmap->bitmapImage();
- if (!imageForRendering)
- return;
-
- drawImageInternal(imageForRendering.get(), actualSrcRect, actualDstRect, state().m_globalComposite, state().m_globalBlend);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- LayoutSize destRectSize = sizeFor(image, ImageSizeAfterDevicePixelRatio);
- drawImage(image, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- LayoutSize sourceRectSize = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
- drawImage(image, FloatRect(0, 0, sourceRectSize.width(), sourceRectSize.height()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
-{
- drawImage(image, srcRect, dstRect, state().m_globalComposite, state().m_globalBlend, exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
- || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
- return;
-
- ImageResource* cachedImage = image->cachedImage();
- if (!cachedImage || !image->complete())
- return;
-
- LayoutSize size = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
- if (!size.width() || !size.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- if (!dstRect.width() || !dstRect.height())
- return;
-
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- FloatRect imageRect = FloatRect(FloatPoint(), size);
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
- }
- if (!imageRect.intersects(normalizedSrcRect))
- return;
-
- clipRectsToImageRect(imageRect, &normalizedSrcRect, &normalizedDstRect);
-
- checkOrigin(image);
-
- Image* imageForRendering = cachedImage->imageForRenderer(image->renderer());
-
- // For images that depend on an unavailable container size, we need to fall back to the intrinsic
- // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage
- // FIXME: Without a specified image size this should resolve against the canvas element's size, see: crbug.com/230163.
- if (!image->renderer() && imageForRendering->usesContainerSize())
- imageForRendering->setContainerSize(imageForRendering->size());
-
- drawImageInternal(imageForRendering, normalizedSrcRect, normalizedDstRect, op, blendMode);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float x, float y, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, 0, 0, sourceCanvas->width(), sourceCanvas->height(), x, y, sourceCanvas->width(), sourceCanvas->height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, FloatRect(0, 0, sourceCanvas->width(), sourceCanvas->height()), FloatRect(x, y, width, height), exceptionState);
+ GraphicsContext* c = drawingContext(); // Do not exit yet if !c because we may need to throw exceptions first
+ CompositeOperator op = c ? c->compositeOperation() : CompositeSourceOver;
+ blink::WebBlendMode blendMode = c ? c->blendModeOperation() : blink::WebBlendModeNormal;
+ drawImageInternal(imageSource, sx, sy, sw, sh, dx, dy, dw, dh, exceptionState, op, blendMode);
}
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
+void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource,
float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
- const FloatRect& dstRect, ExceptionState& exceptionState)
-{
- if (!sourceCanvas) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size());
-
- if (!srcCanvasRect.width() || !srcCanvasRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
+ float dx, float dy, float dw, float dh, ExceptionState& exceptionState,
+ CompositeOperator op, blink::WebBlendMode blendMode)
+{
+ RefPtr<Image> image;
+ SourceImageStatus sourceImageStatus;
+ if (!imageSource->isVideoElement()) {
+ SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolatile : DontCopySourceImage; // Thunking for ==
+ image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus);
+ if (sourceImageStatus == UndecodableSourceImageStatus)
+ exceptionState.throwDOMException(InvalidStateError, "The HTMLImageElement provided is in the 'broken' state.");
+ if (!image || !image->width() || !image->height())
+ return;
}
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
- return;
-
- clipRectsToImageRect(srcCanvasRect, &normalizedSrcRect, &normalizedDstRect);
-
GraphicsContext* c = drawingContext();
if (!c)
return;
+
if (!state().m_invertibleCTM)
return;
- // FIXME: Do this through platform-independent GraphicsContext API.
- ImageBuffer* buffer = sourceCanvas->buffer();
- if (!buffer)
+ if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) || !std::isfinite(dh)
+ || !std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)
+ || !dw || !dh || !sw || !sh)
return;
FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+ if (!c->getTransformedClipBounds(&clipBounds))
return;
- checkOrigin(sourceCanvas);
+ FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh));
+ FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh));
- // 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 (sourceContext && sourceContext->is3d())
- sourceContext->paintRenderingResultsToCanvas();
+ clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &srcRect, &dstRect);
- if (rectContainsTransformedRect(normalizedDstRect, clipBounds)) {
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(clipBounds);
- } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite);
- didDraw(clipBounds);
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(clipBounds);
+ imageSource->adjustDrawRects(&srcRect, &dstRect);
+
+ if (srcRect.isEmpty())
+ return;
+
+ FloatRect dirtyRect = clipBounds;
+ if (imageSource->isVideoElement()) {
+ drawVideo(static_cast<HTMLVideoElement*>(imageSource), srcRect, dstRect);
+ computeDirtyRect(dstRect, clipBounds, &dirtyRect);
} else {
- FloatRect dirtyRect;
- if (computeDirtyRect(normalizedDstRect, clipBounds, &dirtyRect)) {
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(dirtyRect);
+ if (rectContainsTransformedRect(dstRect, clipBounds)) {
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+ } else if (isFullCanvasCompositeMode(op)) {
+ fullCanvasCompositedDrawImage(image.get(), dstRect, srcRect, op);
+ } else if (op == CompositeCopy) {
+ clearCanvas();
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+ } else {
+ FloatRect dirtyRect;
+ computeDirtyRect(dstRect, clipBounds, &dirtyRect);
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
}
- }
-
- // Flush canvas's ImageBuffer when drawImage from WebGL to HW accelerated 2d canvas
- if (sourceContext && sourceContext->is3d() && is2d() && isAccelerated() && canvas()->buffer())
- canvas()->buffer()->flush();
-}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionState& exceptionState)
-{
- if (!video) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
+ if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && canvas()->buffer())
+ canvas()->buffer()->flush();
}
- IntSize size = sizeFor(video);
- drawImage(video, x, y, size.width(), size.height(), exceptionState);
-}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- if (!video) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- IntSize size = sizeFor(video);
- drawImage(video, FloatRect(0, 0, size.width(), size.height()), FloatRect(x, y, width, height), exceptionState);
-}
+ if (canvas()->originClean() && wouldTaintOrigin(imageSource))
+ canvas()->setOriginTainted();
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
+ didDraw(dirtyRect);
}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::drawVideo(HTMLVideoElement* video, FloatRect srcRect, FloatRect dstRect)
{
- if (!video) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA)
- return;
-
- FloatRect videoRect = FloatRect(FloatPoint(), sizeFor(video));
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
- }
-
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- if (!videoRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
- return;
-
- clipRectsToImageRect(videoRect, &normalizedSrcRect, &normalizedDstRect);
-
GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
-
- checkOrigin(video);
-
- FloatRect dirtyRect;
- if (!computeDirtyRect(normalizedDstRect, &dirtyRect))
- return;
-
GraphicsContextStateSaver stateSaver(*c);
- c->clip(normalizedDstRect);
- c->translate(normalizedDstRect.x(), normalizedDstRect.y());
- c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), normalizedDstRect.height() / normalizedSrcRect.height()));
- c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y());
- video->paintCurrentFrameInContext(c, IntRect(IntPoint(), sizeFor(video)));
+ c->clip(dstRect);
+ c->translate(dstRect.x(), dstRect.y());
+ c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height());
+ c->translate(-srcRect.x(), -srcRect.y());
+ video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())));
stateSaver.restore();
-
- didDraw(dirtyRect);
+ validateStateStack();
}
void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
@@ -1617,12 +1549,14 @@ void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
float dx, float dy, float dw, float dh,
const String& compositeOperation)
{
+ if (!image)
+ return;
CompositeOperator op;
blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blendOp != blink::WebBlendModeNormal)
op = CompositeSourceOver;
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, blink::WebBlendModeNormal, IGNORE_EXCEPTION);
+ drawImageInternal(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION, op, blendOp);
}
void CanvasRenderingContext2D::setAlpha(float alpha)
@@ -1660,18 +1594,14 @@ static void drawImageToContext(Image* image, GraphicsContext* context, const Flo
context->drawImage(image, dest, src, op);
}
-static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
-{
- context->drawImageBuffer(imageBuffer, dest, src, op);
-}
-
template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
ASSERT(isFullCanvasCompositeMode(op));
- drawingContext()->beginLayer(1, op);
- drawImageToContext(image, drawingContext(), dest, src, CompositeSourceOver);
- drawingContext()->endLayer();
+ GraphicsContext* c = drawingContext();
+ c->beginLayer(1, op);
+ drawImageToContext(image, c, dest, src, CompositeSourceOver);
+ c->endLayer();
}
static void fillPrimitive(const FloatRect& rect, GraphicsContext* context)
@@ -1698,78 +1628,82 @@ template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const
c->endLayer();
}
-PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState& exceptionState)
+static void strokePrimitive(const FloatRect& rect, GraphicsContext* context)
{
- if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(x1) || !std::isfinite(y1)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
+ context->strokeRect(rect);
+}
+
+static void strokePrimitive(const Path& path, GraphicsContext* context)
+{
+ context->strokePath(path);
+}
+template<class T> void CanvasRenderingContext2D::fullCanvasCompositedStroke(const T& area)
+{
+ ASSERT(isFullCanvasCompositeMode(state().m_globalComposite));
+
+ GraphicsContext* c = drawingContext();
+ ASSERT(c);
+ c->beginLayer(1, state().m_globalComposite);
+ CompositeOperator previousOperator = c->compositeOperation();
+ c->setCompositeOperation(CompositeSourceOver);
+ strokePrimitive(area, c);
+ c->setCompositeOperation(previousOperator);
+ c->endLayer();
+}
+
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
+{
RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
return gradient.release();
}
PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState& exceptionState)
{
- if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(r0) || !std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(r1)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
-
if (r0 < 0 || r1 < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
+ exceptionState.throwDOMException(IndexSizeError, String::format("The %s provided is less than 0.", r0 < 0 ? "r0" : "r1"));
+ return nullptr;
}
RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
return gradient.release();
}
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(CanvasImageSource* imageSource,
const String& repetitionType, ExceptionState& exceptionState)
{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
- }
bool repeatX, repeatY;
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
if (exceptionState.hadException())
- return 0;
-
- if (!image->complete())
- return 0;
-
- ImageResource* cachedImage = image->cachedImage();
- Image* imageForRendering = cachedImage ? cachedImage->imageForRenderer(image->renderer()) : 0;
- if (!imageForRendering)
- return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
+ return nullptr;
- // We need to synthesize a container size if a renderer is not available to provide one.
- if (!image->renderer() && imageForRendering->usesContainerSize())
- imageForRendering->setContainerSize(imageForRendering->size());
+ SourceImageStatus status;
+ RefPtr<Image> imageForRendering = imageSource->getSourceImageForCanvas(CopySourceImageIfVolatile, &status);
- bool originClean = cachedImage->isAccessAllowed(canvas()->securityOrigin());
- return CanvasPattern::create(imageForRendering, repeatX, repeatY, originClean);
-}
-
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
- const String& repetitionType, ExceptionState& exceptionState)
-{
- if (!canvas) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
- }
- if (!canvas->width() || !canvas->height()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return 0;
+ switch (status) {
+ case NormalSourceImageStatus:
+ break;
+ case ZeroSizeCanvasSourceImageStatus:
+ exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", imageSource->sourceSize().width() ? "height" : "width"));
+ return nullptr;
+ case UndecodableSourceImageStatus:
+ exceptionState.throwDOMException(InvalidStateError, "Source image is in the 'broken' state.");
+ return nullptr;
+ case InvalidSourceImageStatus:
+ imageForRendering = Image::nullImage();
+ break;
+ case IncompleteSourceImageStatus:
+ return nullptr;
+ default:
+ case ExternalSourceImageStatus: // should not happen when mode is CopySourceImageIfVolatile
+ ASSERT_NOT_REACHED();
+ return nullptr;
}
+ ASSERT(imageForRendering);
- bool repeatX, repeatY;
- CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
- if (exceptionState.hadException())
- return 0;
- return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+ bool originClean = !wouldTaintOrigin(imageSource);
+
+ return CanvasPattern::create(imageForRendering.release(), repeatX, repeatY, originClean);
}
bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, FloatRect* dirtyRect)
@@ -1822,46 +1756,36 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& dirtyRect)
GraphicsContext* CanvasRenderingContext2D::drawingContext() const
{
+ if (isContextLost())
+ return 0;
return canvas()->drawingContext();
}
-static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
+static PassRefPtrWillBeRawPtr<ImageData> createEmptyImageData(const IntSize& size)
{
- Checked<int, RecordOverflow> dataSize = 4;
- dataSize *= size.width();
- dataSize *= size.height();
- if (dataSize.hasOverflowed())
- return 0;
+ if (RefPtrWillBeRawPtr<ImageData> data = ImageData::create(size)) {
+ data->data()->zeroFill();
+ return data.release();
+ }
- RefPtr<ImageData> data = ImageData::create(size);
- data->data()->zeroFill();
- return data.release();
+ return nullptr;
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtrWillBeRawPtr<ImageData> imageData) const
{
- if (!imageData) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
-
return createEmptyImageData(imageData->size());
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionState& exceptionState) const
{
if (!sw || !sh) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
- }
- if (!std::isfinite(sw) || !std::isfinite(sh)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
+ return nullptr;
}
FloatSize logicalSize(fabs(sw), fabs(sh));
if (!logicalSize.isExpressibleAsIntSize())
- return 0;
+ return nullptr;
IntSize size = expandedIntSize(logicalSize);
if (size.width() < 1)
@@ -1872,26 +1796,15 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float
return createEmptyImageData(size);
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionState& exceptionState) const
{
- return getImageData(sx, sy, sw, sh, exceptionState);
-}
-
-PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionState& exceptionState) const
-{
- if (!canvas()->originClean()) {
+ if (!canvas()->originClean())
exceptionState.throwSecurityError("The canvas has been tainted by cross-origin data.");
- return 0;
- }
+ else if (!sw || !sh)
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
- if (!sw || !sh) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
- }
- if (!std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
+ if (exceptionState.hadException())
+ return nullptr;
if (sw < 0) {
sx += sw;
@@ -1908,41 +1821,27 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy,
if (logicalRect.height() < 1)
logicalRect.setHeight(1);
if (!logicalRect.isExpressibleAsIntRect())
- return 0;
+ return nullptr;
IntRect imageDataRect = enclosingIntRect(logicalRect);
ImageBuffer* buffer = canvas()->buffer();
- if (!buffer)
+ if (!buffer || isContextLost())
return createEmptyImageData(imageDataRect.size());
RefPtr<Uint8ClampedArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect);
if (!byteArray)
- return 0;
+ return nullptr;
return ImageData::create(imageDataRect.size(), byteArray.release());
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy)
{
- if (!data) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- putImageData(data, dx, dy, 0, 0, data->width(), data->height(), exceptionState);
+ putImageData(data, dx, dy, 0, 0, data->width(), data->height());
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY,
- float dirtyWidth, float dirtyHeight, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
{
- if (!data) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dirtyX) || !std::isfinite(dirtyY) || !std::isfinite(dirtyWidth) || !std::isfinite(dirtyHeight)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
ImageBuffer* buffer = canvas()->buffer();
if (!buffer)
return;
@@ -1981,11 +1880,11 @@ String CanvasRenderingContext2D::font() const
StringBuilder serializedFont;
const FontDescription& fontDescription = state().m_font.fontDescription();
- if (fontDescription.italic())
+ if (fontDescription.style() == FontStyleItalic)
serializedFont.appendLiteral("italic ");
if (fontDescription.weight() == FontWeightBold)
serializedFont.appendLiteral("bold ");
- if (fontDescription.smallCaps() == FontSmallCapsOn)
+ if (fontDescription.variant() == FontVariantSmallCaps)
serializedFont.appendLiteral("small-caps ");
serializedFont.appendNumber(fontDescription.computedPixelSize());
@@ -2012,13 +1911,17 @@ String CanvasRenderingContext2D::font() const
void CanvasRenderingContext2D::setFont(const String& newFont)
{
+ // The style resolution required for rendering text is not available in frame-less documents.
+ if (!canvas()->document().frame())
+ return;
+
MutableStylePropertyMap::iterator i = m_fetchedFonts.find(newFont);
- RefPtr<MutableStylePropertySet> parsedStyle = i != m_fetchedFonts.end() ? i->value : 0;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> parsedStyle = i != m_fetchedFonts.end() ? i->value : nullptr;
if (!parsedStyle) {
parsedStyle = MutableStylePropertySet::create();
CSSParserMode mode = m_usesCSSCompatibilityParseMode ? HTMLQuirksMode : HTMLStandardMode;
- CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, mode, 0);
+ BisonCSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, mode, 0);
m_fetchedFonts.add(newFont, parsedStyle);
}
if (parsedStyle->isEmpty())
@@ -2039,9 +1942,12 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
// Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
// relative to the canvas.
RefPtr<RenderStyle> newStyle = RenderStyle::create();
- if (RenderStyle* computedStyle = canvas()->computedStyle())
- newStyle->setFontDescription(computedStyle->fontDescription());
- else {
+ if (RenderStyle* computedStyle = canvas()->computedStyle()) {
+ FontDescription elementFontDescription(computedStyle->fontDescription());
+ // Reset the computed size to avoid inheriting the zoom factor from the <canvas> element.
+ elementFontDescription.setComputedSize(elementFontDescription.specifiedSize());
+ newStyle->setFontDescription(elementFontDescription);
+ } else {
FontFamily fontFamily;
fontFamily.setFamily(defaultFontFamily);
@@ -2068,8 +1974,10 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
StyleResolver& styleResolver = canvas()->document().ensureStyleResolver();
styleResolver.applyPropertiesToStyle(properties, WTF_ARRAY_LENGTH(properties), newStyle.get());
+#if !ENABLE(OILPAN)
if (state().m_realizedFont)
- state().m_font.fontSelector()->unregisterForInvalidationCallbacks(&modifiableState());
+ static_cast<CSSFontSelector*>(state().m_font.fontSelector())->unregisterForInvalidationCallbacks(&modifiableState());
+#endif
modifiableState().m_font = newStyle->font();
modifiableState().m_font.update(canvas()->document().styleEngine()->fontSelector());
modifiableState().m_realizedFont = true;
@@ -2128,31 +2036,84 @@ void CanvasRenderingContext2D::strokeText(const String& text, float x, float y,
drawTextInternal(text, x, y, false, maxWidth, true);
}
-PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+static inline bool isSpaceCharacter(UChar c)
{
- FontCachePurgePreventer fontCachePurgePreventer;
- RefPtr<TextMetrics> metrics = TextMetrics::create();
- canvas()->document().updateStyleIfNeeded();
- metrics->setWidth(accessFont().width(TextRun(text)));
- return metrics.release();
+ // According to specification all space characters should be replaced with 0x0020 space character.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-preparation-algorithm
+ // The space characters according to specification are : U+0020, U+0009, U+000A, U+000C, and U+000D.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#space-character
+ // This function returns true for 0x000B also, so that this is backward compatible.
+ // Otherwise, the test LayoutTests/canvas/philip/tests/2d.text.draw.space.collapse.space.html will fail
+ return c == 0x0009 || c == 0x000A || c == 0x000B || c == 0x000C || c == 0x000D;
}
-static void replaceCharacterInString(String& text, WTF::CharacterMatchFunctionPtr matchFunction, const String& replacement)
+static String normalizeSpaces(const String& text)
{
- const size_t replacementLength = replacement.length();
- size_t index = 0;
- while ((index = text.find(matchFunction, index)) != kNotFound) {
- text.replace(index, 1, replacement);
- index += replacementLength;
+ unsigned textLength = text.length();
+ Vector<UChar> charVector(textLength);
+
+ for (unsigned i = 0; i < textLength; i++) {
+ if (isSpaceCharacter(text[i]))
+ charVector[i] = ' ';
+ else
+ charVector[i] = text[i];
}
+
+ return String(charVector);
+}
+
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+{
+ RefPtr<TextMetrics> metrics = TextMetrics::create();
+
+ // The style resolution required for rendering text is not available in frame-less documents.
+ if (!canvas()->document().frame())
+ return metrics.release();
+
+ FontCachePurgePreventer fontCachePurgePreventer;
+ canvas()->document().updateRenderTreeIfNeeded();
+ const Font& font = accessFont();
+ String normalizedText = normalizeSpaces(text);
+ const TextRun textRun(normalizedText);
+ FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font.fontDescription().computedSize(), 0, -1, true);
+
+ // x direction
+ metrics->setWidth(font.width(textRun));
+ metrics->setActualBoundingBoxLeft(-textBounds.x());
+ metrics->setActualBoundingBoxRight(textBounds.maxX());
+
+ // y direction
+ const FontMetrics& fontMetrics = font.fontMetrics();
+ const float ascent = fontMetrics.floatAscent();
+ const float descent = fontMetrics.floatDescent();
+ const float baselineY = getFontBaseline(fontMetrics);
+
+ metrics->setFontBoundingBoxAscent(ascent - baselineY);
+ metrics->setFontBoundingBoxDescent(descent + baselineY);
+ metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY);
+ metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY);
+
+ // Note : top/bottom and ascend/descend are currently the same, so there's no difference
+ // between the EM box's top and bottom and the font's ascend and descend
+ metrics->setEmHeightAscent(0);
+ metrics->setEmHeightDescent(0);
+
+ metrics->setHangingBaseline(-0.8f * ascent + baselineY);
+ metrics->setAlphabeticBaseline(baselineY);
+ metrics->setIdeographicBaseline(descent + baselineY);
+ return metrics.release();
}
void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
{
+ // The style resolution required for rendering text is not available in frame-less documents.
+ if (!canvas()->document().frame())
+ return;
+
// accessFont needs the style to be up to date, but updating style can cause script to run,
// (e.g. due to autofocus) which can free the GraphicsContext, so update style before grabbing
// the GraphicsContext.
- canvas()->document().updateStyleIfNeeded();
+ canvas()->document().updateRenderTreeIfNeeded();
GraphicsContext* c = drawingContext();
if (!c)
@@ -2177,9 +2138,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
const Font& font = accessFont();
const FontMetrics& fontMetrics = font.fontMetrics();
- // According to spec, all the space characters must be replaced with U+0020 SPACE characters.
- String normalizedText = text;
- replaceCharacterInString(normalizedText, isSpaceOrNewline, " ");
+ String normalizedText = normalizeSpaces(text);
// FIXME: Need to turn off font smoothing.
@@ -2190,24 +2149,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override, true, TextRun::NoRounding);
// Draw the item text at the correct point.
- FloatPoint location(x, y);
- switch (state().m_textBaseline) {
- case TopTextBaseline:
- case HangingTextBaseline:
- location.setY(y + fontMetrics.ascent());
- break;
- case BottomTextBaseline:
- case IdeographicTextBaseline:
- location.setY(y - fontMetrics.descent());
- break;
- case MiddleTextBaseline:
- location.setY(y - fontMetrics.descent() + fontMetrics.height() / 2);
- break;
- case AlphabeticTextBaseline:
- default:
- // Do nothing.
- break;
- }
+ FloatPoint location(x, y + getFontBaseline(fontMetrics));
float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override));
@@ -2240,21 +2182,40 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
if (!fill)
inflateStrokeRect(textRunPaintInfo.bounds);
- FloatRect dirtyRect;
- if (!computeDirtyRect(textRunPaintInfo.bounds, &dirtyRect))
- return;
-
c->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+
+ GraphicsContextStateSaver stateSaver(*c);
if (useMaxWidth) {
- GraphicsContextStateSaver stateSaver(*c);
c->translate(location.x(), location.y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
- c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
- c->drawBidiText(font, textRunPaintInfo, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
- } else
- c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ c->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1);
+ location = FloatPoint();
+ }
- didDraw(dirtyRect);
+ FloatRect clipBounds;
+ if (!c->getTransformedClipBounds(&clipBounds)) {
+ return;
+ }
+
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ c->beginLayer(1, state().m_globalComposite);
+ CompositeOperator previousOperator = c->compositeOperation();
+ c->setCompositeOperation(CompositeSourceOver);
+ c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ c->setCompositeOperation(previousOperator);
+ c->endLayer();
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ didDraw(clipBounds);
+ } else {
+ FloatRect dirtyRect;
+ if (computeDirtyRect(textRunPaintInfo.bounds, clipBounds, &dirtyRect)) {
+ c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ didDraw(dirtyRect);
+ }
+ }
}
void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
@@ -2281,6 +2242,28 @@ const Font& CanvasRenderingContext2D::accessFont()
return state().m_font;
}
+int CanvasRenderingContext2D::getFontBaseline(const FontMetrics& fontMetrics) const
+{
+ switch (state().m_textBaseline) {
+ case TopTextBaseline:
+ return fontMetrics.ascent();
+ case HangingTextBaseline:
+ // According to http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
+ // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of the ascender height"
+ return (fontMetrics.ascent() * 4) / 5;
+ case BottomTextBaseline:
+ case IdeographicTextBaseline:
+ return -fontMetrics.descent();
+ case MiddleTextBaseline:
+ return -fontMetrics.descent() + fontMetrics.height() / 2;
+ case AlphabeticTextBaseline:
+ default:
+ // Do nothing.
+ break;
+ }
+ return 0;
+}
+
blink::WebLayer* CanvasRenderingContext2D::platformLayer() const
{
return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
@@ -2300,7 +2283,7 @@ void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
modifiableState().m_imageSmoothingEnabled = enabled;
GraphicsContext* c = drawingContext();
if (c)
- c->setImageInterpolationQuality(enabled ? DefaultInterpolationQuality : InterpolationNone);
+ c->setImageInterpolationQuality(enabled ? CanvasDefaultInterpolationQuality : InterpolationNone);
}
PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttributes() const
@@ -2310,33 +2293,31 @@ PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttrib
return attributes.release();
}
-void CanvasRenderingContext2D::drawSystemFocusRing(Element* element)
+void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element)
+{
+ drawFocusIfNeededInternal(m_path, element);
+}
+
+void CanvasRenderingContext2D::drawFocusIfNeeded(Path2D* path2d, Element* element)
{
- if (!focusRingCallIsValid(m_path, element))
+ drawFocusIfNeededInternal(path2d->path(), element);
+}
+
+void CanvasRenderingContext2D::drawFocusIfNeededInternal(const Path& path, Element* element)
+{
+ if (!focusRingCallIsValid(path, element))
return;
- updateFocusRingAccessibility(m_path, element);
// Note: we need to check document->focusedElement() rather than just calling
// element->focused(), because element->focused() isn't updated until after
// focus events fire.
if (element->document().focusedElement() == element)
- drawFocusRing(m_path);
-}
-
-bool CanvasRenderingContext2D::drawCustomFocusRing(Element* element)
-{
- if (!focusRingCallIsValid(m_path, element))
- return false;
-
- updateFocusRingAccessibility(m_path, element);
-
- // Return true if the application should draw the focus ring. The spec allows us to
- // override this for accessibility, but currently Blink doesn't take advantage of this.
- return element->focused();
+ drawFocusRing(path);
}
bool CanvasRenderingContext2D::focusRingCallIsValid(const Path& path, Element* element)
{
+ ASSERT(element);
if (!state().m_invertibleCTM)
return false;
if (path.isEmpty())
@@ -2347,62 +2328,32 @@ bool CanvasRenderingContext2D::focusRingCallIsValid(const Path& path, Element* e
return true;
}
-void CanvasRenderingContext2D::updateFocusRingAccessibility(const Path& path, Element* element)
-{
- if (!canvas()->renderer())
- return;
-
- // If accessibility is already enabled in this frame, associate this path's
- // bounding box with the accessible object. Do this even if the element
- // isn't focused because assistive technology might try to explore the object's
- // location before it gets focus.
- if (AXObjectCache* axObjectCache = element->document().existingAXObjectCache()) {
- if (AXObject* obj = axObjectCache->getOrCreate(element)) {
- // Get the bounding rect and apply transformations.
- FloatRect bounds = m_path.boundingRect();
- AffineTransform ctm = state().m_transform;
- FloatRect transformedBounds = ctm.mapRect(bounds);
- LayoutRect elementRect = LayoutRect(transformedBounds);
-
- // Offset by the canvas rect and set the bounds of the accessible element.
- IntRect canvasRect = canvas()->renderer()->absoluteBoundingBoxRect();
- elementRect.moveBy(canvasRect.location());
- obj->setElementRect(elementRect);
-
- // Set the bounds of any ancestor accessible elements, up to the canvas element,
- // otherwise this element will appear to not be within its parent element.
- obj = obj->parentObject();
- while (obj && obj->node() != canvas()) {
- obj->setElementRect(elementRect);
- obj = obj->parentObject();
- }
- }
- }
-}
-
void CanvasRenderingContext2D::drawFocusRing(const Path& path)
{
GraphicsContext* c = drawingContext();
if (!c)
return;
+ // These should match the style defined in html.css.
+ Color focusRingColor = RenderTheme::theme().focusRingColor();
+ const int focusRingWidth = 5;
+ const int focusRingOutline = 0;
+
+ // We need to add focusRingWidth to dirtyRect.
+ StrokeData strokeData;
+ strokeData.setThickness(focusRingWidth);
+
FloatRect dirtyRect;
- if (!computeDirtyRect(path.boundingRect(), &dirtyRect))
+ if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect))
return;
c->save();
- c->setAlpha(1.0);
+ c->setAlphaAsFloat(1.0);
c->clearShadow();
c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
-
- // These should match the style defined in html.css.
- Color focusRingColor = RenderTheme::focusRingColor();
- const int focusRingWidth = 5;
- const int focusRingOutline = 0;
c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor);
-
c->restore();
-
+ validateStateStack();
didDraw(dirtyRect);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h
index 8493b10b149..65d883d220c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h
@@ -26,10 +26,12 @@
#ifndef CanvasRenderingContext2D_h
#define CanvasRenderingContext2D_h
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/css/CSSFontSelectorClient.h"
#include "core/html/canvas/Canvas2DContextAttributes.h"
#include "core/html/canvas/CanvasPathMethods.h"
#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/svg/SVGMatrix.h"
+#include "core/svg/SVGMatrixTearOff.h"
#include "platform/fonts/Font.h"
#include "platform/graphics/Color.h"
#include "platform/geometry/FloatSize.h"
@@ -45,10 +47,11 @@ namespace blink { class WebLayer; }
namespace WebCore {
+class CanvasImageSource;
class CanvasGradient;
class CanvasPattern;
class CanvasStyle;
-class DOMPath;
+class Path2D;
class Element;
class ExceptionState;
class FloatRect;
@@ -60,13 +63,13 @@ class ImageBitmap;
class ImageData;
class TextMetrics;
-typedef HashMap<String, RefPtr<MutableStylePropertySet> > MutableStylePropertyMap;
+typedef WillBeHeapHashMap<String, RefPtrWillBeMember<MutableStylePropertySet> > MutableStylePropertyMap;
-class CanvasRenderingContext2D : public CanvasRenderingContext, public CanvasPathMethods {
+class CanvasRenderingContext2D FINAL: public CanvasRenderingContext, public ScriptWrappable, public CanvasPathMethods {
public:
- static PassOwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
+ static PassOwnPtrWillBeRawPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
{
- return adoptPtr(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode));
+ return adoptPtrWillBeNoop(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode));
}
virtual ~CanvasRenderingContext2D();
@@ -90,12 +93,9 @@ public:
const Vector<float>& getLineDash() const;
void setLineDash(const Vector<float>&);
- void setWebkitLineDash(const Vector<float>&);
float lineDashOffset() const;
void setLineDashOffset(float);
- float webkitLineDashOffset() const;
- void setWebkitLineDashOffset(float);
float shadowOffsetX() const;
void setShadowOffsetX(float);
@@ -112,17 +112,19 @@ public:
float globalAlpha() const;
void setGlobalAlpha(float);
+ bool isContextLost() const;
+
String globalCompositeOperation() const;
void setGlobalCompositeOperation(const String&);
- void save() { ++m_unrealizedSaveCount; }
+ void save() { ++m_stateStack.last()->m_unrealizedSaveCount; }
void restore();
- SVGMatrix currentTransform() const
+ PassRefPtr<SVGMatrixTearOff> currentTransform() const
{
- return SVGMatrix(state().m_transform);
+ return SVGMatrixTearOff::create(state().m_transform);
}
- void setCurrentTransform(const SVGMatrix&);
+ void setCurrentTransform(PassRefPtr<SVGMatrixTearOff>);
void scale(float sx, float sy);
void rotate(float angleInRadians);
@@ -147,14 +149,20 @@ public:
void beginPath();
- PassRefPtr<DOMPath> currentPath();
- void setCurrentPath(DOMPath*);
void fill(const String& winding = "nonzero");
+ void fill(Path2D*, const String& winding = "nonzero");
void stroke();
+ void stroke(Path2D*);
void clip(const String& winding = "nonzero");
+ void clip(Path2D*, const String& winding = "nonzero");
bool isPointInPath(const float x, const float y, const String& winding = "nonzero");
+ bool isPointInPath(Path2D*, const float x, const float y, const String& winding = "nonzero");
bool isPointInStroke(const float x, const float y);
+ bool isPointInStroke(Path2D*, const float x, const float y);
+
+ void scrollPathIntoView();
+ void scrollPathIntoView(Path2D*);
void clearRect(float x, float y, float width, float height);
void fillRect(float x, float y, float width, float height);
@@ -170,22 +178,9 @@ public:
void clearShadow();
- void drawImage(ImageBitmap*, float x, float y, ExceptionState&);
- void drawImage(ImageBitmap*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(ImageBitmap*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLImageElement*, float x, float y, ExceptionState&);
- void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
- void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const blink::WebBlendMode&, ExceptionState&);
- void drawImage(HTMLCanvasElement*, float x, float y, ExceptionState&);
- void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
- void drawImage(HTMLVideoElement*, float x, float y, ExceptionState&);
- void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
+ void drawImage(CanvasImageSource*, float x, float y, ExceptionState&);
+ void drawImage(CanvasImageSource*, float x, float y, float width, float height, ExceptionState&);
+ void drawImage(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
@@ -194,22 +189,15 @@ public:
void setCompositeOperation(const String&);
- PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState&);
+ PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1);
PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState&);
- PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionState&);
- PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionState&);
+ PassRefPtr<CanvasPattern> createPattern(CanvasImageSource*, const String& repetitionType, ExceptionState&);
- PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData>, ExceptionState&) const;
- PassRefPtr<ImageData> createImageData(float width, float height, ExceptionState&) const;
- PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const;
- void putImageData(ImageData*, float dx, float dy, ExceptionState&);
- void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState&);
-
- // Slated for deprecation:
- void webkitPutImageDataHD(ImageData* image, float dx, float dy, ExceptionState& e) { putImageData(image, dx, dy, e); }
- void webkitPutImageDataHD(ImageData* image, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState& e) { putImageData(image, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight, e); }
- PassRefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionState&) const;
- float webkitBackingStorePixelRatio() const { return 1; }
+ PassRefPtrWillBeRawPtr<ImageData> createImageData(PassRefPtrWillBeRawPtr<ImageData>) const;
+ PassRefPtrWillBeRawPtr<ImageData> createImageData(float width, float height, ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const;
+ void putImageData(ImageData*, float dx, float dy);
+ void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
void reset();
@@ -236,18 +224,29 @@ public:
PassRefPtr<Canvas2DContextAttributes> getContextAttributes() const;
- void drawSystemFocusRing(Element*);
- bool drawCustomFocusRing(Element*);
+ void drawFocusIfNeeded(Element*);
+ void drawFocusIfNeeded(Path2D*, Element*);
+
+ void loseContext();
+ void restoreContext();
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- struct State : FontSelectorClient {
+ class State FINAL : public CSSFontSelectorClient {
+ public:
State();
virtual ~State();
State(const State&);
State& operator=(const State&);
- virtual void fontsNeedUpdate(FontSelector*) OVERRIDE;
+ // CSSFontSelectorClient implementation
+ virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE;
+
+ virtual void trace(Visitor* visitor) OVERRIDE { CSSFontSelectorClient::trace(visitor); }
+
+ unsigned m_unrealizedSaveCount;
String m_unparsedStrokeColor;
String m_unparsedFillColor;
@@ -280,15 +279,18 @@ private:
CanvasRenderingContext2D(HTMLCanvasElement*, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode);
- State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); }
- const State& state() const { return m_stateStack.last(); }
+ State& modifiableState() { ASSERT(!state().m_unrealizedSaveCount); return *m_stateStack.last(); }
+ const State& state() const { return *m_stateStack.last(); }
void applyLineDash() const;
void setShadow(const FloatSize& offset, float blur, RGBA32 color);
void applyShadow();
bool shouldDrawShadows() const;
- void drawImageInternal(Image*, const FloatRect&, const FloatRect&, const CompositeOperator&, const blink::WebBlendMode&);
+ void dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*);
+ void dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*);
+ void tryRestoreContextEvent(Timer<CanvasRenderingContext2D>*);
+
bool computeDirtyRect(const FloatRect& localBounds, FloatRect*);
bool computeDirtyRect(const FloatRect& localBounds, const FloatRect& transformedClipBounds, FloatRect*);
void didDraw(const FloatRect&);
@@ -296,19 +298,27 @@ private:
GraphicsContext* drawingContext() const;
void unwindStateStack();
- void realizeSaves()
- {
- if (m_unrealizedSaveCount)
- realizeSavesLoop();
- }
- void realizeSavesLoop();
+ void realizeSaves();
void applyStrokePattern();
void applyFillPattern();
+ void drawImageInternal(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&, CompositeOperator, blink::WebBlendMode);
+ void drawVideo(HTMLVideoElement*, FloatRect srcRect, FloatRect dstRect);
+
+ void fillInternal(const Path&, const String& windingRuleString);
+ void strokeInternal(const Path&);
+ void clipInternal(const Path&, const String& windingRuleString);
+
+ bool isPointInPathInternal(const Path&, const float x, const float y, const String& windingRuleString);
+ bool isPointInStrokeInternal(const Path&, const float x, const float y);
+
+ void scrollPathIntoViewInternal(const Path&);
+
void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
const Font& accessFont();
+ int getFontBaseline(const FontMetrics&) const;
void clearCanvas();
bool rectContainsTransformedRect(const FloatRect&, const FloatRect&) const;
@@ -316,25 +326,34 @@ private:
void inflateStrokeRect(FloatRect&) const;
template<class T> void fullCanvasCompositedFill(const T&);
+ template<class T> void fullCanvasCompositedStroke(const T&);
template<class T> void fullCanvasCompositedDrawImage(T*, const FloatRect&, const FloatRect&, CompositeOperator);
+ void drawFocusIfNeededInternal(const Path&, Element*);
bool focusRingCallIsValid(const Path&, Element*);
- void updateFocusRingAccessibility(const Path&, Element*);
void drawFocusRing(const Path&);
+ void validateStateStack();
+
virtual bool is2d() const OVERRIDE { return true; }
virtual bool isAccelerated() const OVERRIDE;
virtual bool hasAlpha() const OVERRIDE { return m_hasAlpha; }
- virtual bool isTransformInvertible() const { return state().m_invertibleCTM; }
+ virtual bool isTransformInvertible() const OVERRIDE { return state().m_invertibleCTM; }
virtual blink::WebLayer* platformLayer() const OVERRIDE;
- Vector<State, 1> m_stateStack;
- unsigned m_unrealizedSaveCount;
+ WillBeHeapVector<OwnPtrWillBeMember<State> > m_stateStack;
bool m_usesCSSCompatibilityParseMode;
bool m_hasAlpha;
+ bool m_isContextLost;
+ bool m_contextRestorable;
+ Canvas2DContextStorage m_storageMode;
MutableStylePropertyMap m_fetchedFonts;
+ unsigned m_tryRestoreContextAttemptCount;
+ Timer<CanvasRenderingContext2D> m_dispatchContextLostEventTimer;
+ Timer<CanvasRenderingContext2D> m_dispatchContextRestoredEventTimer;
+ Timer<CanvasRenderingContext2D> m_tryRestoreContextEventTimer;
};
DEFINE_TYPE_CASTS(CanvasRenderingContext2D, CanvasRenderingContext, context, context->is2d(), context.is2d());
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl
index 1c243a6b4a0..1738af041a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl
@@ -23,154 +23,160 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-enum CanvasWindingRule { "nonzero", "evenodd" };
-
-interface CanvasRenderingContext2D : CanvasRenderingContext {
-
- void save();
- void restore();
-
- [RuntimeEnabled=ExperimentalCanvasFeatures, Immutable] attribute SVGMatrix currentTransform;
- void scale(float sx, float sy);
- void rotate(float angle);
- void translate(float tx, float ty);
- void transform(float m11, float m12, float m21, float m22, float dx, float dy);
- void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasrenderingcontext2d
+
+// FIXME: float => double throughout
+// FIXME: Use union type in drawImage and createPattern once supported:
+// http://crbug.com/372891
+typedef (HTMLImageElement or
+ HTMLVideoElement or
+ HTMLCanvasElement // or
+ // CanvasRenderingContext2D or
+ // ImageBitmap
+ ) CanvasImageSource;
+
+enum CanvasFillRule { "nonzero", "evenodd" };
+
+[
+ TypeChecking=Interface|Nullable|Unrestricted,
+ WillBeGarbageCollected,
+] interface CanvasRenderingContext2D {
+ // back-reference to the canvas
+ readonly attribute HTMLCanvasElement canvas;
+
+ // state
+ void save(); // push state on state stack
+ void restore(); // pop state stack and restore state
+
+ // transformations (default transform is the identity matrix)
+ [RuntimeEnabled=ExperimentalCanvasFeatures] attribute SVGMatrix currentTransform;
+ void scale(unrestricted float x, unrestricted float y);
+ void rotate(unrestricted float angle);
+ void translate(unrestricted float x, unrestricted float y);
+ void transform(unrestricted float a, unrestricted float b, unrestricted float c, unrestricted float d, unrestricted float e, unrestricted float f);
+ void setTransform(unrestricted float a, unrestricted float b, unrestricted float c, unrestricted float d, unrestricted float e, unrestricted float f);
void resetTransform();
- attribute float globalAlpha;
- [TreatNullAs=NullString] attribute DOMString globalCompositeOperation;
+ // compositing
+ attribute unrestricted float globalAlpha; // (default 1.0)
+ [TreatNullAs=NullString] attribute DOMString globalCompositeOperation; // (default source-over)
- [RaisesException] CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
- [RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
-
- attribute float lineWidth;
- [TreatNullAs=NullString] attribute DOMString lineCap;
- [TreatNullAs=NullString] attribute DOMString lineJoin;
- attribute float miterLimit;
+ // image smoothing
+ [ImplementedAs=imageSmoothingEnabled, MeasureAs=PrefixedImageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
+ [MeasureAs=UnprefixedImageSmoothingEnabled] attribute boolean imageSmoothingEnabled;
- attribute float shadowOffsetX;
- attribute float shadowOffsetY;
- attribute float shadowBlur;
+ // colors and styles (see also the CanvasDrawingStyles interface)
+ // FIXME: Use union types when supported: http://crbug.com/372891
+ [Custom] attribute object strokeStyle; // (default black)
+ [Custom] attribute object fillStyle; // (default black)
+ CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
+ [RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
+ [RaisesException] CanvasPattern createPattern(HTMLCanvasElement canvas, [TreatNullAs=NullString] DOMString repetitionType);
+ [RaisesException] CanvasPattern createPattern(HTMLImageElement image, [TreatNullAs=NullString] DOMString repetitionType);
+ [RaisesException] CanvasPattern createPattern(HTMLVideoElement image, [TreatNullAs=NullString] DOMString repetitionType);
+
+ // shadows
+ attribute unrestricted float shadowOffsetX;
+ attribute unrestricted float shadowOffsetY;
+ attribute unrestricted float shadowBlur;
[TreatNullAs=NullString] attribute DOMString shadowColor;
- void setLineDash(sequence<float> dash);
- sequence<float> getLineDash();
- attribute float lineDashOffset;
-
- // FIXME: These attributes should be implemented.
- // [Custom] attribute Array webkitLineDash;
- // attribute float webkitLineDashOffset;
-
- void clearRect(float x, float y, float width, float height);
- void fillRect(float x, float y, float width, float height);
+ // rects
+ void clearRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ void fillRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ void strokeRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ // path API (see also CanvasPathMethods)
void beginPath();
-
- attribute Path currentPath;
-
- // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
- 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);
- [RaisesException] void arcTo(float x1, float y1, float x2, float y2, float radius);
- void rect(float x, float y, float width, float height);
- [RaisesException] void arc(float x, float y, float radius, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
- [RaisesException] void ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, boolean anticlockwise);
-
- void fill(optional CanvasWindingRule winding);
+ void fill(optional CanvasFillRule winding);
+ [RuntimeEnabled=Path2D] void fill(Path2D path, optional CanvasFillRule winding);
void stroke();
- void clip(optional CanvasWindingRule winding);
- boolean isPointInPath(float x, float y, optional CanvasWindingRule winding);
- boolean isPointInStroke(float x, float y);
-
- // text
- attribute DOMString font;
- attribute DOMString textAlign;
- attribute DOMString textBaseline;
-
+ [RuntimeEnabled=Path2D] void stroke(Path2D path);
+ // Focus rings
+ void drawFocusIfNeeded(Element element);
+ [RuntimeEnabled=Path2D] void drawFocusIfNeeded(Path2D path, Element element);
+
+ [RuntimeEnabled=ExperimentalCanvasFeatures] void scrollPathIntoView(optional Path2D path);
+ void clip(optional CanvasFillRule winding);
+ [RuntimeEnabled=Path2D] void clip(Path2D path, optional CanvasFillRule winding);
+ boolean isPointInPath(unrestricted float x, unrestricted float y, optional CanvasFillRule winding);
+ [RuntimeEnabled=Path2D] boolean isPointInPath(Path2D path, unrestricted float x, unrestricted float y, optional CanvasFillRule winding);
+ boolean isPointInStroke(unrestricted float x, unrestricted float y);
+ [RuntimeEnabled=Path2D] boolean isPointInStroke(Path2D path, unrestricted float x, unrestricted float y);
+
+ // text (see also the CanvasDrawingStyles interface)
+ void fillText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
+ void strokeText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
TextMetrics measureText(DOMString text);
- // other
-
- void setAlpha(float alpha);
- void setCompositeOperation(DOMString compositeOperation);
-
- void setLineWidth(float width);
- void setLineCap(DOMString cap);
- void setLineJoin(DOMString join);
- void setMiterLimit(float limit);
-
- void clearShadow();
-
- void fillText(DOMString text, float x, float y, optional float maxWidth);
- void strokeText(DOMString text, float x, float y, optional float maxWidth);
-
- void setStrokeColor([StrictTypeChecking] DOMString color, optional float alpha);
- void setStrokeColor(float grayLevel, optional float alpha);
- void setStrokeColor(float r, float g, float b, float a);
- void setStrokeColor(float c, float m, float y, float k, float a);
-
- void setFillColor([StrictTypeChecking] DOMString color, optional float alpha);
- void setFillColor(float grayLevel, optional float alpha);
- void setFillColor(float r, float g, float b, float a);
- void setFillColor(float c, float m, float y, float k, float a);
-
- void strokeRect(float x, float y, float width, float height);
-
- [RaisesException] void drawImage(HTMLImageElement? image, float x, float y);
- [RaisesException] void drawImage(HTMLImageElement? image, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLImageElement? image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y);
- [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLVideoElement? video, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap? imageBitmap, float x, float y);
- [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap? imageBitmap, float x, float y, float width, float height);
- [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap? imageBitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
-
- void drawImageFromRect(HTMLImageElement image,
- optional float sx, optional float sy, optional float sw, optional float sh,
- optional float dx, optional float dy, optional float dw, optional float dh,
- optional DOMString compositeOperation);
-
- void setShadow(float width, float height, float blur, [StrictTypeChecking] optional DOMString color, optional float alpha);
- void setShadow(float width, float height, float blur, float grayLevel, optional float alpha);
- void setShadow(float width, float height, float blur, float r, float g, float b, float a);
- void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
-
- [RaisesException] void putImageData(ImageData? imagedata, float dx, float dy);
- [RaisesException] void putImageData(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
-
- [RaisesException] void webkitPutImageDataHD(ImageData? imagedata, float dx, float dy);
- [RaisesException] void webkitPutImageDataHD(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
-
- [RaisesException] CanvasPattern createPattern(HTMLCanvasElement? canvas, [TreatNullAs=NullString] DOMString repetitionType);
- [RaisesException] CanvasPattern createPattern(HTMLImageElement? image, [TreatNullAs=NullString] DOMString repetitionType);
- [RaisesException] ImageData createImageData(ImageData? imagedata);
- [RaisesException] ImageData createImageData(float sw, float sh);
-
- [Custom] attribute object strokeStyle;
- [Custom] attribute object fillStyle;
+ // drawing images
+ [RaisesException] void drawImage(HTMLImageElement image, unrestricted float x, unrestricted float y);
+ [RaisesException] void drawImage(HTMLImageElement image, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void drawImage(HTMLImageElement image, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RaisesException] void drawImage(HTMLCanvasElement canvas, unrestricted float x, unrestricted float y);
+ [RaisesException] void drawImage(HTMLCanvasElement canvas, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void drawImage(HTMLCanvasElement canvas, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RaisesException] void drawImage(HTMLVideoElement video, unrestricted float x, unrestricted float y);
+ [RaisesException] void drawImage(HTMLVideoElement video, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void drawImage(HTMLVideoElement video, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap imageBitmap, unrestricted float x, unrestricted float y);
+ [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap imageBitmap, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap imageBitmap, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
// pixel manipulation
+ ImageData createImageData(ImageData imagedata);
+ [RaisesException] ImageData createImageData(float sw, float sh);
[RaisesException] ImageData getImageData(float sx, float sy, float sw, float sh);
+ void putImageData(ImageData imagedata, float dx, float dy);
+ void putImageData(ImageData imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
- [RaisesException] ImageData webkitGetImageDataHD(float sx, float sy, float sw, float sh);
+ // Context state
+ // Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental
+ [RuntimeEnabled=ExperimentalCanvasFeatures] boolean isContextLost();
- // Focus rings
- [RuntimeEnabled=ExperimentalCanvasFeatures] void drawSystemFocusRing(Element element);
- [RuntimeEnabled=ExperimentalCanvasFeatures] boolean drawCustomFocusRing(Element element);
+ Canvas2DContextAttributes getContextAttributes();
- readonly attribute float webkitBackingStorePixelRatio;
+ // FIXME: factor out to CanvasDrawingStyles
+ // line caps/joins
+ attribute unrestricted float lineWidth; // (default 1)
+ [TreatNullAs=NullString] attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
+ [TreatNullAs=NullString] attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
+ attribute unrestricted float miterLimit; // (default 10)
- [ImplementedAs=imageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
- attribute boolean imageSmoothingEnabled;
+ // dashed lines
+ void setLineDash(sequence<unrestricted float> dash);
+ sequence<unrestricted float> getLineDash();
+ attribute unrestricted float lineDashOffset;
- Canvas2DContextAttributes getContextAttributes();
+ // text
+ attribute DOMString font; // (default 10px sans-serif)
+ attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
+ attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
+
+ // Non-standard APIs. Candidates for deprecation
+ // https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D
+ [MeasureAs=CanvasRenderingContext2DSetAlpha] void setAlpha(unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetCompositeOperation] void setCompositeOperation(DOMString compositeOperation);
+ [MeasureAs=CanvasRenderingContext2DSetLineWidth] void setLineWidth(unrestricted float width);
+ [MeasureAs=CanvasRenderingContext2DSetLineCap] void setLineCap(DOMString cap);
+ [MeasureAs=CanvasRenderingContext2DSetLineJoin] void setLineJoin(DOMString join);
+ [MeasureAs=CanvasRenderingContext2DSetMiterLimit] void setMiterLimit(unrestricted float limit);
+ [MeasureAs=CanvasRenderingContext2DClearShadow] void clearShadow();
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(DOMString color, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(unrestricted float grayLevel, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(DOMString color, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(unrestricted float grayLevel, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DDrawImageFromRect] void drawImageFromRect(
+ HTMLImageElement? image, optional unrestricted float sx, optional unrestricted float sy, optional unrestricted float sw, optional unrestricted float sh,
+ optional unrestricted float dx, optional unrestricted float dy, optional unrestricted float dw, optional unrestricted float dh, optional DOMString compositeOperation);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, optional DOMString color, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float grayLevel, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
};
+CanvasRenderingContext2D implements CanvasPathMethods;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp
index b68421af1f6..ae7e6d41b70 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "core/html/canvas/CanvasStyle.h"
-#include "CSSPropertyNames.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/canvas/CanvasGradient.h"
@@ -42,13 +42,14 @@ namespace WebCore {
enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed };
-static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString, Document* document = 0)
+static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString)
{
if (equalIgnoringCase(colorString, "currentcolor"))
return ParsedCurrentColor;
- if (CSSParser::parseColor(parsedColor, colorString))
+ const bool useStrictParsing = true;
+ if (BisonCSSParser::parseColor(parsedColor, colorString, useStrictParsing))
return ParsedRGBA;
- if (CSSParser::parseSystemColor(parsedColor, colorString, document))
+ if (BisonCSSParser::parseSystemColor(parsedColor, colorString))
return ParsedSystemColor;
return ParseFailed;
}
@@ -58,13 +59,13 @@ RGBA32 currentColor(HTMLCanvasElement* canvas)
if (!canvas || !canvas->inDocument() || !canvas->inlineStyle())
return Color::black;
RGBA32 rgba = Color::black;
- CSSParser::parseColor(rgba, canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
+ BisonCSSParser::parseColor(rgba, canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
return rgba;
}
bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
{
- ColorParseResult parseResult = parseColor(parsedColor, colorString, canvas ? &canvas->document() : 0);
+ ColorParseResult parseResult = parseColor(parsedColor, colorString);
switch (parseResult) {
case ParsedRGBA:
case ParsedSystemColor:
@@ -123,10 +124,10 @@ CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
{
}
-PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Document* document)
+PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color)
{
RGBA32 rgba;
- ColorParseResult parseResult = parseColor(rgba, color, document);
+ ColorParseResult parseResult = parseColor(rgba, color);
switch (parseResult) {
case ParsedRGBA:
case ParsedSystemColor:
@@ -134,10 +135,10 @@ PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Docum
case ParsedCurrentColor:
return adoptRef(new CanvasStyle(CurrentColor));
case ParseFailed:
- return 0;
+ return nullptr;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
@@ -151,23 +152,24 @@ PassRefPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const Str
case ParsedCurrentColor:
return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
case ParseFailed:
- return 0;
+ return nullptr;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
{
if (!gradient)
- return 0;
+ return nullptr;
return adoptRef(new CanvasStyle(gradient));
}
+
PassRefPtr<CanvasStyle> CanvasStyle::createFromPattern(PassRefPtr<CanvasPattern> pattern)
{
if (!pattern)
- return 0;
+ return nullptr;
return adoptRef(new CanvasStyle(pattern));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h
index 526ab716345..f939e3e8214 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h
@@ -36,14 +36,13 @@ namespace WebCore {
class CanvasGradient;
class CanvasPattern;
- class Document;
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, Document* = 0);
+ 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)); }
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp
index 5a28161937c..41b6cb3332d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp
@@ -47,19 +47,19 @@ PassRefPtr<DataView> DataView::create(unsigned length)
{
RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(uint8_t));
if (!buffer.get())
- return 0;
+ return nullptr;
return create(buffer, 0, length);
}
PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
{
if (byteOffset > buffer->byteLength())
- return 0;
+ return nullptr;
CheckedInt<uint32_t> checkedOffset(byteOffset);
CheckedInt<uint32_t> checkedLength(byteLength);
CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
if (!checkedMax.isValid() || checkedMax.value() > buffer->byteLength())
- return 0;
+ return nullptr;
return adoptRef(new DataView(buffer, byteOffset, byteLength));
}
@@ -133,7 +133,7 @@ template<typename T>
T DataView::getData(unsigned byteOffset, bool littleEndian, ExceptionState& exceptionState) const
{
if (beyondRange<T>(byteOffset)) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided offset (" + String::number(byteOffset) + ") is outside the allowed range.");
return 0;
}
@@ -148,7 +148,7 @@ template<typename T>
void DataView::setData(unsigned byteOffset, T value, bool littleEndian, ExceptionState& exceptionState)
{
if (beyondRange<T>(byteOffset)) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided offset (" + String::number(byteOffset) + ") is outside the allowed range.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h
index 4a9728d845e..d497eae2f97 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h
@@ -34,14 +34,12 @@ namespace WebCore {
class ExceptionState;
-class DataView : public ArrayBufferView, public ScriptWrappable {
+class DataView FINAL : public ArrayBufferView, public ScriptWrappable {
public:
static PassRefPtr<DataView> create(unsigned length);
static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
- virtual unsigned length() const { return m_byteLength; }
- virtual unsigned byteLength() const { return m_byteLength; }
- virtual PassRefPtr<ArrayBufferView> slice(int, int) const { return 0; }
+ virtual unsigned byteLength() const OVERRIDE { return m_byteLength; }
int8_t getInt8(unsigned byteOffset, ExceptionState&);
uint8_t getUint8(unsigned byteOffset, ExceptionState&);
@@ -73,13 +71,13 @@ public:
void setFloat64(unsigned byteOffset, double value, ExceptionState& ec) { setFloat64(byteOffset, value, false, ec); }
void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionState&);
- virtual ViewType getType() const
+ virtual ViewType type() const OVERRIDE
{
return TypeDataView;
}
protected:
- virtual void neuter();
+ virtual void neuter() OVERRIDE;
private:
DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl
index a9b9facac3e..4fc89615027 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl
@@ -26,30 +26,30 @@
[
Custom=Wrap,
CustomConstructor(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long byteLength),
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
+ TypeChecking=Interface|Nullable,
] interface DataView : ArrayBufferView {
// All these methods raise an exception if they would read or write beyond the end of the view.
[RaisesException] byte getInt8(unsigned long byteOffset);
[RaisesException] octet getUint8(unsigned long byteOffset);
- [StrictTypeChecking, RaisesException] short getInt16(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] unsigned short getUint16(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] long getInt32(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] unsigned long getUint32(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] short getInt16(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] unsigned short getUint16(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] long getInt32(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] unsigned long getUint32(unsigned long byteOffset, optional boolean littleEndian);
// Use custom code to handle NaN case for JSC.
- [StrictTypeChecking, RaisesException] float getFloat32(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] double getFloat64(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] float getFloat32(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] double getFloat64(unsigned long byteOffset, optional boolean littleEndian);
[RaisesException] void setInt8(unsigned long byteOffset, byte value);
[RaisesException] void setUint8(unsigned long byteOffset, octet value);
- [StrictTypeChecking, RaisesException] void setInt16(unsigned long byteOffset, short value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setUint16(unsigned long byteOffset, unsigned short value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setInt32(unsigned long byteOffset, long value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setUint32(unsigned long byteOffset, unsigned long value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setFloat32(unsigned long byteOffset, float value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setFloat64(unsigned long byteOffset, double value, optional boolean littleEndian);
+ [RaisesException] void setInt16(unsigned long byteOffset, short value, optional boolean littleEndian);
+ [RaisesException] void setUint16(unsigned long byteOffset, unsigned short value, optional boolean littleEndian);
+ [RaisesException] void setInt32(unsigned long byteOffset, long value, optional boolean littleEndian);
+ [RaisesException] void setUint32(unsigned long byteOffset, unsigned long value, optional boolean littleEndian);
+ [RaisesException] void setFloat32(unsigned long byteOffset, float value, optional boolean littleEndian);
+ [RaisesException] void setFloat64(unsigned long byteOffset, double value, optional boolean littleEndian);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp
new file mode 100644
index 00000000000..8ded7388912
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/html/canvas/EXTBlendMinMax.h"
+
+namespace WebCore {
+
+EXTBlendMinMax::EXTBlendMinMax(WebGLRenderingContextBase* context)
+ : WebGLExtension(context)
+{
+ ScriptWrappable::init(this);
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_blend_minmax");
+}
+
+EXTBlendMinMax::~EXTBlendMinMax()
+{
+}
+
+WebGLExtensionName EXTBlendMinMax::name() const
+{
+ return EXTBlendMinMaxName;
+}
+
+PassRefPtr<EXTBlendMinMax> EXTBlendMinMax::create(WebGLRenderingContextBase* context)
+{
+ return adoptRef(new EXTBlendMinMax(context));
+}
+
+bool EXTBlendMinMax::supported(WebGLRenderingContextBase* context)
+{
+ return context->extensionsUtil()->supportsExtension("GL_EXT_blend_minmax");
+}
+
+const char* EXTBlendMinMax::extensionName()
+{
+ return "EXT_blend_minmax";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h
new file mode 100644
index 00000000000..4c6421760de
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTBlendMinMax_h
+#define EXTBlendMinMax_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLExtension.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class EXTBlendMinMax FINAL : public WebGLExtension, public ScriptWrappable {
+public:
+ static PassRefPtr<EXTBlendMinMax> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
+ static const char* extensionName();
+
+ virtual ~EXTBlendMinMax();
+ virtual WebGLExtensionName name() const OVERRIDE;
+
+private:
+ EXTBlendMinMax(WebGLRenderingContextBase*);
+};
+
+} // namespace WebCore
+
+#endif // EXTBlendMinMax_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl
new file mode 100644
index 00000000000..55baea7d615
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl
@@ -0,0 +1,12 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ DoNotCheckConstants,
+ NoInterfaceObject,
+ TypeChecking=Interface|Nullable,
+] interface EXTBlendMinMax {
+ const unsigned long MIN_EXT = 0x8007;
+ const unsigned long MAX_EXT = 0x8008;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp
index a2484d283d3..002deb3df74 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp
@@ -27,35 +27,32 @@
#include "core/html/canvas/EXTFragDepth.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-EXTFragDepth::EXTFragDepth(WebGLRenderingContext* context)
+EXTFragDepth::EXTFragDepth(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_EXT_frag_depth");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_frag_depth");
}
EXTFragDepth::~EXTFragDepth()
{
}
-WebGLExtension::ExtensionName EXTFragDepth::name() const
+WebGLExtensionName EXTFragDepth::name() const
{
return EXTFragDepthName;
}
-PassRefPtr<EXTFragDepth> EXTFragDepth::create(WebGLRenderingContext* context)
+PassRefPtr<EXTFragDepth> EXTFragDepth::create(WebGLRenderingContextBase* context)
{
return adoptRef(new EXTFragDepth(context));
}
-bool EXTFragDepth::supported(WebGLRenderingContext* context)
+bool EXTFragDepth::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_EXT_frag_depth");
+ return context->extensionsUtil()->supportsExtension("GL_EXT_frag_depth");
}
const char* EXTFragDepth::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h
index fc8a9fa6f8e..eee90dcc021 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class EXTFragDepth : public WebGLExtension, public ScriptWrappable {
+class EXTFragDepth FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<EXTFragDepth> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<EXTFragDepth> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~EXTFragDepth();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- explicit EXTFragDepth(WebGLRenderingContext*);
+ explicit EXTFragDepth(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp
new file mode 100644
index 00000000000..d258bef94cf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/html/canvas/EXTShaderTextureLOD.h"
+
+namespace WebCore {
+
+EXTShaderTextureLOD::EXTShaderTextureLOD(WebGLRenderingContextBase* context)
+ : WebGLExtension(context)
+{
+ ScriptWrappable::init(this);
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_shader_texture_lod");
+}
+
+EXTShaderTextureLOD::~EXTShaderTextureLOD()
+{
+}
+
+WebGLExtensionName EXTShaderTextureLOD::name() const
+{
+ return EXTShaderTextureLODName;
+}
+
+PassRefPtr<EXTShaderTextureLOD> EXTShaderTextureLOD::create(WebGLRenderingContextBase* context)
+{
+ return adoptRef(new EXTShaderTextureLOD(context));
+}
+
+bool EXTShaderTextureLOD::supported(WebGLRenderingContextBase* context)
+{
+ return context->extensionsUtil()->supportsExtension("GL_EXT_shader_texture_lod");
+}
+
+const char* EXTShaderTextureLOD::extensionName()
+{
+ return "EXT_shader_texture_lod";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h
new file mode 100644
index 00000000000..342d94d0965
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTShaderTextureLOD_h
+#define EXTShaderTextureLOD_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLExtension.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class EXTShaderTextureLOD FINAL : public WebGLExtension, public ScriptWrappable {
+public:
+ static PassRefPtr<EXTShaderTextureLOD> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
+ static const char* extensionName();
+
+ virtual ~EXTShaderTextureLOD();
+ virtual WebGLExtensionName name() const OVERRIDE;
+
+private:
+ EXTShaderTextureLOD(WebGLRenderingContextBase*);
+};
+
+} // namespace WebCore
+
+#endif // EXTShaderTextureLOD_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl
new file mode 100644
index 00000000000..a2e18b616ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl
@@ -0,0 +1,8 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ NoInterfaceObject
+] interface EXTShaderTextureLOD {
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
index 231c3c58662..d98399a4ccc 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContext* context)
+EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_texture_filter_anisotropic");
}
EXTTextureFilterAnisotropic::~EXTTextureFilterAnisotropic()
{
}
-WebGLExtension::ExtensionName EXTTextureFilterAnisotropic::name() const
+WebGLExtensionName EXTTextureFilterAnisotropic::name() const
{
return EXTTextureFilterAnisotropicName;
}
-PassRefPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContext* context)
+PassRefPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContextBase* context)
{
return adoptRef(new EXTTextureFilterAnisotropic(context));
}
-bool EXTTextureFilterAnisotropic::supported(WebGLRenderingContext* context)
+bool EXTTextureFilterAnisotropic::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_EXT_texture_filter_anisotropic");
+ return context->extensionsUtil()->supportsExtension("GL_EXT_texture_filter_anisotropic");
}
const char* EXTTextureFilterAnisotropic::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
index 727f00ee086..a69a9bc3ab2 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class EXTTextureFilterAnisotropic : public WebGLExtension, public ScriptWrappable {
+class EXTTextureFilterAnisotropic FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~EXTTextureFilterAnisotropic();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- EXTTextureFilterAnisotropic(WebGLRenderingContext*);
+ EXTTextureFilterAnisotropic(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp
index a4b0e29c94d..95fac41b58c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/OESElementIndexUint.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESElementIndexUint::OESElementIndexUint(WebGLRenderingContext* context)
+OESElementIndexUint::OESElementIndexUint(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_element_index_uint");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_element_index_uint");
}
OESElementIndexUint::~OESElementIndexUint()
{
}
-WebGLExtension::ExtensionName OESElementIndexUint::name() const
+WebGLExtensionName OESElementIndexUint::name() const
{
return OESElementIndexUintName;
}
-PassRefPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContext* context)
+PassRefPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESElementIndexUint(context));
}
-bool OESElementIndexUint::supported(WebGLRenderingContext* context)
+bool OESElementIndexUint::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_element_index_uint");
+ return context->extensionsUtil()->supportsExtension("GL_OES_element_index_uint");
}
const char* OESElementIndexUint::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h
index 0116c1ddcf1..f11ebd251ee 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESElementIndexUint : public WebGLExtension, public ScriptWrappable {
+class OESElementIndexUint FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESElementIndexUint> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESElementIndexUint> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESElementIndexUint();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESElementIndexUint(WebGLRenderingContext*);
+ OESElementIndexUint(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp
index aec473bc686..49b7adff0d8 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/OESStandardDerivatives.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContext* context)
+OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_standard_derivatives");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_standard_derivatives");
}
OESStandardDerivatives::~OESStandardDerivatives()
{
}
-WebGLExtension::ExtensionName OESStandardDerivatives::name() const
+WebGLExtensionName OESStandardDerivatives::name() const
{
return OESStandardDerivativesName;
}
-PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContext* context)
+PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESStandardDerivatives(context));
}
-bool OESStandardDerivatives::supported(WebGLRenderingContext* context)
+bool OESStandardDerivatives::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_standard_derivatives");
+ return context->extensionsUtil()->supportsExtension("GL_OES_standard_derivatives");
}
const char* OESStandardDerivatives::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h
index 327a15286d1..8eb7226eb20 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESStandardDerivatives : public WebGLExtension, public ScriptWrappable {
+class OESStandardDerivatives FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESStandardDerivatives> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESStandardDerivatives> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESStandardDerivatives();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESStandardDerivatives(WebGLRenderingContext*);
+ OESStandardDerivatives(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp
index 99d1387376c..a949e5c54b0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp
@@ -26,35 +26,37 @@
#include "config.h"
#include "core/html/canvas/OESTextureFloat.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESTextureFloat::OESTextureFloat(WebGLRenderingContext* context)
+OESTextureFloat::OESTextureFloat(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_float");
+ if (context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_float")) {
+ // Implicitly enable rendering to float textures
+ context->extensionsUtil()->ensureExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb");
+ }
}
OESTextureFloat::~OESTextureFloat()
{
}
-WebGLExtension::ExtensionName OESTextureFloat::name() const
+WebGLExtensionName OESTextureFloat::name() const
{
return OESTextureFloatName;
}
-PassRefPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureFloat(context));
}
-bool OESTextureFloat::supported(WebGLRenderingContext* context)
+bool OESTextureFloat::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_float");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_float");
}
const char* OESTextureFloat::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h
index 255c6741b11..dfc59086c48 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureFloat : public WebGLExtension, public ScriptWrappable {
+class OESTextureFloat FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureFloat> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureFloat> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureFloat();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureFloat(WebGLRenderingContext*);
+ OESTextureFloat(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp
index 1e8518d95d6..15a7cd356a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp
@@ -27,35 +27,32 @@
#include "core/html/canvas/OESTextureFloatLinear.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContext* context)
+OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_float_linear");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_float_linear");
}
OESTextureFloatLinear::~OESTextureFloatLinear()
{
}
-WebGLExtension::ExtensionName OESTextureFloatLinear::name() const
+WebGLExtensionName OESTextureFloatLinear::name() const
{
return OESTextureFloatLinearName;
}
-PassRefPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureFloatLinear(context));
}
-bool OESTextureFloatLinear::supported(WebGLRenderingContext* context)
+bool OESTextureFloatLinear::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_float_linear");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_float_linear");
}
const char* OESTextureFloatLinear::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h
index 4d7f8d1af53..a0646ccd3a7 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureFloatLinear : public WebGLExtension, public ScriptWrappable {
+class OESTextureFloatLinear FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureFloatLinear> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureFloatLinear> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureFloatLinear();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureFloatLinear(WebGLRenderingContext*);
+ OESTextureFloatLinear(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp
index 7253837aa42..dd7f119c947 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/OESTextureHalfFloat.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContext* context)
+OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_half_float");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_half_float");
}
OESTextureHalfFloat::~OESTextureHalfFloat()
{
}
-WebGLExtension::ExtensionName OESTextureHalfFloat::name() const
+WebGLExtensionName OESTextureHalfFloat::name() const
{
return OESTextureHalfFloatName;
}
-PassRefPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureHalfFloat(context));
}
-bool OESTextureHalfFloat::supported(WebGLRenderingContext* context)
+bool OESTextureHalfFloat::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_half_float");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_half_float");
}
const char* OESTextureHalfFloat::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h
index 953d3110f07..dc5d917a345 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureHalfFloat : public WebGLExtension, public ScriptWrappable {
+class OESTextureHalfFloat FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureHalfFloat> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureHalfFloat> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureHalfFloat();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureHalfFloat(WebGLRenderingContext*);
+ OESTextureHalfFloat(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
index c7da9bd745b..37ceabe5197 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
@@ -27,35 +27,32 @@
#include "core/html/canvas/OESTextureHalfFloatLinear.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContext* context)
+OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_half_float_linear");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_half_float_linear");
}
OESTextureHalfFloatLinear::~OESTextureHalfFloatLinear()
{
}
-WebGLExtension::ExtensionName OESTextureHalfFloatLinear::name() const
+WebGLExtensionName OESTextureHalfFloatLinear::name() const
{
return OESTextureHalfFloatLinearName;
}
-PassRefPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureHalfFloatLinear(context));
}
-bool OESTextureHalfFloatLinear::supported(WebGLRenderingContext* context)
+bool OESTextureHalfFloatLinear::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_half_float_linear");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_half_float_linear");
}
const char* OESTextureHalfFloatLinear::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h
index 17532033b45..421bbbca4d0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureHalfFloatLinear : public WebGLExtension, public ScriptWrappable {
+class OESTextureHalfFloatLinear FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureHalfFloatLinear();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureHalfFloatLinear(WebGLRenderingContext*);
+ OESTextureHalfFloatLinear(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp
index 848c85f5557..932195ed611 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp
@@ -28,29 +28,28 @@
#include "core/html/canvas/OESVertexArrayObject.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "core/html/canvas/WebGLVertexArrayObjectOES.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContext* context)
+OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_vertex_array_object");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_vertex_array_object");
}
OESVertexArrayObject::~OESVertexArrayObject()
{
}
-WebGLExtension::ExtensionName OESVertexArrayObject::name() const
+WebGLExtensionName OESVertexArrayObject::name() const
{
return OESVertexArrayObjectName;
}
-PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context)
+PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESVertexArrayObject(context));
}
@@ -58,7 +57,7 @@ PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingCont
PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
{
if (isLost())
- return 0;
+ return nullptr;
RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
m_context->addContextObject(o.get());
@@ -71,12 +70,12 @@ void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* array
return;
if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject)
- m_context->setBoundVertexArrayObject(0);
+ m_context->setBoundVertexArrayObject(nullptr);
- arrayObject->deleteObject(m_context->graphicsContext3D());
+ arrayObject->deleteObject(m_context->webContext());
}
-GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
+GLboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
{
if (!arrayObject || isLost())
return 0;
@@ -84,8 +83,7 @@ GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* ar
if (!arrayObject->hasEverBeenBound())
return 0;
- Extensions3D* extensions = m_context->graphicsContext3D()->extensions();
- return extensions->isVertexArrayOES(arrayObject->object());
+ return m_context->webContext()->isVertexArrayOES(arrayObject->object());
}
void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
@@ -94,26 +92,24 @@ void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayOb
return;
if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, context()))) {
- m_context->graphicsContext3D()->synthesizeGLError(GL_INVALID_OPERATION);
+ m_context->webContext()->synthesizeGLError(GL_INVALID_OPERATION);
return;
}
- Extensions3D* extensions = m_context->graphicsContext3D()->extensions();
if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
- extensions->bindVertexArrayOES(arrayObject->object());
+ m_context->webContext()->bindVertexArrayOES(arrayObject->object());
arrayObject->setHasEverBeenBound();
m_context->setBoundVertexArrayObject(arrayObject);
} else {
- extensions->bindVertexArrayOES(0);
- m_context->setBoundVertexArrayObject(0);
+ m_context->webContext()->bindVertexArrayOES(0);
+ m_context->setBoundVertexArrayObject(nullptr);
}
}
-bool OESVertexArrayObject::supported(WebGLRenderingContext* context)
+bool OESVertexArrayObject::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_vertex_array_object");
+ return context->extensionsUtil()->supportsExtension("GL_OES_vertex_array_object");
}
const char* OESVertexArrayObject::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h
index 2fd0735f21a..3f616be0575 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h
@@ -28,30 +28,29 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/WebGLExtension.h"
-#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
class WebGLVertexArrayObjectOES;
-class OESVertexArrayObject : public WebGLExtension, public ScriptWrappable {
+class OESVertexArrayObject FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESVertexArrayObject> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESVertexArrayObject> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESVertexArrayObject();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
PassRefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
void deleteVertexArrayOES(WebGLVertexArrayObjectOES*);
- GC3Dboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
+ GLboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
void bindVertexArrayOES(WebGLVertexArrayObjectOES*);
private:
- OESVertexArrayObject(WebGLRenderingContext*);
+ OESVertexArrayObject(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl
index aa9a16d6377..5a21f238d79 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl
@@ -24,13 +24,14 @@
*/
[
+ DoNotCheckConstants,
NoInterfaceObject,
- DoNotCheckConstants
+ TypeChecking=Interface|Nullable,
] interface OESVertexArrayObject {
const unsigned long VERTEX_ARRAY_BINDING_OES = 0x85B5;
- [StrictTypeChecking] WebGLVertexArrayObjectOES createVertexArrayOES();
- [StrictTypeChecking] void deleteVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
- [StrictTypeChecking] boolean isVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
- [StrictTypeChecking] void bindVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
+ WebGLVertexArrayObjectOES createVertexArrayOES();
+ void deleteVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
+ boolean isVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
+ void bindVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Path.idl b/chromium/third_party/WebKit/Source/core/html/canvas/Path.idl
deleted file mode 100644
index 66435a5da46..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Path.idl
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- RuntimeEnabled=ExperimentalCanvasFeatures,
- Constructor,
- Constructor(Path path),
- Constructor(DOMString text),
- ImplementedAs=DOMPath
-] interface Path {
-
- // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
- void closePath();
- void moveTo([Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void lineTo([Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void quadraticCurveTo([Default=Undefined] optional float cpx,
- [Default=Undefined] optional float cpy,
- [Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void bezierCurveTo([Default=Undefined] optional float cp1x,
- [Default=Undefined] optional float cp1y,
- [Default=Undefined] optional float cp2x,
- [Default=Undefined] optional float cp2y,
- [Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- [RaisesException] void arcTo([Default=Undefined] optional float x1,
- [Default=Undefined] optional float y1,
- [Default=Undefined] optional float x2,
- [Default=Undefined] optional float y2,
- [Default=Undefined] optional float radius);
- void rect([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float width,
- [Default=Undefined] optional float height);
- [RaisesException] void arc([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float radius,
- [Default=Undefined] optional float startAngle,
- [Default=Undefined] optional float endAngle,
- [Default=Undefined] optional boolean anticlockwise);
-};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h
index 9ce2cba9512..f09839bb1e9 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h
@@ -25,50 +25,60 @@
* SUCH DAMAGE.
*/
-#ifndef DOMPath_h
-#define DOMPath_h
+#ifndef Path2D_h
+#define Path2D_h
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/CanvasPathMethods.h"
+#include "core/svg/SVGMatrixTearOff.h"
#include "core/svg/SVGPathUtilities.h"
+#include "platform/transforms/AffineTransform.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class DOMPath : public RefCounted<DOMPath>, public CanvasPathMethods, public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DOMPath); WTF_MAKE_FAST_ALLOCATED;
+class Path2D FINAL : public RefCounted<Path2D>, public CanvasPathMethods, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(Path2D); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassRefPtr<DOMPath> create() { return adoptRef(new DOMPath); }
- static PassRefPtr<DOMPath> create(const String& pathData) { return adoptRef(new DOMPath(pathData)); }
- static PassRefPtr<DOMPath> create(DOMPath* path) { return adoptRef(new DOMPath(path)); }
+ static PassRefPtr<Path2D> create() { return adoptRef(new Path2D); }
+ static PassRefPtr<Path2D> create(const String& pathData) { return adoptRef(new Path2D(pathData)); }
+ static PassRefPtr<Path2D> create(Path2D* path) { return adoptRef(new Path2D(path)); }
- static PassRefPtr<DOMPath> create(const Path& path) { return adoptRef(new DOMPath(path)); }
+ static PassRefPtr<Path2D> create(const Path& path) { return adoptRef(new Path2D(path)); }
const Path& path() const { return m_path; }
- virtual ~DOMPath() { }
+ void addPath(Path2D* path)
+ {
+ addPath(path, 0);
+ }
+
+ void addPath(Path2D* path, SVGMatrixTearOff* transform)
+ {
+ Path src = path->path();
+ m_path.addPath(src, transform ? transform->value() : AffineTransform(1, 0, 0, 1, 0, 0));
+ }
+ virtual ~Path2D() { }
private:
- DOMPath() : CanvasPathMethods()
+ Path2D() : CanvasPathMethods()
{
ScriptWrappable::init(this);
}
- DOMPath(const Path& path)
- : CanvasPathMethods()
+ Path2D(const Path& path)
+ : CanvasPathMethods(path)
{
ScriptWrappable::init(this);
- m_path = path;
}
- DOMPath(DOMPath* path)
- : CanvasPathMethods()
+ Path2D(Path2D* path)
+ : CanvasPathMethods(path->path())
{
ScriptWrappable::init(this);
- m_path = path->path();
}
- DOMPath(const String& pathData)
+ Path2D(const String& pathData)
: CanvasPathMethods()
{
ScriptWrappable::init(this);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl
new file mode 100644
index 00000000000..262148560a2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path2d
+
+[
+ Constructor,
+ Constructor(Path2D path),
+ Constructor(DOMString text),
+ RuntimeEnabled=Path2D,
+] interface Path2D {
+
+ [RuntimeEnabled=ExperimentalCanvasFeatures, TypeChecking=Interface|Nullable] void addPath(Path2D path, optional SVGMatrix? transform);
+};
+
+Path2D implements CanvasPathMethods;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h
index 7571e3681ec..b1c983484b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h
@@ -27,7 +27,7 @@
#define WebGLActiveInfo_h
#include "bindings/v8/ScriptWrappable.h"
-#include "platform/graphics/GraphicsContext3D.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -36,16 +36,16 @@ namespace WebCore {
class WebGLActiveInfo : public RefCounted<WebGLActiveInfo>, public ScriptWrappable {
public:
- static PassRefPtr<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
+ static PassRefPtr<WebGLActiveInfo> create(const String& name, GLenum type, GLint size)
{
return adoptRef(new WebGLActiveInfo(name, type, size));
}
String name() const { return m_name; }
- GC3Denum type() const { return m_type; }
- GC3Dint size() const { return m_size; }
+ GLenum type() const { return m_type; }
+ GLint size() const { return m_size; }
private:
- WebGLActiveInfo(const String& name, GC3Denum type, GC3Dint size)
+ WebGLActiveInfo(const String& name, GLenum type, GLint size)
: m_name(name)
, m_type(type)
, m_size(size)
@@ -56,8 +56,8 @@ private:
ScriptWrappable::init(this);
}
String m_name;
- GC3Denum m_type;
- GC3Dint m_size;
+ GLenum m_type;
+ GLint m_size;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp
index 48bf88a1ab0..6308eccf192 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp
@@ -27,21 +27,21 @@
#include "core/html/canvas/WebGLBuffer.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLBuffer(ctx));
}
-WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_target(0)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createBuffer());
+ setObject(ctx->webContext()->createBuffer());
}
WebGLBuffer::~WebGLBuffer()
@@ -49,12 +49,12 @@ WebGLBuffer::~WebGLBuffer()
deleteObject(0);
}
-void WebGLBuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLBuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteBuffer(object);
}
-void WebGLBuffer::setTarget(GC3Denum target)
+void WebGLBuffer::setTarget(GLenum target)
{
// In WebGL, a buffer is bound to one target in its lifetime
if (m_target)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h
index 8483685f58c..9f596be4c8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h
@@ -33,26 +33,26 @@
namespace WebCore {
-class WebGLBuffer : public WebGLSharedObject, public ScriptWrappable {
+class WebGLBuffer FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLBuffer();
- static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLBuffer> create(WebGLRenderingContextBase*);
- GC3Denum getTarget() const { return m_target; }
- void setTarget(GC3Denum);
+ GLenum getTarget() const { return m_target; }
+ void setTarget(GLenum);
bool hasEverBeenBound() const { return object() && m_target; }
protected:
- WebGLBuffer(WebGLRenderingContext*);
+ WebGLBuffer(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isBuffer() const { return true; }
+ virtual bool isBuffer() const OVERRIDE { return true; }
- GC3Denum m_target;
+ GLenum m_target;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
index dad7ff49b05..3bfd7d8f0b1 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
@@ -27,37 +27,34 @@
#include "core/html/canvas/WebGLCompressedTextureATC.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContext* context)
+WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGB_AMD);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
+ context->addCompressedTextureFormat(GC3D_COMPRESSED_ATC_RGB_AMD);
+ context->addCompressedTextureFormat(GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD);
+ context->addCompressedTextureFormat(GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
}
WebGLCompressedTextureATC::~WebGLCompressedTextureATC()
{
}
-WebGLExtension::ExtensionName WebGLCompressedTextureATC::name() const
+WebGLExtensionName WebGLCompressedTextureATC::name() const
{
return WebGLCompressedTextureATCName;
}
-PassRefPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLCompressedTextureATC(context));
}
-bool WebGLCompressedTextureATC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTextureATC::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_AMD_compressed_ATC_texture");
+ return context->extensionsUtil()->supportsExtension("GL_AMD_compressed_ATC_texture");
}
const char* WebGLCompressedTextureATC::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h
index eb49bc4bfe8..069fe145bd0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h
@@ -34,17 +34,17 @@ namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureATC : public WebGLExtension, public ScriptWrappable {
+class WebGLCompressedTextureATC FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLCompressedTextureATC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLCompressedTextureATC> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLCompressedTextureATC();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLCompressedTextureATC(WebGLRenderingContext*);
+ WebGLCompressedTextureATC(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp
new file mode 100644
index 00000000000..a2abde855a3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/html/canvas/WebGLCompressedTextureETC1.h"
+
+#include "core/html/canvas/WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+WebGLCompressedTextureETC1::WebGLCompressedTextureETC1(WebGLRenderingContextBase* context)
+ : WebGLExtension(context)
+{
+ ScriptWrappable::init(this);
+ context->addCompressedTextureFormat(GL_ETC1_RGB8_OES);
+}
+
+WebGLCompressedTextureETC1::~WebGLCompressedTextureETC1()
+{
+}
+
+WebGLExtensionName WebGLCompressedTextureETC1::name() const
+{
+ return WebGLCompressedTextureETC1Name;
+}
+
+PassRefPtr<WebGLCompressedTextureETC1> WebGLCompressedTextureETC1::create(WebGLRenderingContextBase* context)
+{
+ return adoptRef(new WebGLCompressedTextureETC1(context));
+}
+
+bool WebGLCompressedTextureETC1::supported(WebGLRenderingContextBase* context)
+{
+ Extensions3DUtil* extensionsUtil = context->extensionsUtil();
+ return extensionsUtil->supportsExtension("GL_OES_compressed_ETC1_RGB8_texture");
+}
+
+const char* WebGLCompressedTextureETC1::extensionName()
+{
+ return "WEBGL_compressed_texture_etc1";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h
new file mode 100644
index 00000000000..4cf3a57ed74
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WebGLCompressedTextureETC1_h
+#define WebGLCompressedTextureETC1_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLExtension.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class WebGLTexture;
+
+class WebGLCompressedTextureETC1 FINAL : public WebGLExtension, public ScriptWrappable {
+public:
+ static PassRefPtr<WebGLCompressedTextureETC1> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
+ static const char* extensionName();
+
+ virtual ~WebGLCompressedTextureETC1();
+ virtual WebGLExtensionName name() const OVERRIDE;
+
+private:
+ WebGLCompressedTextureETC1(WebGLRenderingContextBase*);
+};
+
+} // namespace WebCore
+
+#endif // WebGLCompressedTextureETC1_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl
new file mode 100644
index 00000000000..e37d990cb6d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl
@@ -0,0 +1,11 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface WebGLCompressedTextureETC1 {
+ /* Compressed Texture Formats */
+ const unsigned long COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
index 8ae4acd2689..d1586ff22d6 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
@@ -27,39 +27,37 @@
#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContext* context)
+WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
}
WebGLCompressedTexturePVRTC::~WebGLCompressedTexturePVRTC()
{
}
-WebGLExtension::ExtensionName WebGLCompressedTexturePVRTC::name() const
+WebGLExtensionName WebGLCompressedTexturePVRTC::name() const
{
return WebGLCompressedTexturePVRTCName;
}
-PassRefPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLCompressedTexturePVRTC(context));
}
-bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_IMG_texture_compression_pvrtc");
+ return context->extensionsUtil()->supportsExtension("GL_IMG_texture_compression_pvrtc");
}
const char* WebGLCompressedTexturePVRTC::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
index dc28e5f9522..27cde75bca7 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class WebGLCompressedTexturePVRTC : public WebGLExtension, public ScriptWrappable {
+class WebGLCompressedTexturePVRTC FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLCompressedTexturePVRTC();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLCompressedTexturePVRTC(WebGLRenderingContext*);
+ WebGLCompressedTexturePVRTC(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
index 9d3f2543001..35834cc91ff 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
@@ -27,42 +27,41 @@
#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContext* context)
+WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
}
WebGLCompressedTextureS3TC::~WebGLCompressedTextureS3TC()
{
}
-WebGLExtension::ExtensionName WebGLCompressedTextureS3TC::name() const
+WebGLExtensionName WebGLCompressedTextureS3TC::name() const
{
return WebGLCompressedTextureS3TCName;
}
-PassRefPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLCompressedTextureS3TC(context));
}
-bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_EXT_texture_compression_s3tc")
- || (extensions->supports("GL_EXT_texture_compression_dxt1")
- && extensions->supports("GL_CHROMIUM_texture_compression_dxt3")
- && extensions->supports("GL_CHROMIUM_texture_compression_dxt5"));
+ Extensions3DUtil* extensionsUtil = context->extensionsUtil();
+ return extensionsUtil->supportsExtension("GL_EXT_texture_compression_s3tc")
+ || (extensionsUtil->supportsExtension("GL_EXT_texture_compression_dxt1")
+ && extensionsUtil->supportsExtension("GL_CHROMIUM_texture_compression_dxt3")
+ && extensionsUtil->supportsExtension("GL_CHROMIUM_texture_compression_dxt5"));
}
const char* WebGLCompressedTextureS3TC::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
index 615f4f587fb..aaed4a7764c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
@@ -34,17 +34,17 @@ namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureS3TC : public WebGLExtension, public ScriptWrappable {
+class WebGLCompressedTextureS3TC FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLCompressedTextureS3TC();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLCompressedTextureS3TC(WebGLRenderingContext*);
+ WebGLCompressedTextureS3TC(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp
index cb26556a731..385720617fd 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp
@@ -28,6 +28,8 @@
#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/frame/Settings.h"
+
namespace WebCore {
PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
@@ -35,20 +37,28 @@ PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
return adoptRef(new WebGLContextAttributes());
}
-PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes)
-{
- return adoptRef(new WebGLContextAttributes(attributes));
-}
-
WebGLContextAttributes::WebGLContextAttributes()
: CanvasContextAttributes()
+ , m_alpha(true)
+ , m_depth(true)
+ , m_stencil(false)
+ , m_antialias(true)
+ , m_premultipliedAlpha(true)
+ , m_preserveDrawingBuffer(false)
+ , m_failIfMajorPerformanceCaveat(false)
{
ScriptWrappable::init(this);
}
-WebGLContextAttributes::WebGLContextAttributes(GraphicsContext3D::Attributes attributes)
+WebGLContextAttributes::WebGLContextAttributes(const WebGLContextAttributes& attrs)
: CanvasContextAttributes()
- , m_attrs(attributes)
+ , m_alpha(attrs.m_alpha)
+ , m_depth(attrs.m_depth)
+ , m_stencil(attrs.m_stencil)
+ , m_antialias(attrs.m_antialias)
+ , m_premultipliedAlpha(attrs.m_premultipliedAlpha)
+ , m_preserveDrawingBuffer(attrs.m_preserveDrawingBuffer)
+ , m_failIfMajorPerformanceCaveat(attrs.m_failIfMajorPerformanceCaveat)
{
ScriptWrappable::init(this);
}
@@ -57,79 +67,104 @@ WebGLContextAttributes::~WebGLContextAttributes()
{
}
+PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::clone() const
+{
+ return adoptRef(new WebGLContextAttributes(*this));
+}
+
bool WebGLContextAttributes::alpha() const
{
- return m_attrs.alpha;
+ return m_alpha;
}
void WebGLContextAttributes::setAlpha(bool alpha)
{
- m_attrs.alpha = alpha;
+ m_alpha = alpha;
}
bool WebGLContextAttributes::depth() const
{
- return m_attrs.depth;
+ return m_depth;
}
void WebGLContextAttributes::setDepth(bool depth)
{
- m_attrs.depth = depth;
+ m_depth = depth;
}
bool WebGLContextAttributes::stencil() const
{
- return m_attrs.stencil;
+ return m_stencil;
}
void WebGLContextAttributes::setStencil(bool stencil)
{
- m_attrs.stencil = stencil;
+ m_stencil = stencil;
}
bool WebGLContextAttributes::antialias() const
{
- return m_attrs.antialias;
+ return m_antialias;
}
void WebGLContextAttributes::setAntialias(bool antialias)
{
- m_attrs.antialias = antialias;
+ m_antialias = antialias;
}
bool WebGLContextAttributes::premultipliedAlpha() const
{
- return m_attrs.premultipliedAlpha;
+ return m_premultipliedAlpha;
}
void WebGLContextAttributes::setPremultipliedAlpha(bool premultipliedAlpha)
{
- m_attrs.premultipliedAlpha = premultipliedAlpha;
+ m_premultipliedAlpha = premultipliedAlpha;
}
bool WebGLContextAttributes::preserveDrawingBuffer() const
{
- return m_attrs.preserveDrawingBuffer;
+ return m_preserveDrawingBuffer;
}
void WebGLContextAttributes::setPreserveDrawingBuffer(bool preserveDrawingBuffer)
{
- m_attrs.preserveDrawingBuffer = preserveDrawingBuffer;
+ m_preserveDrawingBuffer = preserveDrawingBuffer;
}
bool WebGLContextAttributes::failIfMajorPerformanceCaveat() const
{
- return m_attrs.failIfMajorPerformanceCaveat;
+ return m_failIfMajorPerformanceCaveat;
}
void WebGLContextAttributes::setFailIfMajorPerformanceCaveat(bool failIfMajorPerformanceCaveat)
{
- m_attrs.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat;
+ m_failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat;
}
-GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const
+blink::WebGraphicsContext3D::Attributes WebGLContextAttributes::attributes(
+ const blink::WebString& topDocumentURL, Settings* settings) const
{
- return m_attrs;
+ blink::WebGraphicsContext3D::Attributes attrs;
+
+ attrs.alpha = m_alpha;
+ attrs.depth = m_depth;
+ attrs.stencil = m_stencil;
+ attrs.antialias = m_antialias;
+ if (m_antialias) {
+ if (settings && !settings->openGLMultisamplingEnabled())
+ attrs.antialias = false;
+ }
+ attrs.premultipliedAlpha = m_premultipliedAlpha;
+ attrs.failIfMajorPerformanceCaveat = m_failIfMajorPerformanceCaveat;
+
+ attrs.noExtensions = true;
+ attrs.shareResources = false;
+ attrs.preferDiscreteGPU = true;
+
+ attrs.topDocumentURL = topDocumentURL;
+
+ return attrs;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h
index 62a576ef736..eeee443e2fa 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h
@@ -29,42 +29,44 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/CanvasContextAttributes.h"
-#include "platform/graphics/GraphicsContext3D.h"
+#include "public/platform/WebGraphicsContext3D.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class WebGLContextAttributes : public CanvasContextAttributes, public ScriptWrappable {
+class Settings;
+
+class WebGLContextAttributes FINAL : public CanvasContextAttributes, public ScriptWrappable {
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);
+ // Create a copy of this object.
+ PassRefPtr<WebGLContextAttributes> clone() const;
// Whether or not the drawing buffer has an alpha channel; default=true
bool alpha() const;
- void setAlpha(bool alpha);
+ void setAlpha(bool);
// Whether or not the drawing buffer has a depth buffer; default=true
bool depth() const;
- void setDepth(bool depth);
+ void setDepth(bool);
- // Whether or not the drawing buffer has a stencil buffer; default=true
+ // Whether or not the drawing buffer has a stencil buffer; default=false
bool stencil() const;
- void setStencil(bool stencil);
+ void setStencil(bool);
// Whether or not the drawing buffer is antialiased; default=true
bool antialias() const;
- void setAntialias(bool antialias);
+ void setAntialias(bool);
// 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);
+ void setPremultipliedAlpha(bool);
// Whether or not to preserve the drawing buffer after presentation to the
// screen; default=false
@@ -76,16 +78,23 @@ public:
bool failIfMajorPerformanceCaveat() const;
void setFailIfMajorPerformanceCaveat(bool);
- // 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;
+ // Set up the attributes that can be used to initialize a WebGraphicsContext3D.
+ // It's mostly based on WebGLContextAttributes, but would be adjusted based
+ // on settings.
+ blink::WebGraphicsContext3D::Attributes attributes(const blink::WebString&, Settings*) const;
protected:
WebGLContextAttributes();
- WebGLContextAttributes(GraphicsContext3D::Attributes attributes);
+ WebGLContextAttributes(const WebGLContextAttributes&);
private:
- GraphicsContext3D::Attributes m_attrs;
+ bool m_alpha;
+ bool m_depth;
+ bool m_stencil;
+ bool m_antialias;
+ bool m_premultipliedAlpha;
+ bool m_preserveDrawingBuffer;
+ bool m_failIfMajorPerformanceCaveat;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp
index 7f4cf7c7576..f26e8441ea3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/html/canvas/WebGLContextEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
WebGLContextEventInit::WebGLContextEventInit()
@@ -62,4 +60,9 @@ const AtomicString& WebGLContextEvent::interfaceName() const
return EventNames::WebGLContextEvent;
}
+void WebGLContextEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h
index 18f4a4812f9..0bd83808671 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h
@@ -36,25 +36,27 @@ struct WebGLContextEventInit : public EventInit {
String statusMessage;
};
-class WebGLContextEvent : public Event {
+class WebGLContextEvent FINAL : public Event {
public:
- static PassRefPtr<WebGLContextEvent> create()
+ static PassRefPtrWillBeRawPtr<WebGLContextEvent> create()
{
- return adoptRef(new WebGLContextEvent);
+ return adoptRefWillBeNoop(new WebGLContextEvent);
}
- static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ static PassRefPtrWillBeRawPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
{
- return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ return adoptRefWillBeNoop(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
}
- static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
{
- return adoptRef(new WebGLContextEvent(type, initializer));
+ return adoptRefWillBeNoop(new WebGLContextEvent(type, initializer));
}
virtual ~WebGLContextEvent();
const String& statusMessage() const { return m_statusMessage; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
WebGLContextEvent();
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp
index 93ff6f4f4f1..e9e3ebe267e 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp
@@ -46,19 +46,19 @@ WebGLContextGroup::~WebGLContextGroup()
detachAndRemoveAllObjects();
}
-GraphicsContext3D* WebGLContextGroup::getAGraphicsContext3D()
+blink::WebGraphicsContext3D* WebGLContextGroup::getAWebGraphicsContext3D()
{
ASSERT(!m_contexts.isEmpty());
- HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin();
- return (*it)->graphicsContext3D();
+ HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin();
+ return (*it)->webContext();
}
-void WebGLContextGroup::addContext(WebGLRenderingContext* context)
+void WebGLContextGroup::addContext(WebGLRenderingContextBase* context)
{
m_contexts.add(context);
}
-void WebGLContextGroup::removeContext(WebGLRenderingContext* context)
+void WebGLContextGroup::removeContext(WebGLRenderingContextBase* context)
{
// We must call detachAndRemoveAllObjects before removing the last context.
if (m_contexts.size() == 1 && m_contexts.contains(context))
@@ -85,13 +85,13 @@ void WebGLContextGroup::detachAndRemoveAllObjects()
}
}
-void WebGLContextGroup::loseContextGroup(WebGLRenderingContext::LostContextMode mode)
+void WebGLContextGroup::loseContextGroup(WebGLRenderingContextBase::LostContextMode mode)
{
// Detach must happen before loseContextImpl, which destroys the GraphicsContext3D
// and prevents groupObjects from being properly deleted.
detachAndRemoveAllObjects();
- for (HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
+ for (HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
(*it)->loseContextImpl(mode);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h
index b1fece9111b..6c2f9953540 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h
@@ -26,17 +26,20 @@
#ifndef WebGLContextGroup_h
#define WebGLContextGroup_h
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "wtf/HashSet.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
+namespace blink {
+class WebGraphicsContext3D;
+}
+
namespace WebCore {
-class GraphicsContext3D;
class WebGLExtension;
class WebGLSharedObject;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
typedef int ExceptionCode;
@@ -45,15 +48,15 @@ public:
static PassRefPtr<WebGLContextGroup> create();
~WebGLContextGroup();
- void addContext(WebGLRenderingContext*);
- void removeContext(WebGLRenderingContext*);
+ void addContext(WebGLRenderingContextBase*);
+ void removeContext(WebGLRenderingContextBase*);
void addObject(WebGLSharedObject*);
void removeObject(WebGLSharedObject*);
- GraphicsContext3D* getAGraphicsContext3D();
+ blink::WebGraphicsContext3D* getAWebGraphicsContext3D();
- void loseContextGroup(WebGLRenderingContext::LostContextMode);
+ void loseContextGroup(WebGLRenderingContextBase::LostContextMode);
private:
friend class WebGLObject;
@@ -62,7 +65,7 @@ public:
void detachAndRemoveAllObjects();
- HashSet<WebGLRenderingContext*> m_contexts;
+ HashSet<WebGLRenderingContextBase*> m_contexts;
HashSet<WebGLSharedObject*> m_groupObjects;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp
index ea718c51e7a..83441589def 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp
@@ -27,11 +27,11 @@
#include "core/html/canvas/WebGLContextObject.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLContextObject::WebGLContextObject(WebGLRenderingContext* context)
+WebGLContextObject::WebGLContextObject(WebGLRenderingContextBase* context)
: WebGLObject(context)
, m_context(context)
{
@@ -47,15 +47,15 @@ void WebGLContextObject::detachContext()
{
detach();
if (m_context) {
- deleteObject(m_context->graphicsContext3D());
+ deleteObject(m_context->webContext());
m_context->removeContextObject(this);
m_context = 0;
}
}
-GraphicsContext3D* WebGLContextObject::getAGraphicsContext3D() const
+blink::WebGraphicsContext3D* WebGLContextObject::getAWebGraphicsContext3D() const
{
- return m_context ? m_context->graphicsContext3D() : 0;
+ return m_context ? m_context->webContext() : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h
index 1e4d2965754..21be7a53d8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h
@@ -28,20 +28,23 @@
#include "core/html/canvas/WebGLObject.h"
+namespace blink {
+class WebGraphicsContext3D;
+}
+
namespace WebCore {
-class GraphicsContext3D;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
// WebGLContextObject the base class for objects that are owned by a specific
-// WebGLRenderingContext.
+// WebGLRenderingContextBase.
class WebGLContextObject : public WebGLObject {
public:
virtual ~WebGLContextObject();
- WebGLRenderingContext* context() const { return m_context; }
+ WebGLRenderingContextBase* context() const { return m_context; }
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext* context) const
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase* context) const OVERRIDE FINAL
{
return context == m_context;
}
@@ -49,17 +52,17 @@ public:
void detachContext();
protected:
- WebGLContextObject(WebGLRenderingContext*);
+ WebGLContextObject(WebGLRenderingContextBase*);
- virtual bool hasGroupOrContext() const
+ virtual bool hasGroupOrContext() const OVERRIDE FINAL
{
return m_context;
}
- virtual GraphicsContext3D* getAGraphicsContext3D() const;
+ virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const OVERRIDE FINAL;
private:
- WebGLRenderingContext* m_context;
+ WebGLRenderingContextBase* m_context;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
index bca809a7c0e..cc61d268de1 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContext* context)
+WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
@@ -39,17 +39,17 @@ WebGLDebugRendererInfo::~WebGLDebugRendererInfo()
{
}
-WebGLExtension::ExtensionName WebGLDebugRendererInfo::name() const
+WebGLExtensionName WebGLDebugRendererInfo::name() const
{
return WebGLDebugRendererInfoName;
}
-PassRefPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDebugRendererInfo(context));
}
-bool WebGLDebugRendererInfo::supported(WebGLRenderingContext*)
+bool WebGLDebugRendererInfo::supported(WebGLRenderingContextBase*)
{
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h
index 2baa7abe337..8863aeb30f5 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h
@@ -32,22 +32,22 @@
namespace WebCore {
-class WebGLDebugRendererInfo : public WebGLExtension, public ScriptWrappable {
+class WebGLDebugRendererInfo FINAL : public WebGLExtension, public ScriptWrappable {
public:
enum EnumType {
UNMASKED_VENDOR_WEBGL = 0x9245,
UNMASKED_RENDERER_WEBGL = 0x9246
};
- static PassRefPtr<WebGLDebugRendererInfo> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDebugRendererInfo> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDebugRendererInfo();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLDebugRendererInfo(WebGLRenderingContext*);
+ WebGLDebugRendererInfo(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp
index 8ecb09379d2..2b4a0aa5037 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp
@@ -27,13 +27,12 @@
#include "core/html/canvas/WebGLDebugShaders.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "core/html/canvas/WebGLShader.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContext* context)
+WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
@@ -43,12 +42,12 @@ WebGLDebugShaders::~WebGLDebugShaders()
{
}
-WebGLExtension::ExtensionName WebGLDebugShaders::name() const
+WebGLExtensionName WebGLDebugShaders::name() const
{
return WebGLDebugShadersName;
}
-PassRefPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDebugShaders(context));
}
@@ -59,13 +58,12 @@ String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader)
return String();
if (!m_context->validateWebGLObject("getTranslatedShaderSource", shader))
return "";
- return m_context->graphicsContext3D()->extensions()->getTranslatedShaderSourceANGLE(shader->object());
+ return m_context->ensureNotNull(m_context->webContext()->getTranslatedShaderSourceANGLE(shader->object()));
}
-bool WebGLDebugShaders::supported(WebGLRenderingContext* context)
+bool WebGLDebugShaders::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_ANGLE_translated_shader_source");
+ return context->extensionsUtil()->supportsExtension("GL_ANGLE_translated_shader_source");
}
const char* WebGLDebugShaders::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h
index 1adbd3074c1..f1ae4f04b00 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h
@@ -34,19 +34,19 @@ namespace WebCore {
class WebGLShader;
-class WebGLDebugShaders : public WebGLExtension, public ScriptWrappable {
+class WebGLDebugShaders FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLDebugShaders> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDebugShaders> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDebugShaders();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
String getTranslatedShaderSource(WebGLShader*);
private:
- WebGLDebugShaders(WebGLRenderingContext*);
+ WebGLDebugShaders(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl
index 55a6f3cb981..74851c7c226 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl
@@ -24,7 +24,8 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
+ TypeChecking=Interface|Nullable,
] interface WebGLDebugShaders {
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getTranslatedShaderSource(WebGLShader shader);
+ [TreatReturnedNullStringAs=Null] DOMString getTranslatedShaderSource(WebGLShader? shader);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp
index d42019ff82f..eb2e41d905b 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp
@@ -27,42 +27,40 @@
#include "core/html/canvas/WebGLDepthTexture.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContext* context)
+WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_CHROMIUM_depth_texture");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_CHROMIUM_depth_texture");
}
WebGLDepthTexture::~WebGLDepthTexture()
{
}
-WebGLExtension::ExtensionName WebGLDepthTexture::name() const
+WebGLExtensionName WebGLDepthTexture::name() const
{
return WebGLDepthTextureName;
}
-PassRefPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDepthTexture(context));
}
-bool WebGLDepthTexture::supported(WebGLRenderingContext* context)
+bool WebGLDepthTexture::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
+ Extensions3DUtil* extensionsUtil = context->extensionsUtil();
// Emulating the UNSIGNED_INT_24_8_WEBGL texture internal format in terms
// of two separate texture objects is too difficult, so disable depth
// textures unless a packed depth/stencil format is available.
- if (!extensions->supports("GL_OES_packed_depth_stencil"))
+ if (!extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil"))
return false;
- return extensions->supports("GL_CHROMIUM_depth_texture")
- || extensions->supports("GL_OES_depth_texture")
- || extensions->supports("GL_ARB_depth_texture");
+ return extensionsUtil->supportsExtension("GL_CHROMIUM_depth_texture")
+ || extensionsUtil->supportsExtension("GL_OES_depth_texture")
+ || extensionsUtil->supportsExtension("GL_ARB_depth_texture");
}
const char* WebGLDepthTexture::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h
index 34b052511b0..34017ee1801 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class WebGLDepthTexture : public WebGLExtension, public ScriptWrappable {
+class WebGLDepthTexture FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLDepthTexture> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDepthTexture> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDepthTexture();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLDepthTexture(WebGLRenderingContext*);
+ WebGLDepthTexture(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp
index 20b21feb5fe..e5b6b48659f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp
@@ -27,36 +27,33 @@
#include "core/html/canvas/WebGLDrawBuffers.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContext* context)
+WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_EXT_draw_buffers");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_draw_buffers");
}
WebGLDrawBuffers::~WebGLDrawBuffers()
{
}
-WebGLExtension::ExtensionName WebGLDrawBuffers::name() const
+WebGLExtensionName WebGLDrawBuffers::name() const
{
- return WebGLExtension::WebGLDrawBuffersName;
+ return WebGLDrawBuffersName;
}
-PassRefPtr<WebGLDrawBuffers> WebGLDrawBuffers::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDrawBuffers> WebGLDrawBuffers::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDrawBuffers(context));
}
// static
-bool WebGLDrawBuffers::supported(WebGLRenderingContext* context)
+bool WebGLDrawBuffers::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return (extensions->supports("GL_EXT_draw_buffers")
+ return (context->extensionsUtil()->supportsExtension("GL_EXT_draw_buffers")
&& satisfiesWebGLRequirements(context));
}
@@ -65,12 +62,12 @@ const char* WebGLDrawBuffers::extensionName()
return "WEBGL_draw_buffers";
}
-void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
+void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GLenum>& buffers)
{
if (isLost())
return;
- GC3Dsizei n = buffers.size();
- const GC3Denum* bufs = buffers.data();
+ GLsizei n = buffers.size();
+ const GLenum* bufs = buffers.data();
if (!m_context->m_framebufferBinding) {
if (n != 1) {
m_context->synthesizeGLError(GL_INVALID_VALUE, "drawBuffersWEBGL", "more than one buffer");
@@ -81,16 +78,16 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
return;
}
// Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
- GC3Denum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE;
- m_context->graphicsContext3D()->extensions()->drawBuffersEXT(1, &value);
+ GLenum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE;
+ m_context->webContext()->drawBuffersEXT(1, &value);
m_context->setBackDrawBuffer(bufs[0]);
} else {
if (n > m_context->maxDrawBuffers()) {
m_context->synthesizeGLError(GL_INVALID_VALUE, "drawBuffersWEBGL", "more than max draw buffers");
return;
}
- for (GC3Dsizei i = 0; i < n; ++i) {
- if (bufs[i] != GL_NONE && bufs[i] != static_cast<GC3Denum>(Extensions3D::COLOR_ATTACHMENT0_EXT + i)) {
+ for (GLsizei i = 0; i < n; ++i) {
+ if (bufs[i] != GL_NONE && bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT + i)) {
m_context->synthesizeGLError(GL_INVALID_OPERATION, "drawBuffersWEBGL", "COLOR_ATTACHMENTi_EXT or NONE");
return;
}
@@ -100,15 +97,16 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
}
// static
-bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
+bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext)
{
- GraphicsContext3D* context = webglContext->graphicsContext3D();
+ blink::WebGraphicsContext3D* context = webglContext->webContext();
+ Extensions3DUtil* extensionsUtil = webglContext->extensionsUtil();
// This is called after we make sure GL_EXT_draw_buffers is supported.
- GC3Dint maxDrawBuffers = 0;
- GC3Dint maxColorAttachments = 0;
- context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
- context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments);
+ GLint maxDrawBuffers = 0;
+ GLint maxColorAttachments = 0;
+ context->getIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
+ context->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments);
if (maxDrawBuffers < 4 || maxColorAttachments < 4)
return false;
@@ -116,11 +114,11 @@ bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglCo
context->bindFramebuffer(GL_FRAMEBUFFER, fbo);
const unsigned char* buffer = 0; // Chromium doesn't allow init data for depth/stencil tetxures.
- bool supportsDepth = (context->extensions()->supports("GL_CHROMIUM_depth_texture")
- || context->extensions()->supports("GL_OES_depth_texture")
- || context->extensions()->supports("GL_ARB_depth_texture"));
- bool supportsDepthStencil = (context->extensions()->supports("GL_EXT_packed_depth_stencil")
- || context->extensions()->supports("GL_OES_packed_depth_stencil"));
+ bool supportsDepth = (extensionsUtil->supportsExtension("GL_CHROMIUM_depth_texture")
+ || extensionsUtil->supportsExtension("GL_OES_depth_texture")
+ || extensionsUtil->supportsExtension("GL_ARB_depth_texture"));
+ bool supportsDepthStencil = (extensionsUtil->supportsExtension("GL_EXT_packed_depth_stencil")
+ || extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil"));
Platform3DObject depthStencil = 0;
if (supportsDepthStencil) {
depthStencil = context->createTexture();
@@ -136,8 +134,8 @@ bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglCo
Vector<Platform3DObject> colors;
bool ok = true;
- GC3Dint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments);
- for (GC3Dint i = 0; i < maxAllowedBuffers; ++i) {
+ GLint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments);
+ for (GLint i = 0; i < maxAllowedBuffers; ++i) {
Platform3DObject color = context->createTexture();
colors.append(color);
context->bindTexture(GL_TEXTURE_2D, color);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h
index 58e14f12483..be66f91c99d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h
@@ -32,21 +32,21 @@
namespace WebCore {
-class WebGLDrawBuffers : public WebGLExtension, public ScriptWrappable {
+class WebGLDrawBuffers FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLDrawBuffers> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDrawBuffers> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDrawBuffers();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
- void drawBuffersWEBGL(const Vector<GC3Denum>& buffers);
+ void drawBuffersWEBGL(const Vector<GLenum>& buffers);
private:
- WebGLDrawBuffers(WebGLRenderingContext*);
+ WebGLDrawBuffers(WebGLRenderingContextBase*);
- static bool satisfiesWebGLRequirements(WebGLRenderingContext*);
+ static bool satisfiesWebGLRequirements(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp
index 9d3c9413c61..73efb94233b 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-WebGLExtension::WebGLExtension(WebGLRenderingContext* context)
+WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
: m_context(context)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h
index 1bd4c8bcae9..66e072ed2de 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h
@@ -26,7 +26,8 @@
#ifndef WebGLExtension_h
#define WebGLExtension_h
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLExtensionName.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "wtf/RefCounted.h"
namespace WebCore {
@@ -34,36 +35,14 @@ namespace WebCore {
class WebGLExtension : public RefCounted<WebGLExtension> {
WTF_MAKE_FAST_ALLOCATED;
public:
- // Extension names are needed to properly wrap instances in JavaScript objects.
- enum ExtensionName {
- ANGLEInstancedArraysName,
- EXTFragDepthName,
- EXTTextureFilterAnisotropicName,
- OESElementIndexUintName,
- OESStandardDerivativesName,
- OESTextureFloatLinearName,
- OESTextureFloatName,
- OESTextureHalfFloatLinearName,
- OESTextureHalfFloatName,
- OESVertexArrayObjectName,
- WebGLCompressedTextureATCName,
- WebGLCompressedTexturePVRTCName,
- WebGLCompressedTextureS3TCName,
- WebGLDebugRendererInfoName,
- WebGLDebugShadersName,
- WebGLDepthTextureName,
- WebGLDrawBuffersName,
- WebGLLoseContextName,
- };
-
- WebGLRenderingContext* context() { return m_context; }
+ WebGLRenderingContextBase* context() { return m_context; }
virtual ~WebGLExtension();
- virtual ExtensionName name() const = 0;
+ virtual WebGLExtensionName name() const = 0;
// Lose this extension. Passing true = force loss. Some extensions
// like WEBGL_lose_context are not normally lost when the context
- // is lost but must be lost when destroying their WebGLRenderingContext.
+ // is lost but must be lost when destroying their WebGLRenderingContextBase.
virtual void lose(bool)
{
m_context = 0;
@@ -75,9 +54,9 @@ public:
}
protected:
- WebGLExtension(WebGLRenderingContext*);
+ WebGLExtension(WebGLRenderingContextBase*);
- WebGLRenderingContext* m_context;
+ WebGLRenderingContextBase* m_context;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h
new file mode 100644
index 00000000000..6946fb1cd96
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WebGLExtensionName_h
+#define WebGLExtensionName_h
+
+namespace WebCore {
+
+// Extension names are needed to properly wrap instances in JavaScript objects.
+enum WebGLExtensionName {
+ ANGLEInstancedArraysName,
+ EXTBlendMinMaxName,
+ EXTFragDepthName,
+ EXTShaderTextureLODName,
+ EXTTextureFilterAnisotropicName,
+ OESElementIndexUintName,
+ OESStandardDerivativesName,
+ OESTextureFloatLinearName,
+ OESTextureFloatName,
+ OESTextureHalfFloatLinearName,
+ OESTextureHalfFloatName,
+ OESVertexArrayObjectName,
+ WebGLCompressedTextureATCName,
+ WebGLCompressedTextureETC1Name,
+ WebGLCompressedTexturePVRTCName,
+ WebGLCompressedTextureS3TCName,
+ WebGLDebugRendererInfoName,
+ WebGLDebugShadersName,
+ WebGLDepthTextureName,
+ WebGLDrawBuffersName,
+ WebGLLoseContextName,
+ WebGLExtensionNameCount, // Must be the last entry
+};
+
+}
+
+#endif // WebGLExtensionName_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp
index 7ab97df91d1..e968a306e5d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp
@@ -27,9 +27,8 @@
#include "core/html/canvas/WebGLFramebuffer.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "platform/NotImplemented.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
@@ -40,24 +39,22 @@ namespace {
return object ? object->object() : 0;
}
- class WebGLRenderbufferAttachment : public WebGLFramebuffer::WebGLAttachment {
+ class WebGLRenderbufferAttachment FINAL : public WebGLFramebuffer::WebGLAttachment {
public:
static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderbuffer*);
private:
WebGLRenderbufferAttachment(WebGLRenderbuffer*);
- virtual GC3Dsizei width() const;
- virtual GC3Dsizei height() const;
- virtual GC3Denum format() const;
- virtual GC3Denum type() const;
- virtual WebGLSharedObject* object() const;
- virtual bool isSharedObject(WebGLSharedObject*) const;
- virtual bool valid() const;
- virtual bool initialized() const;
- virtual void setInitialized();
- virtual void onDetached(GraphicsContext3D*);
- virtual void attach(GraphicsContext3D*, GC3Denum attachment);
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment);
+ virtual GLsizei width() const OVERRIDE;
+ virtual GLsizei height() const OVERRIDE;
+ virtual GLenum format() const OVERRIDE;
+ virtual GLenum type() const OVERRIDE;
+ virtual WebGLSharedObject* object() const OVERRIDE;
+ virtual bool isSharedObject(WebGLSharedObject*) const OVERRIDE;
+ virtual bool valid() const OVERRIDE;
+ virtual void onDetached(blink::WebGraphicsContext3D*) OVERRIDE;
+ virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
+ virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
WebGLRenderbufferAttachment() { };
@@ -74,19 +71,19 @@ namespace {
{
}
- GC3Dsizei WebGLRenderbufferAttachment::width() const
+ GLsizei WebGLRenderbufferAttachment::width() const
{
return m_renderbuffer->width();
}
- GC3Dsizei WebGLRenderbufferAttachment::height() const
+ GLsizei WebGLRenderbufferAttachment::height() const
{
return m_renderbuffer->height();
}
- GC3Denum WebGLRenderbufferAttachment::format() const
+ GLenum WebGLRenderbufferAttachment::format() const
{
- GC3Denum format = m_renderbuffer->internalFormat();
+ GLenum format = m_renderbuffer->internalFormat();
if (format == GL_DEPTH_STENCIL_OES
&& m_renderbuffer->emulatedStencilBuffer()
&& m_renderbuffer->emulatedStencilBuffer()->internalFormat() != GL_STENCIL_INDEX8) {
@@ -110,23 +107,12 @@ namespace {
return m_renderbuffer->object();
}
- bool WebGLRenderbufferAttachment::initialized() const
- {
- return m_renderbuffer->object() && m_renderbuffer->initialized();
- }
-
- void WebGLRenderbufferAttachment::setInitialized()
- {
- if (m_renderbuffer->object())
- m_renderbuffer->setInitialized();
- }
-
- void WebGLRenderbufferAttachment::onDetached(GraphicsContext3D* context)
+ void WebGLRenderbufferAttachment::onDetached(blink::WebGraphicsContext3D* context)
{
m_renderbuffer->onDetached(context);
}
- void WebGLRenderbufferAttachment::attach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLRenderbufferAttachment::attach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
Platform3DObject object = objectOrZero(m_renderbuffer.get());
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL && m_renderbuffer->emulatedStencilBuffer()) {
@@ -137,7 +123,7 @@ namespace {
}
}
- void WebGLRenderbufferAttachment::unattach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLRenderbufferAttachment::unattach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
@@ -147,61 +133,59 @@ namespace {
}
}
- GC3Denum WebGLRenderbufferAttachment::type() const
+ GLenum WebGLRenderbufferAttachment::type() const
{
notImplemented();
return 0;
}
- class WebGLTextureAttachment : public WebGLFramebuffer::WebGLAttachment {
+ class WebGLTextureAttachment FINAL : public WebGLFramebuffer::WebGLAttachment {
public:
- static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GC3Denum target, GC3Dint level);
+ static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GLenum target, GLint level);
private:
- WebGLTextureAttachment(WebGLTexture*, GC3Denum target, GC3Dint level);
- virtual GC3Dsizei width() const;
- virtual GC3Dsizei height() const;
- virtual GC3Denum format() const;
- virtual GC3Denum type() const;
- virtual WebGLSharedObject* object() const;
- virtual bool isSharedObject(WebGLSharedObject*) const;
- virtual bool valid() const;
- virtual bool initialized() const;
- virtual void setInitialized();
- virtual void onDetached(GraphicsContext3D*);
- virtual void attach(GraphicsContext3D*, GC3Denum attachment);
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment);
+ WebGLTextureAttachment(WebGLTexture*, GLenum target, GLint level);
+ virtual GLsizei width() const OVERRIDE;
+ virtual GLsizei height() const OVERRIDE;
+ virtual GLenum format() const OVERRIDE;
+ virtual GLenum type() const OVERRIDE;
+ virtual WebGLSharedObject* object() const OVERRIDE;
+ virtual bool isSharedObject(WebGLSharedObject*) const OVERRIDE;
+ virtual bool valid() const OVERRIDE;
+ virtual void onDetached(blink::WebGraphicsContext3D*) OVERRIDE;
+ virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
+ virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
WebGLTextureAttachment() { };
RefPtr<WebGLTexture> m_texture;
- GC3Denum m_target;
- GC3Dint m_level;
+ GLenum m_target;
+ GLint m_level;
};
- PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GC3Denum target, GC3Dint level)
+ PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GLenum target, GLint level)
{
return adoptRef(new WebGLTextureAttachment(texture, target, level));
}
- WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GC3Denum target, GC3Dint level)
+ WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GLenum target, GLint level)
: m_texture(texture)
, m_target(target)
, m_level(level)
{
}
- GC3Dsizei WebGLTextureAttachment::width() const
+ GLsizei WebGLTextureAttachment::width() const
{
return m_texture->getWidth(m_target, m_level);
}
- GC3Dsizei WebGLTextureAttachment::height() const
+ GLsizei WebGLTextureAttachment::height() const
{
return m_texture->getHeight(m_target, m_level);
}
- GC3Denum WebGLTextureAttachment::format() const
+ GLenum WebGLTextureAttachment::format() const
{
return m_texture->getInternalFormat(m_target, m_level);
}
@@ -221,29 +205,18 @@ namespace {
return m_texture->object();
}
- bool WebGLTextureAttachment::initialized() const
- {
- // Textures are assumed to be initialized.
- return true;
- }
-
- void WebGLTextureAttachment::setInitialized()
- {
- // Textures are assumed to be initialized.
- }
-
- void WebGLTextureAttachment::onDetached(GraphicsContext3D* context)
+ void WebGLTextureAttachment::onDetached(blink::WebGraphicsContext3D* context)
{
m_texture->onDetached(context);
}
- void WebGLTextureAttachment::attach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLTextureAttachment::attach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
Platform3DObject object = objectOrZero(m_texture.get());
context->framebufferTexture2D(GL_FRAMEBUFFER, attachment, m_target, object, m_level);
}
- void WebGLTextureAttachment::unattach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLTextureAttachment::unattach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
context->framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_target, 0, m_level);
@@ -253,12 +226,12 @@ namespace {
}
}
- GC3Denum WebGLTextureAttachment::type() const
+ GLenum WebGLTextureAttachment::type() const
{
return m_texture->getType(m_target, m_level);
}
- bool isColorRenderable(GC3Denum internalformat)
+ bool isColorRenderable(GLenum internalformat)
{
switch (internalformat) {
case GL_RGBA4:
@@ -280,17 +253,17 @@ WebGLFramebuffer::WebGLAttachment::~WebGLAttachment()
{
}
-PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLFramebuffer(ctx));
}
-WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx)
: WebGLContextObject(ctx)
, m_hasEverBeenBound(false)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createFramebuffer());
+ setObject(ctx->webContext()->createFramebuffer());
}
WebGLFramebuffer::~WebGLFramebuffer()
@@ -298,7 +271,7 @@ WebGLFramebuffer::~WebGLFramebuffer()
deleteObject(0);
}
-void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, GLenum texTarget, WebGLTexture* texture, GLint level)
{
ASSERT(isBound());
removeAttachmentFromBoundFramebuffer(attachment);
@@ -311,7 +284,7 @@ void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3
}
}
-void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, WebGLRenderbuffer* renderbuffer)
{
ASSERT(isBound());
removeAttachmentFromBoundFramebuffer(attachment);
@@ -324,15 +297,15 @@ void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, Web
}
}
-void WebGLFramebuffer::attach(GC3Denum attachment, GC3Denum attachmentPoint)
+void WebGLFramebuffer::attach(GLenum attachment, GLenum attachmentPoint)
{
ASSERT(isBound());
WebGLAttachment* attachmentObject = getAttachment(attachment);
if (attachmentObject)
- attachmentObject->attach(context()->graphicsContext3D(), attachmentPoint);
+ attachmentObject->attach(context()->webContext(), attachmentPoint);
}
-WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GC3Denum attachment) const
+WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) const
{
if (!object())
return 0;
@@ -340,12 +313,12 @@ WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GC3Denum attachment) co
return attachmentObject ? attachmentObject->object() : 0;
}
-bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3Denum attachment, const char** reason) const
+bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const
{
ASSERT(attachedObject && attachedObject->valid());
ASSERT(reason);
- GC3Denum internalformat = attachedObject->format();
+ GLenum internalformat = attachedObject->format();
WebGLSharedObject* object = attachedObject->object();
ASSERT(object && (object->isTexture() || object->isRenderbuffer()));
@@ -356,8 +329,8 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
return false;
}
} else if (object->isTexture()) {
- GC3Denum type = attachedObject->type();
- if (!(context()->m_webglDepthTexture && internalformat == GL_DEPTH_COMPONENT
+ GLenum type = attachedObject->type();
+ if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_COMPONENT
&& (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT))) {
*reason = "the attached texture is not a depth texture";
return false;
@@ -379,23 +352,23 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
return false;
}
} else if (object->isTexture()) {
- GC3Denum type = attachedObject->type();
- if (!(context()->m_webglDepthTexture && internalformat == GL_DEPTH_STENCIL_OES
+ GLenum type = attachedObject->type();
+ if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_STENCIL_OES
&& type == GL_UNSIGNED_INT_24_8_OES)) {
*reason = "the attached texture is not a DEPTH_STENCIL texture";
return false;
}
}
} else if (attachment == GL_COLOR_ATTACHMENT0
- || (context()->m_webglDrawBuffers && attachment > GL_COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))) {
+ || (context()->extensionEnabled(WebGLDrawBuffersName) && attachment > GL_COLOR_ATTACHMENT0
+ && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))) {
if (object->isRenderbuffer()) {
if (!isColorRenderable(internalformat)) {
*reason = "the internalformat of the attached renderbuffer is not color-renderable";
return false;
}
} else if (object->isTexture()) {
- GC3Denum type = attachedObject->type();
+ GLenum type = attachedObject->type();
if (internalformat != GL_RGBA && internalformat != GL_RGB) {
*reason = "the internalformat of the attached texture is not color-renderable";
return false;
@@ -408,8 +381,8 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
&& type != GL_UNSIGNED_SHORT_5_6_5
&& type != GL_UNSIGNED_SHORT_4_4_4_4
&& type != GL_UNSIGNED_SHORT_5_5_5_1
- && !(type == GL_FLOAT && context()->m_oesTextureFloat)
- && !(type == GL_HALF_FLOAT_OES && context()->m_oesTextureHalfFloat)) {
+ && !(type == GL_FLOAT && context()->extensionEnabled(OESTextureFloatName))
+ && !(type == GL_HALF_FLOAT_OES && context()->extensionEnabled(OESTextureHalfFloatName))) {
*reason = "unsupported type: The attached texture is not supported to be rendered to";
return false;
}
@@ -426,13 +399,13 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
return true;
}
-WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
+WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum attachment) const
{
const AttachmentMap::const_iterator it = m_attachments.find(attachment);
return (it != m_attachments.end()) ? it->value.get() : 0;
}
-void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment)
{
ASSERT(isBound());
if (!object())
@@ -440,7 +413,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
WebGLAttachment* attachmentObject = getAttachment(attachment);
if (attachmentObject) {
- attachmentObject->onDetached(context()->graphicsContext3D());
+ attachmentObject->onDetached(context()->webContext());
m_attachments.remove(attachment);
drawBuffersIfNecessary(false);
switch (attachment) {
@@ -472,8 +445,8 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) {
WebGLAttachment* attachmentObject = it->value.get();
if (attachmentObject->isSharedObject(attachment)) {
- GC3Denum attachmentType = it->key;
- attachmentObject->unattach(context()->graphicsContext3D(), attachmentType);
+ GLenum attachmentType = it->key;
+ attachmentObject->unattach(context()->webContext(), attachmentType);
removeAttachmentFromBoundFramebuffer(attachmentType);
checkMore = true;
break;
@@ -482,29 +455,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
}
}
-GC3Dsizei WebGLFramebuffer::colorBufferWidth() const
-{
- if (!object())
- return 0;
- WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0);
- if (!attachment)
- return 0;
-
- return attachment->width();
-}
-
-GC3Dsizei WebGLFramebuffer::colorBufferHeight() const
-{
- if (!object())
- return 0;
- WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0);
- if (!attachment)
- return 0;
-
- return attachment->height();
-}
-
-GC3Denum WebGLFramebuffer::colorBufferFormat() const
+GLenum WebGLFramebuffer::colorBufferFormat() const
{
if (!object())
return 0;
@@ -514,10 +465,10 @@ GC3Denum WebGLFramebuffer::colorBufferFormat() const
return attachment->format();
}
-GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
+GLenum WebGLFramebuffer::checkStatus(const char** reason) const
{
- unsigned int count = 0;
- GC3Dsizei width = 0, height = 0;
+ unsigned count = 0;
+ GLsizei width = 0, height = 0;
bool haveDepth = false;
bool haveStencil = false;
bool haveDepthStencil = false;
@@ -571,7 +522,7 @@ GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
return GL_FRAMEBUFFER_COMPLETE;
}
-bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, const char** reason)
+bool WebGLFramebuffer::onAccess(blink::WebGraphicsContext3D* context3d, const char** reason)
{
if (checkStatus(reason) != GL_FRAMEBUFFER_COMPLETE)
return false;
@@ -586,7 +537,7 @@ bool WebGLFramebuffer::hasStencilBuffer() const
return attachment && attachment->valid();
}
-void WebGLFramebuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLFramebuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
it->value->onDetached(context3d);
@@ -599,7 +550,7 @@ bool WebGLFramebuffer::isBound() const
return (context()->m_framebufferBinding.get() == this);
}
-void WebGLFramebuffer::drawBuffers(const Vector<GC3Denum>& bufs)
+void WebGLFramebuffer::drawBuffers(const Vector<GLenum>& bufs)
{
m_drawBuffers = bufs;
m_filteredDrawBuffers.resize(m_drawBuffers.size());
@@ -610,7 +561,7 @@ void WebGLFramebuffer::drawBuffers(const Vector<GC3Denum>& bufs)
void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
{
- if (!context()->m_webglDrawBuffers)
+ if (!context()->extensionEnabled(WebGLDrawBuffersName))
return;
bool reset = force;
// This filtering works around graphics driver bugs on Mac OS X.
@@ -628,18 +579,18 @@ void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
}
}
if (reset) {
- context()->graphicsContext3D()->extensions()->drawBuffersEXT(
+ context()->webContext()->drawBuffersEXT(
m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
}
}
-GC3Denum WebGLFramebuffer::getDrawBuffer(GC3Denum drawBuffer)
+GLenum WebGLFramebuffer::getDrawBuffer(GLenum drawBuffer)
{
- int index = static_cast<int>(drawBuffer - Extensions3D::DRAW_BUFFER0_EXT);
+ int index = static_cast<int>(drawBuffer - GL_DRAW_BUFFER0_EXT);
ASSERT(index >= 0);
if (index < static_cast<int>(m_drawBuffers.size()))
return m_drawBuffers[index];
- if (drawBuffer == Extensions3D::DRAW_BUFFER0_EXT)
+ if (drawBuffer == GL_DRAW_BUFFER0_EXT)
return GL_COLOR_ATTACHMENT0;
return GL_NONE;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h
index 86e2aebf4e8..e8705e61187 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h
@@ -37,28 +37,26 @@ namespace WebCore {
class WebGLRenderbuffer;
class WebGLTexture;
-class WebGLFramebuffer : public WebGLContextObject, public ScriptWrappable {
+class WebGLFramebuffer FINAL : public WebGLContextObject, public ScriptWrappable {
public:
class WebGLAttachment : public RefCounted<WebGLAttachment> {
public:
virtual ~WebGLAttachment();
- virtual GC3Dsizei width() const = 0;
- virtual GC3Dsizei height() const = 0;
- virtual GC3Denum format() const = 0;
+ virtual GLsizei width() const = 0;
+ virtual GLsizei height() const = 0;
+ virtual GLenum format() const = 0;
// For texture attachment, type() returns the type of the attached texture.
// For renderbuffer attachment, the type of the renderbuffer may vary with GL implementation.
// To avoid confusion, it would be better to not implement type() for renderbuffer attachment and
// we should always use the internalformat of the renderbuffer and avoid using type() API.
- virtual GC3Denum type() const = 0;
+ virtual GLenum type() const = 0;
virtual WebGLSharedObject* object() const = 0;
virtual bool isSharedObject(WebGLSharedObject*) const = 0;
virtual bool valid() const = 0;
- virtual bool initialized() const = 0;
- virtual void setInitialized() = 0;
- virtual void onDetached(GraphicsContext3D*) = 0;
- virtual void attach(GraphicsContext3D*, GC3Denum attachment) = 0;
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment) = 0;
+ virtual void onDetached(blink::WebGraphicsContext3D*) = 0;
+ virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) = 0;
+ virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) = 0;
protected:
WebGLAttachment();
@@ -66,33 +64,29 @@ public:
virtual ~WebGLFramebuffer();
- static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContextBase*);
- void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
- void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
+ void setAttachmentForBoundFramebuffer(GLenum attachment, GLenum texTarget, WebGLTexture*, GLint level);
+ void setAttachmentForBoundFramebuffer(GLenum attachment, WebGLRenderbuffer*);
// If an object is attached to the currently bound framebuffer, remove it.
void removeAttachmentFromBoundFramebuffer(WebGLSharedObject*);
// If a given attachment point for the currently bound framebuffer is not null, remove the attached object.
- void removeAttachmentFromBoundFramebuffer(GC3Denum);
- WebGLSharedObject* getAttachmentObject(GC3Denum) const;
+ void removeAttachmentFromBoundFramebuffer(GLenum);
+ WebGLSharedObject* getAttachmentObject(GLenum) const;
- GC3Denum colorBufferFormat() const;
- GC3Dsizei colorBufferWidth() const;
- GC3Dsizei colorBufferHeight() const;
+ GLenum colorBufferFormat() 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
- // needToInitializeAttachments is true.
- bool onAccess(GraphicsContext3D*, const char** reason);
+ // Return false if the framebuffer is incomplete.
+ bool onAccess(blink::WebGraphicsContext3D*, const char** reason);
// Software version of glCheckFramebufferStatus(), except that when
// FRAMEBUFFER_COMPLETE is returned, it is still possible for
// glCheckFramebufferStatus() to return FRAMEBUFFER_UNSUPPORTED,
// depending on hardware implementation.
- GC3Denum checkStatus(const char** reason) const;
+ GLenum checkStatus(const char** reason) const;
bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
@@ -101,38 +95,36 @@ public:
bool hasStencilBuffer() const;
// Wrapper for drawBuffersEXT/drawBuffersARB to work around a driver bug.
- void drawBuffers(const Vector<GC3Denum>& bufs);
+ void drawBuffers(const Vector<GLenum>& bufs);
- GC3Denum getDrawBuffer(GC3Denum);
+ GLenum getDrawBuffer(GLenum);
protected:
- WebGLFramebuffer(WebGLRenderingContext*);
+ WebGLFramebuffer(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isFramebuffer() const { return true; }
-
- WebGLAttachment* getAttachment(GC3Denum) const;
- bool isAttachmentComplete(WebGLAttachment* attachedObject, GC3Denum attachment, const char** reason) const;
+ WebGLAttachment* getAttachment(GLenum) const;
+ bool isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const;
// Check if the framebuffer is currently bound.
bool isBound() const;
// attach 'attachment' at 'attachmentPoint'.
- void attach(GC3Denum attachment, GC3Denum attachmentPoint);
+ void attach(GLenum attachment, GLenum attachmentPoint);
// Check if a new drawBuffers call should be issued. This is called when we add or remove an attachment.
void drawBuffersIfNecessary(bool force);
- typedef WTF::HashMap<GC3Denum, RefPtr<WebGLAttachment> > AttachmentMap;
+ typedef WTF::HashMap<GLenum, RefPtr<WebGLAttachment> > AttachmentMap;
AttachmentMap m_attachments;
bool m_hasEverBeenBound;
- Vector<GC3Denum> m_drawBuffers;
- Vector<GC3Denum> m_filteredDrawBuffers;
+ Vector<GLenum> m_drawBuffers;
+ Vector<GLenum> m_filteredDrawBuffers;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp
index 55cead3c16f..d4f893bc0d2 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp
@@ -90,7 +90,7 @@ WebGLGetInfo::WebGLGetInfo(const String& value)
{
}
-WebGLGetInfo::WebGLGetInfo(unsigned int value)
+WebGLGetInfo::WebGLGetInfo(unsigned value)
: m_type(kTypeUnsignedInt)
, m_bool(false)
, m_float(0)
@@ -234,7 +234,7 @@ const String& WebGLGetInfo::getString() const
return m_string;
}
-unsigned int WebGLGetInfo::getUnsignedInt() const
+unsigned WebGLGetInfo::getUnsignedInt() const
{
ASSERT(getType() == kTypeUnsignedInt);
return m_unsignedInt;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h
index d72e7f9c65a..4528bb4a2b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h
@@ -78,7 +78,7 @@ public:
// Represents the null value and type.
WebGLGetInfo();
explicit WebGLGetInfo(const String& value);
- explicit WebGLGetInfo(unsigned int value);
+ explicit WebGLGetInfo(unsigned value);
explicit WebGLGetInfo(PassRefPtr<WebGLBuffer> value);
explicit WebGLGetInfo(PassRefPtr<Float32Array> value);
explicit WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value);
@@ -99,7 +99,7 @@ public:
float getFloat() const;
int getInt() const;
const String& getString() const;
- unsigned int getUnsignedInt() const;
+ unsigned getUnsignedInt() const;
PassRefPtr<WebGLBuffer> getWebGLBuffer() const;
PassRefPtr<Float32Array> getWebGLFloatArray() const;
PassRefPtr<WebGLFramebuffer> getWebGLFramebuffer() const;
@@ -120,7 +120,7 @@ private:
float m_float;
int m_int;
String m_string;
- unsigned int m_unsignedInt;
+ unsigned m_unsignedInt;
RefPtr<WebGLBuffer> m_webglBuffer;
RefPtr<Float32Array> m_webglFloatArray;
RefPtr<WebGLFramebuffer> m_webglFramebuffer;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp
index ca1226a9ba2..e2fe7bd738d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp
@@ -27,11 +27,11 @@
#include "core/html/canvas/WebGLLoseContext.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLLoseContext::WebGLLoseContext(WebGLRenderingContext* context)
+WebGLLoseContext::WebGLLoseContext(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
@@ -47,12 +47,12 @@ void WebGLLoseContext::lose(bool force)
WebGLExtension::lose(true);
}
-WebGLExtension::ExtensionName WebGLLoseContext::name() const
+WebGLExtensionName WebGLLoseContext::name() const
{
return WebGLLoseContextName;
}
-PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLLoseContext(context));
}
@@ -60,7 +60,7 @@ PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* con
void WebGLLoseContext::loseContext()
{
if (!isLost())
- m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+ m_context->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
}
void WebGLLoseContext::restoreContext()
@@ -69,7 +69,7 @@ void WebGLLoseContext::restoreContext()
m_context->forceRestoreContext();
}
-bool WebGLLoseContext::supported(WebGLRenderingContext*)
+bool WebGLLoseContext::supported(WebGLRenderingContextBase*)
{
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h
index 23140d62632..cab49f34740 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h
@@ -32,23 +32,23 @@
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-class WebGLLoseContext : public WebGLExtension, public ScriptWrappable {
+class WebGLLoseContext FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLLoseContext> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLLoseContext> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLLoseContext();
- virtual ExtensionName name() const;
- virtual void lose(bool);
+ virtual WebGLExtensionName name() const OVERRIDE;
+ virtual void lose(bool) OVERRIDE;
void loseContext();
void restoreContext();
private:
- WebGLLoseContext(WebGLRenderingContext*);
+ WebGLLoseContext(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl
index 1ac288f2489..117fcf221ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl
@@ -24,8 +24,9 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
+ TypeChecking=Interface|Nullable,
] interface WebGLLoseContext {
- [StrictTypeChecking] void loseContext();
- [StrictTypeChecking] void restoreContext();
+ void loseContext();
+ void restoreContext();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp
index 3ffddaad3fd..14dd8ba5ee8 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-WebGLObject::WebGLObject(WebGLRenderingContext*)
+WebGLObject::WebGLObject(WebGLRenderingContextBase*)
: m_object(0)
, m_attachmentCount(0)
, m_deleted(false)
@@ -47,7 +47,7 @@ void WebGLObject::setObject(Platform3DObject object)
m_object = object;
}
-void WebGLObject::deleteObject(GraphicsContext3D* context3d)
+void WebGLObject::deleteObject(blink::WebGraphicsContext3D* context3d)
{
m_deleted = true;
if (!m_object)
@@ -58,7 +58,7 @@ void WebGLObject::deleteObject(GraphicsContext3D* context3d)
if (!m_attachmentCount) {
if (!context3d)
- context3d = getAGraphicsContext3D();
+ context3d = getAWebGraphicsContext3D();
if (context3d)
deleteObjectImpl(context3d, m_object);
@@ -73,7 +73,7 @@ void WebGLObject::detach()
}
-void WebGLObject::onDetached(GraphicsContext3D* context3d)
+void WebGLObject::onDetached(blink::WebGraphicsContext3D* context3d)
{
if (m_attachmentCount)
--m_attachmentCount;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h
index 55a7d51e2da..ae5c439c8a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h
@@ -26,14 +26,17 @@
#ifndef WebGLObject_h
#define WebGLObject_h
-#include "platform/graphics/GraphicsContext3D.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/RefCounted.h"
+namespace blink {
+class WebGraphicsContext3D;
+}
+
namespace WebCore {
-class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
class WebGLObject : public RefCounted<WebGLObject> {
public:
@@ -44,10 +47,10 @@ public:
// 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(GraphicsContext3D*);
+ void deleteObject(blink::WebGraphicsContext3D*);
void onAttached() { ++m_attachmentCount; }
- void onDetached(GraphicsContext3D*);
+ void onDetached(blink::WebGraphicsContext3D*);
// This indicates whether the client side issue a delete call already, not
// whether the OpenGL resource is deleted.
@@ -55,22 +58,22 @@ public:
bool isDeleted() { return m_deleted; }
// True if this object belongs to the group or context.
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext*) const = 0;
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase*) const = 0;
protected:
- WebGLObject(WebGLRenderingContext*);
+ WebGLObject(WebGLRenderingContextBase*);
// 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(GraphicsContext3D*, Platform3DObject) = 0;
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) = 0;
virtual bool hasGroupOrContext() const = 0;
virtual void detach();
- virtual GraphicsContext3D* getAGraphicsContext3D() const = 0;
+ virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const = 0;
private:
Platform3DObject m_object;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp
index 6a1539331f9..e1e49594139 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp
@@ -27,23 +27,23 @@
#include "core/html/canvas/WebGLProgram.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLProgram(ctx));
}
-WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
+WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_linkStatus(false)
, m_linkCount(0)
, m_infoValid(true)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createProgram());
+ setObject(ctx->webContext()->createProgram());
}
WebGLProgram::~WebGLProgram()
@@ -51,16 +51,16 @@ WebGLProgram::~WebGLProgram()
deleteObject(0);
}
-void WebGLProgram::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject obj)
+void WebGLProgram::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject obj)
{
context3d->deleteProgram(obj);
if (m_vertexShader) {
m_vertexShader->onDetached(context3d);
- m_vertexShader = 0;
+ m_vertexShader = nullptr;
}
if (m_fragmentShader) {
m_fragmentShader->onDetached(context3d);
- m_fragmentShader = 0;
+ m_fragmentShader = nullptr;
}
}
@@ -70,7 +70,7 @@ unsigned WebGLProgram::numActiveAttribLocations()
return m_activeAttribLocations.size();
}
-GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index)
+GLint WebGLProgram::getActiveAttribLocation(GLuint index)
{
cacheInfoIfNeeded();
if (index >= numActiveAttribLocations())
@@ -94,19 +94,13 @@ bool WebGLProgram::linkStatus()
return m_linkStatus;
}
-void WebGLProgram::setLinkStatus(bool status)
-{
- cacheInfoIfNeeded();
- m_linkStatus = status;
-}
-
void WebGLProgram::increaseLinkCount()
{
++m_linkCount;
m_infoValid = false;
}
-WebGLShader* WebGLProgram::getAttachedShader(GC3Denum type)
+WebGLShader* WebGLProgram::getAttachedShader(GLenum type)
{
switch (type) {
case GL_VERTEX_SHADER:
@@ -146,29 +140,29 @@ bool WebGLProgram::detachShader(WebGLShader* shader)
case GL_VERTEX_SHADER:
if (m_vertexShader != shader)
return false;
- m_vertexShader = 0;
+ m_vertexShader = nullptr;
return true;
case GL_FRAGMENT_SHADER:
if (m_fragmentShader != shader)
return false;
- m_fragmentShader = 0;
+ m_fragmentShader = nullptr;
return true;
default:
return false;
}
}
-void WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
+void WebGLProgram::cacheActiveAttribLocations(blink::WebGraphicsContext3D* context3d)
{
m_activeAttribLocations.clear();
- GC3Dint numAttribs = 0;
+ GLint numAttribs = 0;
context3d->getProgramiv(object(), GL_ACTIVE_ATTRIBUTES, &numAttribs);
m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
for (int i = 0; i < numAttribs; ++i) {
- ActiveInfo info;
+ blink::WebGraphicsContext3D::ActiveInfo info;
context3d->getActiveAttrib(object(), i, info);
- m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name);
+ m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.utf8().data());
}
}
@@ -180,10 +174,10 @@ void WebGLProgram::cacheInfoIfNeeded()
if (!object())
return;
- GraphicsContext3D* context = getAGraphicsContext3D();
+ blink::WebGraphicsContext3D* context = getAWebGraphicsContext3D();
if (!context)
return;
- GC3Dint linkStatus = 0;
+ GLint linkStatus = 0;
context->getProgramiv(object(), GL_LINK_STATUS, &linkStatus);
m_linkStatus = linkStatus;
if (m_linkStatus)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h
index 5ba00e7cf70..f68b33048ae 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h
@@ -34,19 +34,18 @@
namespace WebCore {
-class WebGLProgram : public WebGLSharedObject, public ScriptWrappable {
+class WebGLProgram FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLProgram();
- static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLProgram> create(WebGLRenderingContextBase*);
unsigned numActiveAttribLocations();
- GC3Dint getActiveAttribLocation(GC3Duint index);
+ GLint getActiveAttribLocation(GLuint index);
bool isUsingVertexAttrib0();
bool linkStatus();
- void setLinkStatus(bool);
unsigned linkCount() const { return m_linkCount; }
@@ -56,24 +55,24 @@ public:
// Also, we invalidate the cached program info.
void increaseLinkCount();
- WebGLShader* getAttachedShader(GC3Denum);
+ WebGLShader* getAttachedShader(GLenum);
bool attachShader(WebGLShader*);
bool detachShader(WebGLShader*);
protected:
- WebGLProgram(WebGLRenderingContext*);
+ WebGLProgram(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isProgram() const { return true; }
+ virtual bool isProgram() const OVERRIDE { return true; }
- void cacheActiveAttribLocations(GraphicsContext3D*);
+ void cacheActiveAttribLocations(blink::WebGraphicsContext3D*);
void cacheInfoIfNeeded();
- Vector<GC3Dint> m_activeAttribLocations;
+ Vector<GLint> m_activeAttribLocations;
- GC3Dint m_linkStatus;
+ GLint m_linkStatus;
// This is used to track whether a WebGLUniformLocation belongs to this
// program or not.
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp
index da27596f273..76ef482e037 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp
@@ -27,11 +27,11 @@
#include "core/html/canvas/WebGLRenderbuffer.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLRenderbuffer(ctx));
}
@@ -41,25 +41,24 @@ WebGLRenderbuffer::~WebGLRenderbuffer()
deleteObject(0);
}
-WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_internalFormat(GL_RGBA4)
- , m_initialized(false)
, m_width(0)
, m_height(0)
, m_hasEverBeenBound(false)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createRenderbuffer());
+ setObject(ctx->webContext()->createRenderbuffer());
}
-void WebGLRenderbuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLRenderbuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteRenderbuffer(object);
deleteEmulatedStencilBuffer(context3d);
}
-void WebGLRenderbuffer::deleteEmulatedStencilBuffer(GraphicsContext3D* context3d)
+void WebGLRenderbuffer::deleteEmulatedStencilBuffer(blink::WebGraphicsContext3D* context3d)
{
if (!m_emulatedStencilBuffer)
return;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h
index 95688a20d26..4c08712de63 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h
@@ -32,29 +32,25 @@
namespace WebCore {
-class WebGLRenderbuffer : public WebGLSharedObject, public ScriptWrappable {
+class WebGLRenderbuffer FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLRenderbuffer();
- static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContextBase*);
- void setInternalFormat(GC3Denum internalformat)
+ void setInternalFormat(GLenum internalformat)
{
m_internalFormat = internalformat;
- m_initialized = false;
}
- GC3Denum internalFormat() const { return m_internalFormat; }
+ GLenum internalFormat() const { return m_internalFormat; }
- void setSize(GC3Dsizei width, GC3Dsizei height)
+ void setSize(GLsizei width, GLsizei height)
{
m_width = width;
m_height = height;
}
- GC3Dsizei width() const { return m_width; }
- GC3Dsizei height() const { return m_height; }
-
- bool initialized() const { return m_initialized; }
- void setInitialized() { m_initialized = true; }
+ GLsizei width() const { return m_width; }
+ GLsizei height() const { return m_height; }
bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
@@ -62,19 +58,18 @@ public:
void setEmulatedStencilBuffer(PassRefPtr<WebGLRenderbuffer> buffer) { m_emulatedStencilBuffer = buffer; }
WebGLRenderbuffer* emulatedStencilBuffer() const { return m_emulatedStencilBuffer.get(); }
- void deleteEmulatedStencilBuffer(GraphicsContext3D* context3d);
+ void deleteEmulatedStencilBuffer(blink::WebGraphicsContext3D* context3d);
protected:
- WebGLRenderbuffer(WebGLRenderingContext*);
+ WebGLRenderbuffer(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isRenderbuffer() const { return true; }
+ virtual bool isRenderbuffer() const OVERRIDE { return true; }
- GC3Denum m_internalFormat;
- bool m_initialized;
- GC3Dsizei m_width, m_height;
+ GLenum m_internalFormat;
+ GLsizei m_width, m_height;
bool m_hasEverBeenBound;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp
index ed0d58811ad..e1d1c070724 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp
@@ -26,17 +26,11 @@
#include "config.h"
#include "core/html/canvas/WebGLRenderingContext.h"
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLCanvasElement.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/ImageData.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/canvas/ANGLEInstancedArrays.h"
+#include "core/html/canvas/EXTBlendMinMax.h"
#include "core/html/canvas/EXTFragDepth.h"
+#include "core/html/canvas/EXTShaderTextureLOD.h"
#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
#include "core/html/canvas/OESElementIndexUint.h"
#include "core/html/canvas/OESStandardDerivatives.h"
@@ -45,458 +39,36 @@
#include "core/html/canvas/OESTextureHalfFloat.h"
#include "core/html/canvas/OESTextureHalfFloatLinear.h"
#include "core/html/canvas/OESVertexArrayObject.h"
-#include "core/html/canvas/WebGLActiveInfo.h"
-#include "core/html/canvas/WebGLBuffer.h"
#include "core/html/canvas/WebGLCompressedTextureATC.h"
+#include "core/html/canvas/WebGLCompressedTextureETC1.h"
#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
#include "core/html/canvas/WebGLContextAttributes.h"
#include "core/html/canvas/WebGLContextEvent.h"
-#include "core/html/canvas/WebGLContextGroup.h"
#include "core/html/canvas/WebGLDebugRendererInfo.h"
#include "core/html/canvas/WebGLDebugShaders.h"
#include "core/html/canvas/WebGLDepthTexture.h"
#include "core/html/canvas/WebGLDrawBuffers.h"
-#include "core/html/canvas/WebGLFramebuffer.h"
#include "core/html/canvas/WebGLLoseContext.h"
-#include "core/html/canvas/WebGLProgram.h"
-#include "core/html/canvas/WebGLRenderbuffer.h"
-#include "core/html/canvas/WebGLShader.h"
-#include "core/html/canvas/WebGLShaderPrecisionFormat.h"
-#include "core/html/canvas/WebGLTexture.h"
-#include "core/html/canvas/WebGLUniformLocation.h"
-#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "core/frame/Settings.h"
#include "core/rendering/RenderBox.h"
#include "platform/CheckedInt.h"
#include "platform/NotImplemented.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/graphics/Extensions3D.h"
-#include "platform/graphics/UnacceleratedImageBufferSurface.h"
#include "platform/graphics/gpu/DrawingBuffer.h"
-
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Uint32Array.h"
-#include "wtf/text/StringBuilder.h"
+#include "public/platform/Platform.h"
namespace WebCore {
-const double secondsBetweenRestoreAttempts = 1.0;
-const int maxGLErrorsAllowedToConsole = 256;
-const unsigned maxGLActiveContexts = 16;
-
-Vector<WebGLRenderingContext*>& WebGLRenderingContext::activeContexts()
-{
- DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, activeContexts, ());
- return activeContexts;
-}
-
-Vector<WebGLRenderingContext*>& WebGLRenderingContext::forciblyEvictedContexts()
-{
- DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, forciblyEvictedContexts, ());
- return forciblyEvictedContexts;
-}
-
-void WebGLRenderingContext::forciblyLoseOldestContext(const String& reason)
-{
- size_t candidateID = oldestContextIndex();
- if (candidateID >= activeContexts().size())
- return;
-
- WebGLRenderingContext* candidate = activeContexts()[candidateID];
-
- activeContexts().remove(candidateID);
-
- candidate->printWarningToConsole(reason);
- InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
-
- // This will call deactivateContext once the context has actually been lost.
- candidate->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
-}
-
-size_t WebGLRenderingContext::oldestContextIndex()
-{
- if (!activeContexts().size())
- return maxGLActiveContexts;
-
- WebGLRenderingContext* candidate = activeContexts().first();
- size_t candidateID = 0;
- for (size_t ii = 1; ii < activeContexts().size(); ++ii) {
- WebGLRenderingContext* context = activeContexts()[ii];
- if (context->graphicsContext3D() && candidate->graphicsContext3D() && context->graphicsContext3D()->lastFlushID() < candidate->graphicsContext3D()->lastFlushID()) {
- candidate = context;
- candidateID = ii;
- }
- }
-
- return candidateID;
-}
-
-IntSize WebGLRenderingContext::oldestContextSize()
-{
- IntSize size;
-
- size_t candidateID = oldestContextIndex();
- if (candidateID < activeContexts().size()) {
- WebGLRenderingContext* candidate = activeContexts()[candidateID];
- size.setWidth(candidate->drawingBufferWidth());
- size.setHeight(candidate->drawingBufferHeight());
- }
-
- return size;
-}
-
-void WebGLRenderingContext::activateContext(WebGLRenderingContext* context)
-{
- unsigned removedContexts = 0;
- while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) {
- forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost.");
- removedContexts++;
- }
-
- if (!activeContexts().contains(context))
- activeContexts().append(context);
-}
-
-void WebGLRenderingContext::deactivateContext(WebGLRenderingContext* context, bool addToEvictedList)
-{
- size_t position = activeContexts().find(context);
- if (position != WTF::kNotFound)
- activeContexts().remove(position);
-
- if (addToEvictedList && !forciblyEvictedContexts().contains(context))
- forciblyEvictedContexts().append(context);
-}
-
-void WebGLRenderingContext::willDestroyContext(WebGLRenderingContext* context)
-{
- size_t position = forciblyEvictedContexts().find(context);
- if (position != WTF::kNotFound)
- forciblyEvictedContexts().remove(position);
-
- deactivateContext(context, false);
-
- // Try to re-enable the oldest inactive contexts.
- while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) {
- WebGLRenderingContext* evictedContext = forciblyEvictedContexts().first();
- if (!evictedContext->m_restoreAllowed) {
- forciblyEvictedContexts().remove(0);
- continue;
- }
-
- IntSize desiredSize = evictedContext->m_drawingBuffer->adjustSize(evictedContext->clampedCanvasSize());
-
- // If there's room in the pixel budget for this context, restore it.
- if (!desiredSize.isEmpty()) {
- forciblyEvictedContexts().remove(0);
- evictedContext->forceRestoreContext();
- activeContexts().append(evictedContext);
- }
- break;
- }
-}
-
-class WebGLRenderingContextEvictionManager : public ContextEvictionManager {
-public:
- void forciblyLoseOldestContext(const String& reason) {
- WebGLRenderingContext::forciblyLoseOldestContext(reason);
- };
- IntSize oldestContextSize() {
- return WebGLRenderingContext::oldestContextSize();
- };
-};
-
-namespace {
-
- class ScopedDrawingBufferBinder {
- public:
- ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
- : m_drawingBuffer(drawingBuffer)
- , m_framebufferBinding(framebufferBinding)
- {
- // Commit DrawingBuffer if needed (e.g., for multisampling)
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->commit();
- }
-
- ~ScopedDrawingBufferBinder()
- {
- // Restore DrawingBuffer if needed
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->bind();
- }
-
- private:
- DrawingBuffer* m_drawingBuffer;
- WebGLFramebuffer* m_framebufferBinding;
- };
-
- Platform3DObject objectOrZero(WebGLObject* object)
- {
- return object ? object->object() : 0;
- }
-
- GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
- {
- if (value < min)
- value = min;
- if (value > max)
- value = max;
- return value;
- }
-
- // Return true if a character belongs to the ASCII subset as defined in
- // GLSL ES 1.0 spec section 3.1.
- bool validateCharacter(unsigned char c)
- {
- // Printing characters are valid except " $ ` @ \ ' DEL.
- if (c >= 32 && c <= 126
- && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
- return true;
- // Horizontal tab, line feed, vertical tab, form feed, carriage return
- // are also valid.
- if (c >= 9 && c <= 13)
- return true;
- return false;
- }
-
- bool isPrefixReserved(const String& name)
- {
- if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
- return true;
- return false;
- }
-
- // Strips comments from shader text. This allows non-ASCII characters
- // to be used in comments without potentially breaking OpenGL
- // implementations not expecting characters outside the GLSL ES set.
- class StripComments {
- public:
- StripComments(const String& str)
- : m_parseState(BeginningOfLine)
- , m_sourceString(str)
- , m_length(str.length())
- , m_position(0)
- {
- parse();
- }
-
- String result()
- {
- return m_builder.toString();
- }
-
- private:
- bool hasMoreCharacters() const
- {
- return (m_position < m_length);
- }
-
- void parse()
- {
- while (hasMoreCharacters()) {
- process(current());
- // process() might advance the position.
- if (hasMoreCharacters())
- advance();
- }
- }
-
- void process(UChar);
-
- bool peek(UChar& character) const
- {
- if (m_position + 1 >= m_length)
- return false;
- character = m_sourceString[m_position + 1];
- return true;
- }
-
- UChar current()
- {
- ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
- return m_sourceString[m_position];
- }
-
- void advance()
- {
- ++m_position;
- }
-
- static bool isNewline(UChar character)
- {
- // Don't attempt to canonicalize newline related characters.
- return (character == '\n' || character == '\r');
- }
-
- void emit(UChar character)
- {
- m_builder.append(character);
- }
-
- enum ParseState {
- // Have not seen an ASCII non-whitespace character yet on
- // this line. Possible that we might see a preprocessor
- // directive.
- BeginningOfLine,
-
- // Have seen at least one ASCII non-whitespace character
- // on this line.
- MiddleOfLine,
-
- // Handling a preprocessor directive. Passes through all
- // characters up to the end of the line. Disables comment
- // processing.
- InPreprocessorDirective,
-
- // Handling a single-line comment. The comment text is
- // replaced with a single space.
- InSingleLineComment,
-
- // Handling a multi-line comment. Newlines are passed
- // through to preserve line numbers.
- InMultiLineComment
- };
-
- ParseState m_parseState;
- String m_sourceString;
- unsigned m_length;
- unsigned m_position;
- StringBuilder m_builder;
- };
-
- void StripComments::process(UChar c)
- {
- if (isNewline(c)) {
- // No matter what state we are in, pass through newlines
- // so we preserve line numbers.
- emit(c);
-
- if (m_parseState != InMultiLineComment)
- m_parseState = BeginningOfLine;
-
- return;
- }
-
- UChar temp = 0;
- switch (m_parseState) {
- case BeginningOfLine:
- if (WTF::isASCIISpace(c)) {
- emit(c);
- break;
- }
-
- if (c == '#') {
- m_parseState = InPreprocessorDirective;
- emit(c);
- break;
- }
-
- // Transition to normal state and re-handle character.
- m_parseState = MiddleOfLine;
- process(c);
- break;
-
- case MiddleOfLine:
- if (c == '/' && peek(temp)) {
- if (temp == '/') {
- m_parseState = InSingleLineComment;
- emit(' ');
- advance();
- break;
- }
-
- if (temp == '*') {
- m_parseState = InMultiLineComment;
- // Emit the comment start in case the user has
- // an unclosed comment and we want to later
- // signal an error.
- emit('/');
- emit('*');
- advance();
- break;
- }
- }
-
- emit(c);
- break;
-
- case InPreprocessorDirective:
- // No matter what the character is, just pass it
- // through. Do not parse comments in this state. This
- // might not be the right thing to do long term, but it
- // should handle the #error preprocessor directive.
- emit(c);
- break;
-
- case InSingleLineComment:
- // The newline code at the top of this function takes care
- // of resetting our state when we get out of the
- // single-line comment. Swallow all other characters.
- break;
-
- case InMultiLineComment:
- if (c == '*' && peek(temp) && temp == '/') {
- emit('*');
- emit('/');
- m_parseState = MiddleOfLine;
- advance();
- break;
- }
-
- // Swallow all other characters. Unclear whether we may
- // want or need to just emit a space per character to try
- // to preserve column numbers for debugging purposes.
- break;
- }
- }
-
- GraphicsContext3D::Attributes adjustAttributes(const GraphicsContext3D::Attributes& attributes, Settings* settings)
- {
- GraphicsContext3D::Attributes adjustedAttributes = attributes;
- if (adjustedAttributes.antialias) {
- if (settings && !settings->openGLMultisamplingEnabled())
- adjustedAttributes.antialias = false;
- }
-
- return adjustedAttributes;
- }
-} // namespace anonymous
-
-class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
- virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
- virtual ~WebGLRenderingContextLostCallback() {}
-private:
- WebGLRenderingContext* m_context;
-};
-
-class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { }
- virtual void onErrorMessage(const String& message, GC3Dint)
- {
- if (m_context->m_synthesizedErrorsToConsole)
- m_context->printGLErrorToConsole(message);
- InspectorInstrumentation::didFireWebGLErrorOrWarning(m_context->canvas(), message);
- }
- virtual ~WebGLRenderingContextErrorMessageCallback() { }
-private:
- WebGLRenderingContext* m_context;
-};
-
-PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
+PassOwnPtrWillBeRawPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
{
Document& document = canvas->document();
- Frame* frame = document.frame();
- if (!frame)
+ LocalFrame* frame = document.frame();
+ if (!frame) {
+ canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Web page was not allowed to create a WebGL context."));
return nullptr;
+ }
Settings* settings = frame->settings();
// The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
@@ -506,29 +78,30 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
return nullptr;
}
- GraphicsContext3D::Attributes requestedAttributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
- requestedAttributes.noExtensions = true;
- requestedAttributes.shareResources = true;
- requestedAttributes.preferDiscreteGPU = true;
- requestedAttributes.topDocumentURL = document.topDocument()->url();
-
- GraphicsContext3D::Attributes attributes = adjustAttributes(requestedAttributes, settings);
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes));
-
+ // The only situation that attrs is null is through Document::getCSSCanvasContext().
+ RefPtr<WebGLContextAttributes> defaultAttrs;
+ if (!attrs) {
+ defaultAttrs = WebGLContextAttributes::create();
+ attrs = defaultAttrs.get();
+ }
+ blink::WebGraphicsContext3D::Attributes attributes = attrs->attributes(document.topDocument().url().string(), settings);
+ OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes, 0));
if (!context || !context->makeContextCurrent()) {
canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
return nullptr;
}
- Extensions3D* extensions = context->extensions();
- if (extensions->supports("GL_EXT_debug_marker"))
- extensions->pushGroupMarkerEXT("WebGLRenderingContext");
+ OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
+ if (!extensionsUtil)
+ return nullptr;
+ if (extensionsUtil->supportsExtension("GL_EXT_debug_marker"))
+ context->pushGroupMarkerEXT("WebGLRenderingContext");
- OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes, requestedAttributes));
+ OwnPtrWillBeRawPtr<WebGLRenderingContext> renderingContext = adoptPtrWillBeNoop(new WebGLRenderingContext(canvas, context.release(), attrs));
+ renderingContext->registerContextExtensions();
renderingContext->suspendIfNeeded();
- if (renderingContext->m_drawingBuffer->isZeroSized()) {
+ if (!renderingContext->m_drawingBuffer) {
canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
return nullptr;
}
@@ -536,53 +109,25 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
return renderingContext.release();
}
-WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context, GraphicsContext3D::Attributes attributes, GraphicsContext3D::Attributes requestedAttributes)
- : CanvasRenderingContext(passedCanvas)
- , ActiveDOMObject(&passedCanvas->document())
- , m_context(context)
- , m_drawingBuffer(0)
- , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
- , m_restoreAllowed(false)
- , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
- , m_generatedImageCache(4)
- , m_contextLost(false)
- , m_contextLostMode(SyntheticLostContext)
- , m_attributes(attributes)
- , m_requestedAttributes(requestedAttributes)
- , m_synthesizedErrorsToConsole(true)
- , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
- , m_multisamplingAllowed(false)
- , m_multisamplingObserverRegistered(false)
- , m_onePlusMaxEnabledAttribIndex(0)
- , m_onePlusMaxNonDefaultTextureUnit(0)
+WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes)
+ : WebGLRenderingContextBase(passedCanvas, context, requestedAttributes)
{
- ASSERT(m_context);
ScriptWrappable::init(this);
+}
- m_contextGroup = WebGLContextGroup::create();
- m_contextGroup->addContext(this);
-
- m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
- m_context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims);
-
- RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
-
- // Create the DrawingBuffer and initialize the platform layer.
- DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawingBuffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
- m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
+WebGLRenderingContext::~WebGLRenderingContext()
+{
- if (!m_drawingBuffer->isZeroSized()) {
- m_drawingBuffer->bind();
- setupFlags();
- initializeNewContext();
- }
+}
+void WebGLRenderingContext::registerContextExtensions()
+{
// Register extensions.
static const char* const webkitPrefix[] = { "WEBKIT_", 0, };
static const char* const bothPrefixes[] = { "", "WEBKIT_", 0, };
registerExtension<ANGLEInstancedArrays>(m_angleInstancedArrays);
- registerExtension<EXTTextureFilterAnisotropic>(m_extTextureFilterAnisotropic, PrefixedExtension, webkitPrefix);
+ registerExtension<EXTTextureFilterAnisotropic>(m_extTextureFilterAnisotropic, ApprovedExtension, bothPrefixes);
registerExtension<OESElementIndexUint>(m_oesElementIndexUint);
registerExtension<OESStandardDerivatives>(m_oesStandardDerivatives);
registerExtension<OESTextureFloat>(m_oesTextureFloat);
@@ -590,5046 +135,20 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
registerExtension<OESTextureHalfFloat>(m_oesTextureHalfFloat);
registerExtension<OESTextureHalfFloatLinear>(m_oesTextureHalfFloatLinear);
registerExtension<OESVertexArrayObject>(m_oesVertexArrayObject);
- registerExtension<WebGLCompressedTextureATC>(m_webglCompressedTextureATC, PrefixedExtension, webkitPrefix);
- registerExtension<WebGLCompressedTexturePVRTC>(m_webglCompressedTexturePVRTC, PrefixedExtension, webkitPrefix);
- registerExtension<WebGLCompressedTextureS3TC>(m_webglCompressedTextureS3TC, PrefixedExtension, bothPrefixes);
- registerExtension<WebGLDepthTexture>(m_webglDepthTexture, PrefixedExtension, bothPrefixes);
+ registerExtension<WebGLCompressedTextureATC>(m_webglCompressedTextureATC, EnabledDraftExtension, webkitPrefix);
+ registerExtension<WebGLCompressedTexturePVRTC>(m_webglCompressedTexturePVRTC, EnabledDraftExtension, webkitPrefix);
+ registerExtension<WebGLCompressedTextureS3TC>(m_webglCompressedTextureS3TC, ApprovedExtension, bothPrefixes);
+ registerExtension<WebGLDebugRendererInfo>(m_webglDebugRendererInfo);
+ registerExtension<WebGLDebugShaders>(m_webglDebugShaders);
+ registerExtension<WebGLDepthTexture>(m_webglDepthTexture, ApprovedExtension, bothPrefixes);
registerExtension<WebGLDrawBuffers>(m_webglDrawBuffers);
registerExtension<WebGLLoseContext>(m_webglLoseContext, ApprovedExtension, bothPrefixes);
// Register draft extensions.
+ registerExtension<EXTBlendMinMax>(m_extBlendMinMax, DraftExtension);
registerExtension<EXTFragDepth>(m_extFragDepth, DraftExtension);
-
- // Register privileged extensions.
- registerExtension<WebGLDebugRendererInfo>(m_webglDebugRendererInfo, WebGLDebugRendererInfoExtension);
- registerExtension<WebGLDebugShaders>(m_webglDebugShaders, PrivilegedExtension);
-}
-
-void WebGLRenderingContext::initializeNewContext()
-{
- ASSERT(!isContextLost());
- m_needsUpdate = true;
- m_markedCanvasDirty = false;
- m_activeTextureUnit = 0;
- m_packAlignment = 4;
- m_unpackAlignment = 4;
- m_unpackFlipY = false;
- m_unpackPremultiplyAlpha = false;
- m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
- m_boundArrayBuffer = 0;
- m_currentProgram = 0;
- m_framebufferBinding = 0;
- m_renderbufferBinding = 0;
- m_depthMask = true;
- m_stencilEnabled = false;
- m_stencilMask = 0xFFFFFFFF;
- m_stencilMaskBack = 0xFFFFFFFF;
- m_stencilFuncRef = 0;
- m_stencilFuncRefBack = 0;
- m_stencilFuncMask = 0xFFFFFFFF;
- m_stencilFuncMaskBack = 0xFFFFFFFF;
- m_layerCleared = false;
- m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
-
- m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
- m_scissorEnabled = false;
- m_clearDepth = 1;
- m_clearStencil = 0;
- m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
-
- GC3Dint numCombinedTextureImageUnits = 0;
- m_context->getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
- m_textureUnits.clear();
- m_textureUnits.resize(numCombinedTextureImageUnits);
-
- GC3Dint numVertexAttribs = 0;
- m_context->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
- m_maxVertexAttribs = numVertexAttribs;
-
- m_maxTextureSize = 0;
- m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
- m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
- m_maxCubeMapTextureSize = 0;
- m_context->getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
- m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
- m_maxRenderbufferSize = 0;
- m_context->getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
-
- // These two values from EXT_draw_buffers are lazily queried.
- m_maxDrawBuffers = 0;
- m_maxColorAttachments = 0;
-
- m_backDrawBuffer = GL_BACK;
-
- m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
- addContextObject(m_defaultVertexArrayObject.get());
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
-
- m_vertexAttribValue.resize(m_maxVertexAttribs);
-
- createFallbackBlackTextures1x1();
-
- IntSize canvasSize = clampedCanvasSize();
- m_drawingBuffer->reset(canvasSize);
-
- m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
- m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
-
- m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
- m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this)));
-
- // This ensures that the context has a valid "lastFlushID" and won't be mistakenly identified as the "least recently used" context.
- m_context->flush();
-
- activateContext(this);
-}
-
-void WebGLRenderingContext::setupFlags()
-{
- ASSERT(m_context);
- if (Page* p = canvas()->document().page()) {
- m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled();
-
- if (!m_multisamplingObserverRegistered && m_requestedAttributes.antialias) {
- m_multisamplingAllowed = m_drawingBuffer->multisample();
- p->addMultisamplingChangedObserver(this);
- m_multisamplingObserverRegistered = true;
- }
- }
-
- m_isGLES2NPOTStrict = !m_context->extensions()->isEnabled("GL_OES_texture_npot");
- m_isDepthStencilSupported = m_context->extensions()->isEnabled("GL_OES_packed_depth_stencil");
-}
-
-bool WebGLRenderingContext::allowPrivilegedExtensions() const
-{
- if (Page* p = canvas()->document().page())
- return p->settings().privilegedWebGLExtensionsEnabled();
- return false;
-}
-
-bool WebGLRenderingContext::allowWebGLDebugRendererInfo() const
-{
- return true;
-}
-
-void WebGLRenderingContext::addCompressedTextureFormat(GC3Denum format)
-{
- if (!m_compressedTextureFormats.contains(format))
- m_compressedTextureFormats.append(format);
-}
-
-void WebGLRenderingContext::removeAllCompressedTextureFormats()
-{
- m_compressedTextureFormats.clear();
-}
-
-WebGLRenderingContext::~WebGLRenderingContext()
-{
- // Remove all references to WebGLObjects so if they are the last reference
- // they will be freed before the last context is removed from the context group.
- m_boundArrayBuffer = 0;
- m_defaultVertexArrayObject = 0;
- m_boundVertexArrayObject = 0;
- m_vertexAttrib0Buffer = 0;
- m_currentProgram = 0;
- m_framebufferBinding = 0;
- m_renderbufferBinding = 0;
-
- for (size_t i = 0; i < m_textureUnits.size(); ++i) {
- m_textureUnits[i].m_texture2DBinding = 0;
- m_textureUnits[i].m_textureCubeMapBinding = 0;
- }
-
- m_blackTexture2D = 0;
- m_blackTextureCubeMap = 0;
-
- detachAndRemoveAllObjects();
-
- // release all extensions
- for (size_t i = 0; i < m_extensions.size(); ++i)
- delete m_extensions[i];
-
- // Context must be removed from the group prior to the destruction of the
- // GraphicsContext3D, otherwise shared objects may not be properly deleted.
- m_contextGroup->removeContext(this);
-
- destroyGraphicsContext3D();
-
- if (m_multisamplingObserverRegistered) {
- Page* page = canvas()->document().page();
- if (page)
- page->removeMultisamplingChangedObserver(this);
- }
-
- willDestroyContext(this);
-}
-
-void WebGLRenderingContext::destroyGraphicsContext3D()
-{
- m_contextLost = true;
-
- // The drawing buffer holds a context reference. It must also be destroyed
- // in order for the context to be released.
- m_drawingBuffer->releaseResources();
-
- if (m_context) {
- m_context->setContextLostCallback(nullptr);
- m_context->setErrorMessageCallback(nullptr);
- m_context.clear();
- }
-}
-
-void WebGLRenderingContext::markContextChanged()
-{
- if (m_framebufferBinding || isContextLost())
- return;
-
- m_context->markContextChanged();
- m_drawingBuffer->markContentsChanged();
-
- m_layerCleared = false;
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing()) {
- m_markedCanvasDirty = true;
- canvas()->clearCopiedImage();
- renderBox->contentChanged(CanvasChanged);
- } else {
- if (!m_markedCanvasDirty) {
- m_markedCanvasDirty = true;
- canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
- }
- }
-}
-
-bool WebGLRenderingContext::clearIfComposited(GC3Dbitfield mask)
-{
- if (isContextLost())
- return false;
-
- if (!m_context->layerComposited() || m_layerCleared
- || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding))
- return false;
-
- RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
-
- // Determine if it's possible to combine the clear the user asked for and this clear.
- bool combinedClear = mask && !m_scissorEnabled;
-
- m_context->disable(GL_SCISSOR_TEST);
- if (combinedClear && (mask & GL_COLOR_BUFFER_BIT))
- m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
- m_colorMask[1] ? m_clearColor[1] : 0,
- m_colorMask[2] ? m_clearColor[2] : 0,
- m_colorMask[3] ? m_clearColor[3] : 0);
- else
- m_context->clearColor(0, 0, 0, 0);
- m_context->colorMask(true, true, true, true);
- GC3Dbitfield clearMask = GL_COLOR_BUFFER_BIT;
- if (contextAttributes->depth()) {
- if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT))
- m_context->clearDepth(1.0f);
- clearMask |= GL_DEPTH_BUFFER_BIT;
- m_context->depthMask(true);
- }
- if (contextAttributes->stencil()) {
- if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
- m_context->clearStencil(m_clearStencil & m_stencilMask);
- else
- m_context->clearStencil(0);
- clearMask |= GL_STENCIL_BUFFER_BIT;
- m_context->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
- }
-
- m_drawingBuffer->clearFramebuffers(clearMask);
-
- restoreStateAfterClear();
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- m_layerCleared = true;
-
- return combinedClear;
-}
-
-void WebGLRenderingContext::restoreStateAfterClear()
-{
- if (isContextLost())
- return;
-
- // Restore the state that the context set.
- if (m_scissorEnabled)
- m_context->enable(GL_SCISSOR_TEST);
- m_context->clearColor(m_clearColor[0], m_clearColor[1],
- m_clearColor[2], m_clearColor[3]);
- m_context->colorMask(m_colorMask[0], m_colorMask[1],
- m_colorMask[2], m_colorMask[3]);
- m_context->clearDepth(m_clearDepth);
- m_context->clearStencil(m_clearStencil);
- m_context->stencilMaskSeparate(GL_FRONT, m_stencilMask);
- m_context->depthMask(m_depthMask);
-}
-
-void WebGLRenderingContext::markLayerComposited()
-{
- if (!isContextLost())
- m_context->markLayerComposited();
-}
-
-void WebGLRenderingContext::paintRenderingResultsToCanvas()
-{
- if (isContextLost()) {
- canvas()->clearPresentationCopy();
- return;
- }
-
- if (canvas()->document().printing())
- canvas()->clearPresentationCopy();
-
- // Until the canvas is written to by the application, the clear that
- // happened after it was composited should be ignored by the compositor.
- if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
- m_drawingBuffer->paintCompositedResultsToCanvas(canvas()->buffer());
-
- canvas()->makePresentationCopy();
- } else
- canvas()->clearPresentationCopy();
- clearIfComposited();
-
- if (!m_markedCanvasDirty && !m_layerCleared)
- return;
-
- canvas()->clearCopiedImage();
- m_markedCanvasDirty = false;
-
- m_drawingBuffer->commit();
- if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) {
- canvas()->ensureUnacceleratedImageBuffer();
- if (canvas()->hasImageBuffer())
- m_context->paintRenderingResultsToCanvas(canvas()->buffer(), m_drawingBuffer.get());
- }
-
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- m_drawingBuffer->bind();
-}
-
-PassRefPtr<ImageData> WebGLRenderingContext::paintRenderingResultsToImageData()
-{
- if (isContextLost())
- return 0;
-
- clearIfComposited();
- m_drawingBuffer->commit();
- int width, height;
- RefPtr<Uint8ClampedArray> imageDataPixels = m_context->paintRenderingResultsToImageData(m_drawingBuffer.get(), width, height);
- if (!imageDataPixels)
- return 0;
-
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- m_drawingBuffer->bind();
-
- return ImageData::create(IntSize(width, height), imageDataPixels);
-}
-
-void WebGLRenderingContext::reshape(int width, int height)
-{
- if (isContextLost())
- return;
-
- // This is an approximation because at WebGLRenderingContext level we don't
- // know if the underlying FBO uses textures or renderbuffers.
- GC3Dint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
- // Limit drawing buffer size to 4k to avoid memory exhaustion.
- const int sizeUpperLimit = 4096;
- maxSize = std::min(maxSize, sizeUpperLimit);
- GC3Dint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
- GC3Dint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
- width = clamp(width, 1, maxWidth);
- height = clamp(height, 1, maxHeight);
-
- if (m_needsUpdate) {
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing())
- renderBox->contentChanged(CanvasChanged);
- m_needsUpdate = false;
- }
-
- // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
- // clear (and this matches what reshape will do).
- m_drawingBuffer->reset(IntSize(width, height));
- restoreStateAfterClear();
-
- m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()));
- m_context->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-}
-
-int WebGLRenderingContext::drawingBufferWidth() const
-{
- return m_drawingBuffer->size().width();
-}
-
-int WebGLRenderingContext::drawingBufferHeight() const
-{
- return m_drawingBuffer->size().height();
-}
-
-unsigned int WebGLRenderingContext::sizeInBytes(GC3Denum type)
-{
- switch (type) {
- case GL_BYTE:
- return sizeof(GC3Dbyte);
- case GL_UNSIGNED_BYTE:
- return sizeof(GC3Dubyte);
- case GL_SHORT:
- return sizeof(GC3Dshort);
- case GL_UNSIGNED_SHORT:
- return sizeof(GC3Dushort);
- case GL_INT:
- return sizeof(GC3Dint);
- case GL_UNSIGNED_INT:
- return sizeof(GC3Duint);
- case GL_FLOAT:
- return sizeof(GC3Dfloat);
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-void WebGLRenderingContext::activeTexture(GC3Denum texture)
-{
- if (isContextLost())
- return;
- if (texture - GL_TEXTURE0 >= m_textureUnits.size()) {
- synthesizeGLError(GL_INVALID_ENUM, "activeTexture", "texture unit out of range");
- return;
- }
- m_activeTextureUnit = texture - GL_TEXTURE0;
- m_context->activeTexture(texture);
-
- m_drawingBuffer->setActiveTextureUnit(texture);
-
-}
-
-void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader)
-{
- if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
- return;
- if (!program->attachShader(shader)) {
- synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachment already has shader");
- return;
- }
- m_context->attachShader(objectOrZero(program), objectOrZero(shader));
- shader->onAttached();
-}
-
-void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
- return;
- if (!validateLocationLength("bindAttribLocation", name))
- return;
- if (!validateString("bindAttribLocation", name))
- return;
- if (isPrefixReserved(name)) {
- synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "bindAttribLocation", "index out of range");
- return;
- }
- m_context->bindAttribLocation(objectOrZero(program), index, name);
-}
-
-bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
-{
- deleted = false;
- if (isContextLost())
- return false;
- if (object) {
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "object not from this context");
- return false;
- }
- deleted = !object->object();
- }
- return true;
-}
-
-void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
- synthesizeGLError(GL_INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
- return;
- }
- if (target == GL_ARRAY_BUFFER)
- m_boundArrayBuffer = buffer;
- else if (target == GL_ELEMENT_ARRAY_BUFFER)
- m_boundVertexArrayObject->setElementArrayBuffer(buffer);
- else {
- synthesizeGLError(GL_INVALID_ENUM, "bindBuffer", "invalid target");
- return;
- }
-
- m_context->bindBuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setTarget(target);
-}
-
-void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (target != GL_FRAMEBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
- return;
- }
- m_framebufferBinding = buffer;
- m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
- if (!m_framebufferBinding) {
- // Instead of binding fb 0, bind the drawing buffer.
- m_drawingBuffer->bind();
- } else
- m_context->bindFramebuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setHasEverBeenBound();
- applyStencilTest();
-}
-
-void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
- return;
- if (deleted)
- renderBuffer = 0;
- if (target != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target");
- return;
- }
- m_renderbufferBinding = renderBuffer;
- m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
- if (renderBuffer)
- renderBuffer->setHasEverBeenBound();
-}
-
-void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindTexture", texture, deleted))
- return;
- if (deleted)
- texture = 0;
- if (texture && texture->getTarget() && texture->getTarget() != target) {
- synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
- return;
- }
- GC3Dint maxLevel = 0;
- if (target == GL_TEXTURE_2D) {
- m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
- maxLevel = m_maxTextureLevel;
-
- if (!m_activeTextureUnit)
- m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
-
- } else if (target == GL_TEXTURE_CUBE_MAP) {
- m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
- maxLevel = m_maxCubeMapTextureLevel;
- } else {
- synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
- return;
- }
-
- m_context->bindTexture(target, objectOrZero(texture));
- if (texture) {
- texture->setTarget(target, maxLevel);
- m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
- } else {
- // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index
- if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) {
- findNewMaxNonDefaultTextureUnit();
- }
- }
-
- // Note: previously we used to automatically set the TEXTURE_WRAP_R
- // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
- // ES 2.0 doesn't expose this flag (a bug in the specification) and
- // otherwise the application has no control over the seams in this
- // dimension. However, it appears that supporting this properly on all
- // platforms is fairly involved (will require a HashMap from texture ID
- // in all ports), and we have not had any complaints, so the logic has
- // been removed.
-
-}
-
-void WebGLRenderingContext::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha)
-{
- if (isContextLost())
- return;
- m_context->blendColor(red, green, blue, alpha);
-}
-
-void WebGLRenderingContext::blendEquation(GC3Denum mode)
-{
- if (isContextLost() || !validateBlendEquation("blendEquation", mode))
- return;
- m_context->blendEquation(mode);
-}
-
-void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
-{
- if (isContextLost() || !validateBlendEquation("blendEquationSeparate", modeRGB) || !validateBlendEquation("blendEquationSeparate", modeAlpha))
- return;
- m_context->blendEquationSeparate(modeRGB, modeAlpha);
-}
-
-
-void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
-{
- if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
- return;
- m_context->blendFunc(sfactor, dfactor);
-}
-
-void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
-{
- // Note: Alpha does not have the same restrictions as RGB.
- if (isContextLost() || !validateBlendFuncFactors("blendFuncSeparate", srcRGB, dstRGB))
- return;
- m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, long long size, GC3Denum usage)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (size < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size < 0");
- return;
- }
- if (!size) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0");
- return;
- }
-
- m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
- return;
- }
- m_context->bufferData(target, data->byteLength(), data->data(), usage);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
- return;
- }
-
- m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
-}
-
-void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
-
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
-}
-
-void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
-
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->baseAddress());
-}
-
-GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
-{
- if (isContextLost())
- return GL_FRAMEBUFFER_UNSUPPORTED;
- if (target != GL_FRAMEBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid target");
- return 0;
- }
- if (!m_framebufferBinding || !m_framebufferBinding->object())
- return GL_FRAMEBUFFER_COMPLETE;
- const char* reason = "framebuffer incomplete";
- GC3Denum result = m_framebufferBinding->checkStatus(&reason);
- if (result != GL_FRAMEBUFFER_COMPLETE) {
- emitGLWarning("checkFramebufferStatus", reason);
- return result;
- }
- result = m_context->checkFramebufferStatus(target);
- return result;
-}
-
-void WebGLRenderingContext::clear(GC3Dbitfield mask)
-{
- if (isContextLost())
- return;
- if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
- return;
- }
- if (!clearIfComposited(mask))
- m_context->clear(mask);
- markContextChanged();
-}
-
-void WebGLRenderingContext::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC3Dfloat a)
-{
- if (isContextLost())
- return;
- if (std::isnan(r))
- r = 0;
- if (std::isnan(g))
- g = 0;
- if (std::isnan(b))
- b = 0;
- if (std::isnan(a))
- a = 1;
- m_clearColor[0] = r;
- m_clearColor[1] = g;
- m_clearColor[2] = b;
- m_clearColor[3] = a;
- m_context->clearColor(r, g, b, a);
-}
-
-void WebGLRenderingContext::clearDepth(GC3Dfloat depth)
-{
- if (isContextLost())
- return;
- m_clearDepth = depth;
- m_context->clearDepth(depth);
-}
-
-void WebGLRenderingContext::clearStencil(GC3Dint s)
-{
- if (isContextLost())
- return;
- m_clearStencil = s;
- m_context->clearStencil(s);
-}
-
-void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
-{
- if (isContextLost())
- return;
- m_colorMask[0] = red;
- m_colorMask[1] = green;
- m_colorMask[2] = blue;
- m_colorMask[3] = alpha;
- m_context->colorMask(red, green, blue, alpha);
-}
-
-void WebGLRenderingContext::compileShader(WebGLShader* shader)
-{
- if (isContextLost() || !validateWebGLObject("compileShader", shader))
- return;
- m_context->compileShader(objectOrZero(shader));
-}
-
-void WebGLRenderingContext::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("compressedTexImage2D", target, level))
- return;
-
- if (!validateCompressedTexFormat(internalformat)) {
- synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
- return;
- }
- if (border) {
- synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
- return;
- }
- if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
- return;
- if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
- if (!tex)
- return;
- if (!isGLES2NPOTStrict()) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
- return;
- }
- }
- graphicsContext3D()->compressedTexImage2D(target, level, internalformat, width, height,
- border, data->byteLength(), data->baseAddress());
- tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
- return;
- if (!validateCompressedTexFormat(format)) {
- synthesizeGLError(GL_INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
- return;
- }
- if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
- if (!tex)
- return;
-
- if (format != tex->getInternalFormat(target, level)) {
- synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
- return;
- }
-
- if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
- return;
-
- graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset,
- width, height, format, data->byteLength(), data->baseAddress());
-}
-
-bool WebGLRenderingContext::validateSettableTexFormat(const char* functionName, GC3Denum format)
-{
- if (GraphicsContext3D::getClearBitsByFormat(format) & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to");
- return false;
- }
- return true;
-}
-
-void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GL_UNSIGNED_BYTE))
- return;
- if (!validateSettableTexFormat("copyTexImage2D", internalformat))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
- if (!tex)
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
- synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
- return;
- }
- if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
- return;
- }
- clearIfComposited();
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- 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, GL_UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
- if (!tex)
- return;
- if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
- return;
- // Before checking if it is in the range, check if overflow happens first.
- Checked<GC3Dint, RecordOverflow> maxX = xoffset;
- maxX += width;
- Checked<GC3Dint, RecordOverflow> maxY = yoffset;
- maxY += height;
-
- if (maxX.hasOverflowed() || maxY.hasOverflowed()) {
- synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
- return;
- }
- if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > tex->getHeight(target, level)) {
- synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
- return;
- }
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
- synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
- return;
- }
- clearIfComposited();
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-}
-
-PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
- addContextObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLTexture> o = WebGLTexture::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLProgram> o = WebGLProgram::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-WebGLRenderbuffer* WebGLRenderingContext::ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer* renderbuffer)
-{
- if (isContextLost())
- return 0;
- if (!renderbuffer->emulatedStencilBuffer()) {
- renderbuffer->setEmulatedStencilBuffer(createRenderbuffer());
- m_context->bindRenderbuffer(target, objectOrZero(renderbuffer->emulatedStencilBuffer()));
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
- }
- return renderbuffer->emulatedStencilBuffer();
-}
-
-PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type)
-{
- if (isContextLost())
- return 0;
- if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
- synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
- return 0;
- }
-
- RefPtr<WebGLShader> o = WebGLShader::create(this, type);
- addSharedObject(o.get());
- return o;
-}
-
-void WebGLRenderingContext::cullFace(GC3Denum mode)
-{
- if (isContextLost())
- return;
- switch (mode) {
- case GL_FRONT_AND_BACK:
- case GL_FRONT:
- case GL_BACK:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "cullFace", "invalid mode");
- return;
- }
- m_context->cullFace(mode);
-}
-
-bool WebGLRenderingContext::deleteObject(WebGLObject* object)
-{
- if (isContextLost() || !object)
- return false;
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, "delete", "object does not belong to this context");
- return false;
- }
- if (object->object())
- // We need to pass in context here because we want
- // things in this context unbound.
- object->deleteObject(graphicsContext3D());
- return true;
-}
-
-void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
-{
- if (!deleteObject(buffer))
- return;
- if (m_boundArrayBuffer == buffer)
- m_boundArrayBuffer = 0;
-
- m_boundVertexArrayObject->unbindBuffer(buffer);
-}
-
-void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!deleteObject(framebuffer))
- return;
- if (framebuffer == m_framebufferBinding) {
- m_framebufferBinding = 0;
- m_drawingBuffer->setFramebufferBinding(0);
- // Have to call bindFramebuffer here to bind back to internal fbo.
- m_drawingBuffer->bind();
- }
-}
-
-void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
-{
- deleteObject(program);
- // We don't reset m_currentProgram to 0 here because the deletion of the
- // current program is delayed.
-}
-
-void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!deleteObject(renderbuffer))
- return;
- if (renderbuffer == m_renderbufferBinding)
- m_renderbufferBinding = 0;
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
-}
-
-void WebGLRenderingContext::deleteShader(WebGLShader* shader)
-{
- deleteObject(shader);
-}
-
-void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
-{
- if (!deleteObject(texture))
- return;
-
- int maxBoundTextureIndex = -1;
- for (size_t i = 0; i < m_onePlusMaxNonDefaultTextureUnit; ++i) {
- if (texture == m_textureUnits[i].m_texture2DBinding) {
- m_textureUnits[i].m_texture2DBinding = 0;
- maxBoundTextureIndex = i;
- if (!i)
- m_drawingBuffer->setTexture2DBinding(0);
- }
- if (texture == m_textureUnits[i].m_textureCubeMapBinding) {
- m_textureUnits[i].m_textureCubeMapBinding = 0;
- maxBoundTextureIndex = i;
- }
- }
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
-
- // If the deleted was bound to the the current maximum index, trace backwards to find the new max texture index
- if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBoundTextureIndex + 1)) {
- findNewMaxNonDefaultTextureUnit();
- }
-}
-
-void WebGLRenderingContext::depthFunc(GC3Denum func)
-{
- if (isContextLost())
- return;
- if (!validateStencilOrDepthFunc("depthFunc", func))
- return;
- m_context->depthFunc(func);
-}
-
-void WebGLRenderingContext::depthMask(GC3Dboolean flag)
-{
- if (isContextLost())
- return;
- m_depthMask = flag;
- m_context->depthMask(flag);
-}
-
-void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
-{
- if (isContextLost())
- return;
- if (zNear > zFar) {
- synthesizeGLError(GL_INVALID_OPERATION, "depthRange", "zNear > zFar");
- return;
- }
- m_context->depthRange(zNear, zFar);
-}
-
-void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader)
-{
- if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
- return;
- if (!program->detachShader(shader)) {
- synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not attached");
- return;
- }
- m_context->detachShader(objectOrZero(program), objectOrZero(shader));
- shader->onDetached(graphicsContext3D());
-}
-
-void WebGLRenderingContext::disable(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("disable", cap))
- return;
- if (cap == GL_STENCIL_TEST) {
- m_stencilEnabled = false;
- applyStencilTest();
- return;
- }
- if (cap == GL_SCISSOR_TEST) {
- m_scissorEnabled = false;
- m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
- }
- m_context->disable(cap);
-}
-
-void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "disableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = false;
-
- // If the disabled index is the current maximum, trace backwards to find the new max enabled attrib index
- if (m_onePlusMaxEnabledAttribIndex == index + 1) {
- findNewMaxEnabledAttribIndex();
- }
-
- m_context->disableVertexAttribArray(index);
-}
-
-bool WebGLRenderingContext::validateRenderingState()
-{
- if (!m_currentProgram)
- return false;
-
- // Look in each enabled vertex attrib and check if they've been bound to a buffer.
- for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
- if (state.enabled
- && (!state.bufferBinding || !state.bufferBinding->object()))
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
-{
- if (!object || !object->object()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no object or object deleted");
- return false;
- }
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "object does not belong to this context");
- return false;
- }
- return true;
-}
-
-void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
-{
- if (!validateDrawArrays("drawArrays", mode, first, count))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawArrays", true);
- m_context->drawArrays(mode, first, count);
- handleTextureCompleteness("drawArrays", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset)
-{
- if (!validateDrawElements("drawElements", mode, count, type, offset))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawElements", true);
- m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
- handleTextureCompleteness("drawElements", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
-{
- if (!validateDrawArrays("drawArraysInstancedANGLE", mode, first, count))
- return;
-
- if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawArraysInstancedANGLE", true);
- m_context->extensions()->drawArraysInstancedANGLE(mode, first, count, primcount);
- handleTextureCompleteness("drawArraysInstancedANGLE", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
-{
- if (!validateDrawElements("drawElementsInstancedANGLE", mode, count, type, offset))
- return;
-
- if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawElementsInstancedANGLE", true);
- m_context->extensions()->drawElementsInstancedANGLE(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
- handleTextureCompleteness("drawElementsInstancedANGLE", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::enable(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("enable", cap))
- return;
- if (cap == GL_STENCIL_TEST) {
- m_stencilEnabled = true;
- applyStencilTest();
- return;
- }
- if (cap == GL_SCISSOR_TEST) {
- m_scissorEnabled = true;
- m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
- }
- m_context->enable(cap);
-}
-
-void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "enableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = true;
-
- m_onePlusMaxEnabledAttribIndex = max(index + 1, m_onePlusMaxEnabledAttribIndex);
-
- m_context->enableVertexAttribArray(index);
-}
-
-void WebGLRenderingContext::finish()
-{
- if (isContextLost())
- return;
- m_context->flush(); // Intentionally a flush, not a finish.
-}
-
-void WebGLRenderingContext::flush()
-{
- if (isContextLost())
- return;
- m_context->flush();
-}
-
-void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer)
-{
- if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
- return;
- if (renderbuffertarget != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
- return;
- }
- if (buffer && !buffer->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
- return;
- }
- Platform3DObject bufferObject = objectOrZero(buffer);
- switch (attachment) {
- case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
- if (isDepthStencilSupported() || !buffer) {
- m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
- m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
- } else {
- WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(renderbuffertarget, buffer);
- if (!emulatedStencilBuffer) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "out of memory");
- return;
- }
- m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
- m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
- }
- break;
- default:
- m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
- applyStencilTest();
-}
-
-void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level)
-{
- if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
- return;
- if (level) {
- synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0");
- return;
- }
- if (texture && !texture->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
- return;
- }
- Platform3DObject textureObject = objectOrZero(texture);
- switch (attachment) {
- case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
- m_context->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, textureObject, level);
- m_context->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
- break;
- case GL_DEPTH_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- case GL_STENCIL_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- default:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
- applyStencilTest();
-}
-
-void WebGLRenderingContext::frontFace(GC3Denum mode)
-{
- if (isContextLost())
- return;
- switch (mode) {
- case GL_CW:
- case GL_CCW:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "frontFace", "invalid mode");
- return;
- }
- m_context->frontFace(mode);
-}
-
-void WebGLRenderingContext::generateMipmap(GC3Denum target)
-{
- if (isContextLost())
- return;
- WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
- if (!tex)
- return;
- if (!tex->canGenerateMipmaps()) {
- synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
- return;
- }
- if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
- return;
-
- // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
- // on Mac. Remove the hack once this driver bug is fixed.
-#if OS(MACOSX)
- bool needToResetMinFilter = false;
- if (tex->getMinFilter() != GL_NEAREST_MIPMAP_LINEAR) {
- m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
- needToResetMinFilter = true;
- }
-#endif
- m_context->generateMipmap(target);
-#if OS(MACOSX)
- if (needToResetMinFilter)
- m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, tex->getMinFilter());
-#endif
- tex->generateMipmapLevelInfo();
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index)
-{
- if (isContextLost() || !validateWebGLObject("getActiveAttrib", 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, GC3Duint index)
-{
- if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
- return 0;
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), index, info))
- return 0;
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader> >& shaderObjects)
-{
- shaderObjects.clear();
- if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
- return false;
-
- const GC3Denum shaderType[] = {
- GL_VERTEX_SHADER,
- GL_FRAGMENT_SHADER
- };
- for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GC3Denum); ++i) {
- WebGLShader* shader = program->getAttachedShader(shaderType[i]);
- if (shader)
- shaderObjects.append(shader);
- }
- return true;
-}
-
-GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
- return -1;
- if (!validateLocationLength("getAttribLocation", name))
- return -1;
- if (!validateString("getAttribLocation", name))
- return -1;
- if (isPrefixReserved(name))
- return -1;
- if (!program->linkStatus()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked");
- return 0;
- }
- return m_context->getAttribLocation(objectOrZero(program), name);
-}
-
-WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- if (target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid target");
- return WebGLGetInfo();
- }
-
- if (pname != GL_BUFFER_SIZE && pname != GL_BUFFER_USAGE) {
- synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-
- GC3Dint value = 0;
- m_context->getBufferParameteriv(target, pname, &value);
- if (pname == GL_BUFFER_SIZE)
- return WebGLGetInfo(value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
-{
- if (isContextLost())
- return 0;
- // We always need to return a new WebGLContextAttributes object to
- // prevent the user from mutating any cached version.
-
- // Also, we need to enforce requested values of "false" for depth
- // and stencil, regardless of the properties of the underlying
- // GraphicsContext3D or DrawingBuffer.
- RefPtr<WebGLContextAttributes> attributes = WebGLContextAttributes::create(m_context->getContextAttributes());
- if (!m_attributes.depth)
- attributes->setDepth(false);
- if (!m_attributes.stencil)
- attributes->setStencil(false);
- // The DrawingBuffer obtains its parameters from GraphicsContext3D::getContextAttributes(),
- // but it makes its own determination of whether multisampling is supported.
- attributes->setAntialias(m_drawingBuffer->multisample());
- return attributes.release();
-}
-
-GC3Denum WebGLRenderingContext::getError()
-{
- if (lost_context_errors_.size()) {
- GC3Denum err = lost_context_errors_.first();
- lost_context_errors_.remove(0);
- return err;
- }
-
- if (isContextLost())
- return GL_NO_ERROR;
-
- return m_context->getError();
-}
-
-bool WebGLRenderingContext::ExtensionTracker::matchesNameWithPrefixes(const String& name) const
-{
- static const char* const unprefixed[] = { "", 0, };
-
- const char* const* prefixes = m_prefixes ? m_prefixes : unprefixed;
- for (; *prefixes; ++prefixes) {
- String prefixedName = String(*prefixes) + extensionName();
- if (equalIgnoringCase(prefixedName, name)) {
- return true;
- }
- }
- return false;
-}
-
-PassRefPtr<WebGLExtension> WebGLRenderingContext::getExtension(const String& name)
-{
- if (isContextLost())
- return 0;
-
- for (size_t i = 0; i < m_extensions.size(); ++i) {
- ExtensionTracker* tracker = m_extensions[i];
- if (tracker->matchesNameWithPrefixes(name)) {
- if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
- return 0;
- if (tracker->privileged() && !allowPrivilegedExtensions())
- return 0;
- if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
- return 0;
- if (!tracker->supported(this))
- return 0;
- return tracker->getExtension(this);
- }
- }
-
- return 0;
-}
-
-WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname)
-{
- if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
- return WebGLGetInfo();
-
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
- return WebGLGetInfo();
- }
-
- WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
- if (!object) {
- if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
- return WebGLGetInfo(GL_NONE);
- // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
- // specifies INVALID_OPERATION.
- synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-
- ASSERT(object->isTexture() || object->isRenderbuffer());
- if (object->isTexture()) {
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GL_TEXTURE);
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(static_cast<WebGLTexture*>(object)));
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- {
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
- return WebGLGetInfo(value);
- }
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
- return WebGLGetInfo();
- }
- } else {
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GL_RENDERBUFFER);
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(static_cast<WebGLRenderbuffer*>(object)));
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
- return WebGLGetInfo();
- }
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- const int intZero = 0;
- switch (pname) {
- case GL_ACTIVE_TEXTURE:
- return getUnsignedIntParameter(pname);
- case GL_ALIASED_LINE_WIDTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GL_ALIASED_POINT_SIZE_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GL_ALPHA_BITS:
- return getIntParameter(pname);
- case GL_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
- case GL_BLEND:
- return getBooleanParameter(pname);
- case GL_BLEND_COLOR:
- return getWebGLFloatArrayParameter(pname);
- case GL_BLEND_DST_ALPHA:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_DST_RGB:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_EQUATION_ALPHA:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_EQUATION_RGB:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_SRC_ALPHA:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_SRC_RGB:
- return getUnsignedIntParameter(pname);
- case GL_BLUE_BITS:
- return getIntParameter(pname);
- case GL_COLOR_CLEAR_VALUE:
- return getWebGLFloatArrayParameter(pname);
- case GL_COLOR_WRITEMASK:
- return getBooleanArrayParameter(pname);
- case GL_COMPRESSED_TEXTURE_FORMATS:
- return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
- case GL_CULL_FACE:
- return getBooleanParameter(pname);
- case GL_CULL_FACE_MODE:
- return getUnsignedIntParameter(pname);
- case GL_CURRENT_PROGRAM:
- return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
- case GL_DEPTH_BITS:
- if (!m_framebufferBinding && !m_attributes.depth)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GL_DEPTH_CLEAR_VALUE:
- return getFloatParameter(pname);
- case GL_DEPTH_FUNC:
- return getUnsignedIntParameter(pname);
- case GL_DEPTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GL_DEPTH_TEST:
- return getBooleanParameter(pname);
- case GL_DEPTH_WRITEMASK:
- return getBooleanParameter(pname);
- case GL_DITHER:
- return getBooleanParameter(pname);
- case GL_ELEMENT_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->boundElementArrayBuffer()));
- case GL_FRAMEBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
- case GL_FRONT_FACE:
- return getUnsignedIntParameter(pname);
- case GL_GENERATE_MIPMAP_HINT:
- return getUnsignedIntParameter(pname);
- case GL_GREEN_BITS:
- return getIntParameter(pname);
- case GL_LINE_WIDTH:
- return getFloatParameter(pname);
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GL_MAX_RENDERBUFFER_SIZE:
- return getIntParameter(pname);
- case GL_MAX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GL_MAX_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GL_MAX_VARYING_VECTORS:
- return getIntParameter(pname);
- case GL_MAX_VERTEX_ATTRIBS:
- return getIntParameter(pname);
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GL_MAX_VERTEX_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GL_MAX_VIEWPORT_DIMS:
- return getWebGLIntArrayParameter(pname);
- case GL_NUM_SHADER_BINARY_FORMATS:
- // FIXME: should we always return 0 for this?
- return getIntParameter(pname);
- case GL_PACK_ALIGNMENT:
- return getIntParameter(pname);
- case GL_POLYGON_OFFSET_FACTOR:
- return getFloatParameter(pname);
- case GL_POLYGON_OFFSET_FILL:
- return getBooleanParameter(pname);
- case GL_POLYGON_OFFSET_UNITS:
- return getFloatParameter(pname);
- case GL_RED_BITS:
- return getIntParameter(pname);
- case GL_RENDERBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
- case GL_RENDERER:
- return WebGLGetInfo(String("WebKit WebGL"));
- case GL_SAMPLE_BUFFERS:
- return getIntParameter(pname);
- case GL_SAMPLE_COVERAGE_INVERT:
- return getBooleanParameter(pname);
- case GL_SAMPLE_COVERAGE_VALUE:
- return getFloatParameter(pname);
- case GL_SAMPLES:
- return getIntParameter(pname);
- case GL_SCISSOR_BOX:
- return getWebGLIntArrayParameter(pname);
- case GL_SCISSOR_TEST:
- return getBooleanParameter(pname);
- case GL_SHADING_LANGUAGE_VERSION:
- return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GL_SHADING_LANGUAGE_VERSION) + ")");
- case GL_STENCIL_BACK_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_FUNC:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_REF:
- return getIntParameter(pname);
- case GL_STENCIL_BACK_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BITS:
- if (!m_framebufferBinding && !m_attributes.stencil)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GL_STENCIL_CLEAR_VALUE:
- return getIntParameter(pname);
- case GL_STENCIL_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_FUNC:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_REF:
- return getIntParameter(pname);
- case GL_STENCIL_TEST:
- return getBooleanParameter(pname);
- case GL_STENCIL_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GL_SUBPIXEL_BITS:
- return getIntParameter(pname);
- case GL_TEXTURE_BINDING_2D:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
- case GL_TEXTURE_BINDING_CUBE_MAP:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
- case GL_UNPACK_ALIGNMENT:
- return getIntParameter(pname);
- case GC3D_UNPACK_FLIP_Y_WEBGL:
- return WebGLGetInfo(m_unpackFlipY);
- case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- return WebGLGetInfo(m_unpackPremultiplyAlpha);
- case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
- return WebGLGetInfo(m_unpackColorspaceConversion);
- case GL_VENDOR:
- return WebGLGetInfo(String("WebKit"));
- case GL_VERSION:
- return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GL_VERSION) + ")");
- case GL_VIEWPORT:
- return getWebGLIntArrayParameter(pname);
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GL_RENDERER));
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GL_VENDOR));
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
- if (m_oesVertexArrayObject) {
- if (!m_boundVertexArrayObject->isDefaultObject())
- return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
- return WebGLGetInfo();
- }
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic)
- return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
- if (m_webglDrawBuffers)
- return WebGLGetInfo(maxColorAttachments());
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_DRAW_BUFFERS_EXT:
- if (m_webglDrawBuffers)
- return WebGLGetInfo(maxDrawBuffers());
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
- return WebGLGetInfo();
- default:
- if (m_webglDrawBuffers
- && pname >= Extensions3D::DRAW_BUFFER0_EXT
- && pname < static_cast<GC3Denum>(Extensions3D::DRAW_BUFFER0_EXT + maxDrawBuffers())) {
- GC3Dint value = GL_NONE;
- if (m_framebufferBinding)
- value = m_framebufferBinding->getDrawBuffer(pname);
- else // emulated backbuffer
- value = m_backDrawBuffer;
- return WebGLGetInfo(value);
- }
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname)
-{
- if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
- return WebGLGetInfo();
-
- GC3Dint value = 0;
- switch (pname) {
- case GL_DELETE_STATUS:
- return WebGLGetInfo(program->isDeleted());
- case GL_VALIDATE_STATUS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GL_LINK_STATUS:
- return WebGLGetInfo(program->linkStatus());
- case GL_ATTACHED_SHADERS:
- case GL_ACTIVE_ATTRIBUTES:
- case GL_ACTIVE_UNIFORMS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(value);
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program)
-{
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getProgramInfoLog", program))
- return "";
- return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
-}
-
-WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- if (target != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target");
- return WebGLGetInfo();
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
- return WebGLGetInfo();
- }
-
- GC3Dint value = 0;
- switch (pname) {
- case GL_RENDERBUFFER_WIDTH:
- case GL_RENDERBUFFER_HEIGHT:
- case GL_RENDERBUFFER_RED_SIZE:
- case GL_RENDERBUFFER_GREEN_SIZE:
- case GL_RENDERBUFFER_BLUE_SIZE:
- case GL_RENDERBUFFER_ALPHA_SIZE:
- case GL_RENDERBUFFER_DEPTH_SIZE:
- m_context->getRenderbufferParameteriv(target, pname, &value);
- return WebGLGetInfo(value);
- case GL_RENDERBUFFER_STENCIL_SIZE:
- if (m_renderbufferBinding->emulatedStencilBuffer()) {
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding->emulatedStencilBuffer()));
- m_context->getRenderbufferParameteriv(target, pname, &value);
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
- } else {
- m_context->getRenderbufferParameteriv(target, pname, &value);
- }
- return WebGLGetInfo(value);
- case GL_RENDERBUFFER_INTERNAL_FORMAT:
- return WebGLGetInfo(m_renderbufferBinding->internalFormat());
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname)
-{
- if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
- return WebGLGetInfo();
- GC3Dint value = 0;
- switch (pname) {
- case GL_DELETE_STATUS:
- return WebGLGetInfo(shader->isDeleted());
- case GL_COMPILE_STATUS:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GL_SHADER_TYPE:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader)
-{
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getShaderInfoLog", shader))
- return "";
- return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
-}
-
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContext::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType)
-{
- if (isContextLost())
- return 0;
- switch (shaderType) {
- case GL_VERTEX_SHADER:
- case GL_FRAGMENT_SHADER:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
- return 0;
- }
- switch (precisionType) {
- case GL_LOW_FLOAT:
- case GL_MEDIUM_FLOAT:
- case GL_HIGH_FLOAT:
- case GL_LOW_INT:
- case GL_MEDIUM_INT:
- case GL_HIGH_INT:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
- return 0;
- }
-
- GC3Dint range[2] = {0, 0};
- GC3Dint precision = 0;
- m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
- return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
-}
-
-String WebGLRenderingContext::getShaderSource(WebGLShader* shader)
-{
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getShaderSource", shader))
- return "";
- return ensureNotNull(shader->source());
-}
-
-Vector<String> WebGLRenderingContext::getSupportedExtensions()
-{
- Vector<String> result;
- if (isContextLost())
- return result;
-
- for (size_t i = 0; i < m_extensions.size(); ++i) {
- ExtensionTracker* tracker = m_extensions[i];
- if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
- continue;
- if (tracker->privileged() && !allowPrivilegedExtensions())
- continue;
- if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
- continue;
- if (tracker->supported(this))
- result.append(String(tracker->prefixed() ? "WEBKIT_" : "") + tracker->extensionName());
- }
-
- return result;
-}
-
-WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
- if (!tex)
- return WebGLGetInfo();
- GC3Dint value = 0;
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic) {
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- }
- synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
-{
- if (isContextLost() || !validateWebGLObject("getUniform", program))
- return WebGLGetInfo();
- if (!uniformLocation || uniformLocation->program() != program) {
- synthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
- return WebGLGetInfo();
- }
- GC3Dint location = uniformLocation->location();
-
- // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
- GC3Dint activeUniforms = 0;
- m_context->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
- for (GC3Dint 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.endsWith("[0]"))
- info.name = info.name.left(info.name.length() - 3);
- // If it's an array, we need to iterate through each element, appending "[index]" to the name.
- for (GC3Dint index = 0; index < info.size; ++index) {
- String 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
- GC3Dint loc = m_context->getUniformLocation(objectOrZero(program), name);
- if (loc == location) {
- // Found it. Use the type in the ActiveInfo to determine the return type.
- GC3Denum baseType;
- unsigned int length;
- switch (info.type) {
- case GL_BOOL:
- baseType = GL_BOOL;
- length = 1;
- break;
- case GL_BOOL_VEC2:
- baseType = GL_BOOL;
- length = 2;
- break;
- case GL_BOOL_VEC3:
- baseType = GL_BOOL;
- length = 3;
- break;
- case GL_BOOL_VEC4:
- baseType = GL_BOOL;
- length = 4;
- break;
- case GL_INT:
- baseType = GL_INT;
- length = 1;
- break;
- case GL_INT_VEC2:
- baseType = GL_INT;
- length = 2;
- break;
- case GL_INT_VEC3:
- baseType = GL_INT;
- length = 3;
- break;
- case GL_INT_VEC4:
- baseType = GL_INT;
- length = 4;
- break;
- case GL_FLOAT:
- baseType = GL_FLOAT;
- length = 1;
- break;
- case GL_FLOAT_VEC2:
- baseType = GL_FLOAT;
- length = 2;
- break;
- case GL_FLOAT_VEC3:
- baseType = GL_FLOAT;
- length = 3;
- break;
- case GL_FLOAT_VEC4:
- baseType = GL_FLOAT;
- length = 4;
- break;
- case GL_FLOAT_MAT2:
- baseType = GL_FLOAT;
- length = 4;
- break;
- case GL_FLOAT_MAT3:
- baseType = GL_FLOAT;
- length = 9;
- break;
- case GL_FLOAT_MAT4:
- baseType = GL_FLOAT;
- length = 16;
- break;
- case GL_SAMPLER_2D:
- case GL_SAMPLER_CUBE:
- baseType = GL_INT;
- length = 1;
- break;
- default:
- // Can't handle this type
- synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type");
- return WebGLGetInfo();
- }
- switch (baseType) {
- case GL_FLOAT: {
- GC3Dfloat value[16] = {0};
- m_context->getUniformfv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Float32Array::create(value, length));
- }
- case GL_INT: {
- GC3Dint value[4] = {0};
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Int32Array::create(value, length));
- }
- case GL_BOOL: {
- GC3Dint 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
- synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error");
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
- return 0;
- if (!validateLocationLength("getUniformLocation", name))
- return 0;
- if (!validateString("getUniformLocation", name))
- return 0;
- if (isPrefixReserved(name))
- return 0;
- if (!program->linkStatus()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getUniformLocation", "program not linked");
- return 0;
- }
- GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
- if (uniformLocation == -1)
- return 0;
- return WebGLUniformLocation::create(program, uniformLocation);
-}
-
-WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range");
- return WebGLGetInfo();
- }
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-
- if (m_angleInstancedArrays && pname == Extensions3D::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
- return WebGLGetInfo(state.divisor);
-
- switch (pname) {
- case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- if (!state.bufferBinding || !state.bufferBinding->object())
- return WebGLGetInfo();
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
- case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- return WebGLGetInfo(state.enabled);
- case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
- return WebGLGetInfo(state.normalized);
- case GL_VERTEX_ATTRIB_ARRAY_SIZE:
- return WebGLGetInfo(state.size);
- case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
- return WebGLGetInfo(state.originalStride);
- case GL_VERTEX_ATTRIB_ARRAY_TYPE:
- return WebGLGetInfo(state.type);
- case GL_CURRENT_VERTEX_ATTRIB:
- return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-long long WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
-{
- if (isContextLost())
- return 0;
- if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) {
- synthesizeGLError(GL_INVALID_ENUM, "getVertexAttribOffset", "invalid parameter name");
- return 0;
- }
- GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
- return static_cast<long long>(result);
-}
-
-void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
-{
- if (isContextLost())
- return;
- bool isValid = false;
- switch (target) {
- case GL_GENERATE_MIPMAP_HINT:
- isValid = true;
- break;
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- isValid = true;
- break;
- }
- if (!isValid) {
- synthesizeGLError(GL_INVALID_ENUM, "hint", "invalid target");
- return;
- }
- m_context->hint(target, mode);
-}
-
-GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
-{
- if (!buffer || isContextLost())
- return 0;
-
- if (!buffer->hasEverBeenBound())
- return 0;
-
- return m_context->isBuffer(buffer->object());
-}
-
-bool WebGLRenderingContext::isContextLost()
-{
- return m_contextLost;
-}
-
-GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("isEnabled", cap))
- return 0;
- if (cap == GL_STENCIL_TEST)
- return m_stencilEnabled;
- return m_context->isEnabled(cap);
-}
-
-GC3Dboolean WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!framebuffer || isContextLost())
- return 0;
-
- if (!framebuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isFramebuffer(framebuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isProgram(WebGLProgram* program)
-{
- if (!program || isContextLost())
- return 0;
-
- return m_context->isProgram(program->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!renderbuffer || isContextLost())
- return 0;
-
- if (!renderbuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isRenderbuffer(renderbuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isShader(WebGLShader* shader)
-{
- if (!shader || isContextLost())
- return 0;
-
- return m_context->isShader(shader->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isTexture(WebGLTexture* texture)
-{
- if (!texture || isContextLost())
- return 0;
-
- if (!texture->hasEverBeenBound())
- return 0;
-
- return m_context->isTexture(texture->object());
-}
-
-void WebGLRenderingContext::lineWidth(GC3Dfloat width)
-{
- if (isContextLost())
- return;
- m_context->lineWidth(width);
-}
-
-void WebGLRenderingContext::linkProgram(WebGLProgram* program)
-{
- if (isContextLost() || !validateWebGLObject("linkProgram", program))
- return;
-
- m_context->linkProgram(objectOrZero(program));
- program->increaseLinkCount();
-}
-
-void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param)
-{
- if (isContextLost())
- return;
- switch (pname) {
- case GC3D_UNPACK_FLIP_Y_WEBGL:
- m_unpackFlipY = param;
- break;
- case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- m_unpackPremultiplyAlpha = param;
- break;
- case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
- if (static_cast<GC3Denum>(param) == GC3D_BROWSER_DEFAULT_WEBGL || param == GL_NONE)
- m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
- else {
- synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
- return;
- }
- break;
- case GL_PACK_ALIGNMENT:
- case GL_UNPACK_ALIGNMENT:
- if (param == 1 || param == 2 || param == 4 || param == 8) {
- if (pname == GL_PACK_ALIGNMENT)
- m_packAlignment = param;
- else // GL_UNPACK_ALIGNMENT:
- m_unpackAlignment = param;
- m_context->pixelStorei(pname, param);
- } else {
- synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
- return;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "pixelStorei", "invalid parameter name");
- return;
- }
-}
-
-void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
-{
- if (isContextLost())
- return;
- m_context->polygonOffset(factor, units);
-}
-
-void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels)
-{
- if (isContextLost())
- return;
- // Due to WebGL's same-origin restrictions, it is not possible to
- // taint the origin using the WebGL API.
- ASSERT(canvas()->originClean());
- // Validate input parameters.
- if (!pixels) {
- synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
- return;
- }
- switch (format) {
- case GL_ALPHA:
- case GL_RGB:
- case GL_RGBA:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
- return;
- }
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
- return;
- }
- if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
- return;
- }
- // Validate array type against pixel type.
- if (pixels->getType() != ArrayBufferView::TypeUint8) {
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
- return;
- }
- // Calculate array size, taking into consideration of PACK_ALIGNMENT.
- unsigned int totalBytesRequired = 0;
- unsigned int padding = 0;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
- if (error != GL_NO_ERROR) {
- synthesizeGLError(error, "readPixels", "invalid dimensions");
- return;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
- return;
- }
-
- clearIfComposited();
- void* data = pixels->baseAddress();
-
- {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->readPixels(x, y, width, height, format, type, data);
- }
-
-#if OS(MACOSX)
- // 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 (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
- unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
- for (GC3Dsizei iy = 0; iy < height; ++iy) {
- for (GC3Dsizei ix = 0; ix < width; ++ix) {
- pixels[3] = 255;
- pixels += 4;
- }
- pixels += padding;
- }
- }
-#endif
-}
-
-void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (target != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid target");
- return;
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
- return;
- }
- if (!validateSize("renderbufferStorage", width, height))
- return;
- switch (internalformat) {
- case GL_DEPTH_COMPONENT16:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGB565:
- case GL_STENCIL_INDEX8:
- m_context->renderbufferStorage(target, internalformat, width, height);
- m_renderbufferBinding->setInternalFormat(internalformat);
- m_renderbufferBinding->setSize(width, height);
- m_renderbufferBinding->deleteEmulatedStencilBuffer(m_context.get());
- break;
- case GL_DEPTH_STENCIL_OES:
- if (isDepthStencilSupported()) {
- m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
- } else {
- WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(target, m_renderbufferBinding.get());
- if (!emulatedStencilBuffer) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "renderbufferStorage", "out of memory");
- return;
- }
- m_context->renderbufferStorage(target, GL_DEPTH_COMPONENT16, width, height);
- m_context->bindRenderbuffer(target, objectOrZero(emulatedStencilBuffer));
- m_context->renderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
- emulatedStencilBuffer->setSize(width, height);
- emulatedStencilBuffer->setInternalFormat(GL_STENCIL_INDEX8);
- }
- m_renderbufferBinding->setSize(width, height);
- m_renderbufferBinding->setInternalFormat(internalformat);
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
- return;
- }
- applyStencilTest();
-}
-
-void WebGLRenderingContext::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
-{
- if (isContextLost())
- return;
- m_context->sampleCoverage(value, invert);
-}
-
-void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateSize("scissor", width, height))
- return;
- m_context->scissor(x, y, width, height);
-}
-
-void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string)
-{
- if (isContextLost() || !validateWebGLObject("shaderSource", shader))
- return;
- String stringWithoutComments = StripComments(string).result();
- if (!validateString("shaderSource", stringWithoutComments))
- return;
- shader->setSource(string);
- m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
-}
-
-void WebGLRenderingContext::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLost())
- return;
- if (!validateStencilOrDepthFunc("stencilFunc", func))
- return;
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- m_context->stencilFunc(func, ref, mask);
-}
-
-void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLost())
- return;
- if (!validateStencilOrDepthFunc("stencilFuncSeparate", func))
- return;
- switch (face) {
- case GL_FRONT_AND_BACK:
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- break;
- case GL_FRONT:
- m_stencilFuncRef = ref;
- m_stencilFuncMask = mask;
- break;
- case GL_BACK:
- m_stencilFuncRefBack = ref;
- m_stencilFuncMaskBack = mask;
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "stencilFuncSeparate", "invalid face");
- return;
- }
- m_context->stencilFuncSeparate(face, func, ref, mask);
-}
-
-void WebGLRenderingContext::stencilMask(GC3Duint mask)
-{
- if (isContextLost())
- return;
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- m_context->stencilMask(mask);
-}
-
-void WebGLRenderingContext::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
-{
- if (isContextLost())
- return;
- switch (face) {
- case GL_FRONT_AND_BACK:
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- break;
- case GL_FRONT:
- m_stencilMask = mask;
- break;
- case GL_BACK:
- m_stencilMaskBack = mask;
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "stencilMaskSeparate", "invalid face");
- return;
- }
- m_context->stencilMaskSeparate(face, mask);
-}
-
-void WebGLRenderingContext::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLost())
- return;
- m_context->stencilOp(fail, zfail, zpass);
-}
-
-void WebGLRenderingContext::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLost())
- return;
- m_context->stencilOpSeparate(face, fail, zfail, zpass);
-}
-
-void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState& exceptionState)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- // FIXME: Handle errors.
- WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
- ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
- ASSERT(tex);
- ASSERT(!level || !WebGLTexture::isNPOT(width, height));
- ASSERT(!pixels || validateSettableTexFormat("texImage2D", internalformat));
- m_context->texImage2D(target, level, internalformat, width, height,
- border, format, type, pixels);
- tex->setLevelInfo(target, level, internalformat, width, height, type);
-}
-
-void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GL_UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GL_RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-bool WebGLRenderingContext::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
-{
- if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
- return false;
-
- WebGLTexture* texture = validateTextureBinding(functionName, target, true);
- if (!texture)
- return false;
-
- if (functionType == NotTexSubImage2D) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not power of 2");
- return false;
- }
- // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
- // by checking if the ArrayBufferView is null or not.
- if (sourceType != SourceArrayBufferView) {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- }
- } else {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- if (!validateSize(functionName, xoffset, yoffset))
- return false;
- // Before checking if it is in the range, check if overflow happens first.
- if (xoffset + width < 0 || yoffset + height < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions");
- return false;
- }
- if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
- return false;
- }
- if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type and format do not match texture");
- return false;
- }
- }
-
- return true;
-}
-
-PassRefPtr<Image> WebGLRenderingContext::drawImageIntoBuffer(Image* image, int width, int height)
-{
- IntSize size(width, height);
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
- return 0;
- }
-
- IntRect srcRect(IntPoint(), image->size());
- IntRect destRect(0, 0, size.width(), size.height());
- buf->context()->drawImage(image, destRect, srcRect);
- return buf->copyImage(ImageBuffer::fastCopyImageMode());
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
- return;
- 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(GL_UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, width, height, border, format, type, data, exceptionState);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
- return;
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLImageElement("texImage2D", image, exceptionState))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height());
-
- if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
- return;
-
- texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exceptionState) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
- return;
-
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- // If possible, copy from the canvas element directly to the texture
- // via the GPU, without a read-back to system memory.
- if (GL_TEXTURE_2D == target && texture) {
- if (!canvas->is3D()) {
- ImageBuffer* buffer = canvas->buffer();
- if (buffer && buffer->copyToPlatformTexture(*m_context.get(), texture->object(), internalformat, type,
- level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- return;
- }
- } else {
- WebGLRenderingContext* gl = toWebGLRenderingContext(canvas->renderingContext());
- if (gl && gl->m_drawingBuffer->copyToPlatformTexture(*m_context.get(), texture->object(), internalformat, type,
- level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- return;
- }
- }
- }
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
- else
- texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
-{
- IntSize size(video->videoWidth(), video->videoHeight());
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
- return 0;
- }
- IntRect destRect(0, 0, size.width(), size.height());
- // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
- video->paintCurrentFrameInContext(buf->context(), destRect);
- return buf->copyImage(backingStoreCopy);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, exceptionState)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
- return;
-
- // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
- // Otherwise, it will fall back to the normal SW path.
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- if (GL_TEXTURE_2D == target && texture) {
- if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
- return;
- }
- }
-
- // Normal pure SW path.
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
- if (!image)
- return;
- texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat)
-{
- if (isContextLost())
- return;
- WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
- if (!tex)
- return;
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- break;
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- if ((isFloat && paramf != GL_CLAMP_TO_EDGE && paramf != GL_MIRRORED_REPEAT && paramf != GL_REPEAT)
- || (!isFloat && parami != GL_CLAMP_TO_EDGE && parami != GL_MIRRORED_REPEAT && parami != GL_REPEAT)) {
- synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter");
- return;
- }
- break;
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (!m_extTextureFilterAnisotropic) {
- synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
- return;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter name");
- return;
- }
- if (isFloat) {
- tex->setParameterf(pname, paramf);
- m_context->texParameterf(target, pname, paramf);
- } else {
- tex->setParameteri(pname, parami);
- m_context->texParameteri(target, pname, parami);
- }
-}
-
-void WebGLRenderingContext::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
-{
- texParameter(target, pname, param, 0, true);
-}
-
-void WebGLRenderingContext::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
-{
- texParameter(target, pname, 0, param, false);
-}
-
-void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState& exceptionState)
-{
- // FIXME: Handle errors.
- ASSERT(!isContextLost());
- ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
- ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
- ASSERT(validateSettableTexFormat("texSubImage2D", format));
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- if (!tex) {
- ASSERT_NOT_REACHED();
- return;
- }
- ASSERT((xoffset + width) >= 0);
- ASSERT((yoffset + height) >= 0);
- ASSERT(tex->getWidth(target, level) >= (xoffset + width));
- ASSERT(tex->getHeight(target, level) >= (yoffset + height));
- ASSERT(tex->getInternalFormat(target, level) == format);
- ASSERT(tex->getType(target, level) == type);
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GL_UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GL_RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type, needConversion ? data.data() : imagePixelData, exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
- return;
- void* data = pixels->baseAddress();
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, exceptionState);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
- return;
-
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, exceptionState))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height());
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
- return;
-
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
- else
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, exceptionState)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
- if (!image)
- return;
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for current program");
- return;
- }
-
- m_context->uniform1f(location->location(), x);
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
- return;
-
- m_context->uniform1fv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
- return;
-
- m_context->uniform1fv(location->location(), size, v);
-}
-
-void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3Dint x)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform1i", "location not for current program");
- return;
- }
-
- m_context->uniform1i(location->location(), x);
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
- return;
-
- m_context->uniform1iv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
- return;
-
- m_context->uniform1iv(location->location(), size, v);
-}
-
-void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform2f", "location not for current program");
- return;
- }
-
- m_context->uniform2f(location->location(), x, y);
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
- return;
-
- m_context->uniform2fv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
- return;
-
- m_context->uniform2fv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform2i", "location not for current program");
- return;
- }
-
- m_context->uniform2i(location->location(), x, y);
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
- return;
-
- m_context->uniform2iv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
- return;
-
- m_context->uniform2iv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform3f", "location not for current program");
- return;
- }
-
- m_context->uniform3f(location->location(), x, y, z);
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
- return;
-
- m_context->uniform3fv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
- return;
-
- m_context->uniform3fv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform3i", "location not for current program");
- return;
- }
-
- m_context->uniform3i(location->location(), x, y, z);
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
- return;
-
- m_context->uniform3iv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
- return;
-
- m_context->uniform3iv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform4f", "location not for current program");
- return;
- }
-
- m_context->uniform4f(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
- return;
-
- m_context->uniform4fv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
- return;
-
- m_context->uniform4fv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform4i", "location not for current program");
- return;
- }
-
- m_context->uniform4i(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
- return;
-
- m_context->uniform4iv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
- return;
-
- m_context->uniform4iv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
-}
-
-void WebGLRenderingContext::useProgram(WebGLProgram* program)
-{
- bool deleted;
- if (!checkObjectToBeBound("useProgram", program, deleted))
- return;
- if (deleted)
- program = 0;
- if (program && !program->linkStatus()) {
- synthesizeGLError(GL_INVALID_OPERATION, "useProgram", "program not valid");
- return;
- }
- if (m_currentProgram != program) {
- if (m_currentProgram)
- m_currentProgram->onDetached(graphicsContext3D());
- m_currentProgram = program;
- m_context->useProgram(objectOrZero(program));
- if (program)
- program->onAttached();
- }
-}
-
-void WebGLRenderingContext::validateProgram(WebGLProgram* program)
-{
- if (isContextLost() || !validateWebGLObject("validateProgram", program))
- return;
- m_context->validateProgram(objectOrZero(program));
-}
-
-void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
-{
- vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
-{
- vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
-{
- vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
-}
-
-void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset)
-{
- if (isContextLost())
- return;
- switch (type) {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_FLOAT:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "index out of range");
- return;
- }
- if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
- return;
- }
- if (!m_boundArrayBuffer) {
- synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
- return;
- }
- // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
- unsigned int typeSize = sizeInBytes(type);
- if (!typeSize) {
- synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
- synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
- return;
- }
- GC3Dsizei bytesPerElement = size * typeSize;
-
- m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), m_boundArrayBuffer);
- m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
-}
-
-void WebGLRenderingContext::vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor)
-{
- if (isContextLost())
- return;
-
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index out of range");
- return;
- }
-
- m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
- m_context->extensions()->vertexAttribDivisorANGLE(index, divisor);
-}
-
-void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateSize("viewport", width, height))
- return;
- m_context->viewport(x, y, width, height);
-}
-
-void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
-{
- if (isContextLost()) {
- synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
- return;
- }
-
- m_contextGroup->loseContextGroup(mode);
-}
-
-void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode)
-{
- if (isContextLost())
- return;
-
- m_contextLost = true;
- m_contextLostMode = mode;
-
- if (mode == RealLostContext) {
- // Inform the embedder that a lost context was received. In response, the embedder might
- // decide to take action such as asking the user for permission to use WebGL again.
- if (Frame* frame = canvas()->document().frame())
- frame->loader().client()->didLoseWebGLContext(m_context->extensions()->getGraphicsResetStatusARB());
- }
-
- // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
- m_drawingBuffer->setTexture2DBinding(0);
- m_drawingBuffer->setFramebufferBinding(0);
-
- detachAndRemoveAllObjects();
-
- // Lose all the extensions.
- for (size_t i = 0; i < m_extensions.size(); ++i) {
- ExtensionTracker* tracker = m_extensions[i];
- tracker->loseExtension();
- }
-
- removeAllCompressedTextureFormats();
-
- if (mode != RealLostContext)
- destroyGraphicsContext3D();
-
- ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
- synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
-
- // Don't allow restoration unless the context lost event has both been
- // dispatched and its default behavior prevented.
- m_restoreAllowed = false;
-
- // Always defer the dispatch of the context lost event, to implement
- // the spec behavior of queueing a task.
- m_dispatchContextLostEventTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::forceRestoreContext()
-{
- if (!isContextLost()) {
- synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not lost");
- return;
- }
-
- if (!m_restoreAllowed) {
- if (m_contextLostMode == SyntheticLostContext)
- synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context restoration not allowed");
- return;
- }
-
- if (!m_restoreTimer.isActive())
- m_restoreTimer.startOneShot(0);
-}
-
-blink::WebLayer* WebGLRenderingContext::platformLayer() const
-{
- return m_drawingBuffer->platformLayer();
-}
-
-void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object)
-{
- m_contextGroup->removeObject(object);
-}
-
-void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object)
-{
- ASSERT(!isContextLost());
- m_contextGroup->addObject(object);
-}
-
-void WebGLRenderingContext::removeContextObject(WebGLContextObject* object)
-{
- m_contextObjects.remove(object);
-}
-
-void WebGLRenderingContext::addContextObject(WebGLContextObject* object)
-{
- ASSERT(!isContextLost());
- m_contextObjects.add(object);
-}
-
-void WebGLRenderingContext::detachAndRemoveAllObjects()
-{
- while (m_contextObjects.size() > 0) {
- HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
- (*it)->detachContext();
- }
-}
-
-bool WebGLRenderingContext::hasPendingActivity() const
-{
- return false;
-}
-
-void WebGLRenderingContext::stop()
-{
- if (!isContextLost()) {
- forceLostContext(SyntheticLostContext);
- destroyGraphicsContext3D();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GC3Denum pname)
-{
- GC3Dboolean value = 0;
- if (!isContextLost())
- m_context->getBooleanv(pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(GC3Denum pname)
-{
- if (pname != GL_COLOR_WRITEMASK) {
- notImplemented();
- return WebGLGetInfo(0, 0);
- }
- GC3Dboolean value[4] = {0};
- if (!isContextLost())
- m_context->getBooleanv(pname, value);
- bool boolValue[4];
- for (int ii = 0; ii < 4; ++ii)
- boolValue[ii] = static_cast<bool>(value[ii]);
- return WebGLGetInfo(boolValue, 4);
-}
-
-WebGLGetInfo WebGLRenderingContext::getFloatParameter(GC3Denum pname)
-{
- GC3Dfloat value = 0;
- if (!isContextLost())
- m_context->getFloatv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- if (!isContextLost())
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getUnsignedIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- if (!isContextLost())
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(GC3Denum pname)
-{
- GC3Dfloat value[4] = {0};
- if (!isContextLost())
- m_context->getFloatv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GL_ALIASED_POINT_SIZE_RANGE:
- case GL_ALIASED_LINE_WIDTH_RANGE:
- case GL_DEPTH_RANGE:
- length = 2;
- break;
- case GL_BLEND_COLOR:
- case GL_COLOR_CLEAR_VALUE:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Float32Array::create(value, length));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(GC3Denum pname)
-{
- GC3Dint value[4] = {0};
- if (!isContextLost())
- m_context->getIntegerv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GL_MAX_VIEWPORT_DIMS:
- length = 2;
- break;
- case GL_SCISSOR_BOX:
- case GL_VIEWPORT:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Int32Array::create(value, length));
-}
-
-void WebGLRenderingContext::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- bool resetActiveUnit = false;
- WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
- | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
- for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) {
- if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
- || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
- if (ii != m_activeTextureUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = true;
- } else if (resetActiveUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = false;
- }
- WebGLTexture* tex2D;
- WebGLTexture* texCubeMap;
- if (prepareToDraw) {
- String msg(String("texture bound to texture unit ") + String::number(ii)
- + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
- + " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
- emitGLWarning(functionName, msg.utf8().data());
- 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(flag))
- m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D));
- if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
- m_context->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
- }
- }
- if (resetActiveUnit)
- m_context->activeTexture(m_activeTextureUnit);
-}
-
-void WebGLRenderingContext::createFallbackBlackTextures1x1()
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- unsigned char black[] = {0, 0, 0, 255};
- m_blackTexture2D = createTexture();
- m_context->bindTexture(GL_TEXTURE_2D, m_blackTexture2D->object());
- m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->bindTexture(GL_TEXTURE_2D, 0);
- m_blackTextureCubeMap = createTexture();
- m_context->bindTexture(GL_TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->bindTexture(GL_TEXTURE_CUBE_MAP, 0);
-}
-
-bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat)
-{
- unsigned need = GraphicsContext3D::getChannelBitsByFormat(texInternalFormat);
- unsigned have = GraphicsContext3D::getChannelBitsByFormat(colorBufferFormat);
- return (need & have) == need;
-}
-
-GC3Denum WebGLRenderingContext::boundFramebufferColorFormat()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->colorBufferFormat();
- if (m_attributes.alpha)
- return GL_RGBA;
- return GL_RGB;
-}
-
-int WebGLRenderingContext::boundFramebufferWidth()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->colorBufferWidth();
- return m_drawingBuffer->size().width();
-}
-
-int WebGLRenderingContext::boundFramebufferHeight()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->colorBufferHeight();
- return m_drawingBuffer->size().height();
-}
-
-WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
-{
- WebGLTexture* tex = 0;
- switch (target) {
- case GL_TEXTURE_2D:
- tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get();
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (!useSixEnumsForCubeMap) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
- return 0;
- }
- tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
- break;
- case GL_TEXTURE_CUBE_MAP:
- if (useSixEnumsForCubeMap) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
- return 0;
- }
- tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
- return 0;
- }
- if (!tex)
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture");
- return tex;
-}
-
-bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string)
-{
- const unsigned maxWebGLLocationLength = 256;
- if (string.length() > maxWebGLLocationLength) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
-{
- if (x < 0 || y < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateString(const char* functionName, const String& string)
-{
- for (size_t i = 0; i < string.length(); ++i) {
- if (!validateCharacter(string[i])) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "string not ASCII");
- return false;
- }
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level)
-{
- switch (format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_RGB:
- case GL_RGBA:
- break;
- case GL_DEPTH_STENCIL_OES:
- case GL_DEPTH_COMPONENT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "depth texture formats not enabled");
- return false;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture format");
- return false;
- }
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- break;
- case GL_FLOAT:
- if (m_oesTextureFloat)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GL_HALF_FLOAT_OES:
- if (m_oesTextureHalfFloat)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GL_UNSIGNED_INT:
- case GL_UNSIGNED_INT_24_8_OES:
- case GL_UNSIGNED_SHORT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- }
-
- // Verify that the combination of format and type is supported.
- switch (format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- if (type != GL_UNSIGNED_BYTE
- && type != GL_FLOAT
- && type != GL_HALF_FLOAT_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for format");
- return false;
- }
- break;
- case GL_RGB:
- if (type != GL_UNSIGNED_BYTE
- && type != GL_UNSIGNED_SHORT_5_6_5
- && type != GL_FLOAT
- && type != GL_HALF_FLOAT_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGB format");
- return false;
- }
- break;
- case GL_RGBA:
- if (type != GL_UNSIGNED_BYTE
- && type != GL_UNSIGNED_SHORT_4_4_4_4
- && type != GL_UNSIGNED_SHORT_5_5_5_1
- && type != GL_FLOAT
- && type != GL_HALF_FLOAT_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGBA format");
- return false;
- }
- break;
- case GL_DEPTH_COMPONENT:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
- return false;
- }
- if (type != GL_UNSIGNED_SHORT
- && type != GL_UNSIGNED_INT) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
- return false;
- }
- break;
- case GL_DEPTH_STENCIL_OES:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
- return false;
- }
- if (type != GL_UNSIGNED_INT_24_8_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
-{
- if (level < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level < 0");
- return false;
- }
- switch (target) {
- case GL_TEXTURE_2D:
- if (level >= m_maxTextureLevel) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (level >= m_maxCubeMapTextureLevel) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- }
- // This function only checks if level is legal, so we return true and don't
- // generate INVALID_ENUM if target is illegal.
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
- GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height)
-{
- if (width < 0 || height < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- switch (target) {
- case GL_TEXTURE_2D:
- if (width > (m_maxTextureSize >> level) || height > (m_maxTextureSize >> level)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range");
- return false;
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (functionType != TexSubImage2D && width != height) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width != height for cube map");
- return false;
- }
- // No need to check height here. For texImage width == height.
- // For texSubImage that will be checked when checking yoffset + height is in range.
- if (width > (m_maxCubeMapTextureSize >> level)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range for cube map");
- return false;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target,
- GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
-{
- // We absolutely have to validate the format and type combination.
- // The texImage2D entry points taking HTMLImage, etc. will produce
- // temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
- return false;
-
- if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
- return false;
-
- if (format != internalformat) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "format != internalformat");
- return false;
- }
-
- if (border) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "border != 0");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition disposition)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- if (!pixels) {
- if (disposition == NullAllowed)
- return true;
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
- return false;
- }
-
- if (!validateTexFuncFormatAndType(functionName, format, type, level))
- return false;
- if (!validateSettableTexFormat(functionName, format))
- return false;
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- if (pixels->getType() != ArrayBufferView::TypeUint8) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
- return false;
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- if (pixels->getType() != ArrayBufferView::TypeUint16) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
- return false;
- }
- break;
- case GL_FLOAT: // OES_texture_float
- if (pixels->getType() != ArrayBufferView::TypeFloat32) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
- return false;
- }
- break;
- case GL_HALF_FLOAT_OES: // OES_texture_half_float
- // As per the specification, ArrayBufferView should be null when
- // OES_texture_half_float is enabled.
- if (pixels) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- unsigned int totalBytesRequired;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
- if (error != GL_NO_ERROR) {
- synthesizeGLError(error, functionName, "invalid texture dimensions");
- return false;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- if (m_unpackAlignment != 1) {
- error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
- if (pixels->byteLength() == totalBytesRequired) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
- return false;
- }
- }
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexFormat(GC3Denum format)
-{
- return m_compressedTextureFormats.contains(format);
-}
-
-bool WebGLRenderingContext::validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels)
-{
- if (!pixels) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
- return false;
- }
- if (width < 0 || height < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- unsigned int bytesRequired = 0;
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- const int kBlockSize = 8;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- int numBlocks = numBlocksAcross * numBlocksDown;
- bytesRequired = numBlocks * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
- {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- const int kBlockSize = 16;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- int numBlocks = numBlocksAcross * numBlocksDown;
- bytesRequired = numBlocks * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_ATC_RGB_AMD:
- {
- bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 8;
- }
- break;
- case Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
- case Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
- {
- bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 16;
- }
- case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
- {
- bytesRequired = max(width, 8) * max(height, 8) / 2;
- }
- break;
- case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
- {
- bytesRequired = max(width, 8) * max(height, 8) / 4;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format");
- return false;
- }
-
- if (pixels->byteLength() != bytesRequired) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format)
-{
- if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
- return false;
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- bool widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
- bool heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
- if (!widthValid || !heightValid) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
- return false;
- }
- return true;
- }
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
-{
- if (xoffset < 0 || yoffset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "xoffset or yoffset < 0");
- return false;
- }
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
- return false;
- }
- if (width - xoffset > tex->getWidth(target, level)
- || height - yoffset > tex->getHeight(target, level)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
- return false;
- }
- return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
- }
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateDrawMode(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GL_POINTS:
- case GL_LINE_STRIP:
- case GL_LINE_LOOP:
- case GL_LINES:
- case GL_TRIANGLE_STRIP:
- case GL_TRIANGLE_FAN:
- case GL_TRIANGLES:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid draw mode");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateStencilSettings(const char* functionName)
-{
- if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "front and back stencils settings do not match");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateStencilOrDepthFunc(const char* functionName, GC3Denum func)
-{
- switch (func) {
- case GL_NEVER:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid function");
- return false;
- }
-}
-
-void WebGLRenderingContext::printGLErrorToConsole(const String& message)
-{
- if (!m_numGLErrorsToConsoleAllowed)
- return;
-
- --m_numGLErrorsToConsoleAllowed;
- printWarningToConsole(message);
-
- if (!m_numGLErrorsToConsoleAllowed)
- printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
-
- return;
-}
-
-void WebGLRenderingContext::printWarningToConsole(const String& message)
-{
- if (!canvas())
- return;
- canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
-}
-
-bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
-{
- if (target != GL_FRAMEBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
- return false;
- }
- switch (attachment) {
- case GL_COLOR_ATTACHMENT0:
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
- break;
- default:
- if (m_webglDrawBuffers
- && attachment > GL_COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GL_FUNC_ADD:
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
-{
- if (((src == GL_CONSTANT_COLOR || src == GL_ONE_MINUS_CONSTANT_COLOR)
- && (dst == GL_CONSTANT_ALPHA || dst == GL_ONE_MINUS_CONSTANT_ALPHA))
- || ((dst == GL_CONSTANT_COLOR || dst == GL_ONE_MINUS_CONSTANT_COLOR)
- && (src == GL_CONSTANT_ALPHA || src == GL_ONE_MINUS_CONSTANT_ALPHA))) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "incompatible src and dst");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap)
-{
- switch (cap) {
- case GL_BLEND:
- case GL_CULL_FACE:
- case GL_DEPTH_TEST:
- case GL_DITHER:
- case GL_POLYGON_OFFSET_FILL:
- case GL_SAMPLE_ALPHA_TO_COVERAGE:
- case GL_SAMPLE_COVERAGE:
- case GL_SCISSOR_TEST:
- case GL_STENCIL_TEST:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid capability");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- if (!location)
- return false;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "location is not from current program");
- return false;
- }
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- if (transpose) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "transpose not FALSE");
- return false;
- }
- if (size < requiredMinSize || (size % requiredMinSize)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
- return false;
- }
- return true;
-}
-
-WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
-{
- WebGLBuffer* buffer = 0;
- switch (target) {
- case GL_ELEMENT_ARRAY_BUFFER:
- buffer = m_boundVertexArrayObject->boundElementArrayBuffer().get();
- break;
- case GL_ARRAY_BUFFER:
- buffer = m_boundArrayBuffer.get();
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
- return 0;
- }
- if (!buffer) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
- return 0;
- }
- switch (usage) {
- case GL_STREAM_DRAW:
- case GL_STATIC_DRAW:
- case GL_DYNAMIC_DRAW:
- return buffer;
- }
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid usage");
- return 0;
-}
-
-bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionState& exceptionState)
-{
- if (!image || !image->cachedImage()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no image");
- return false;
- }
- const KURL& url = image->cachedImage()->response().url();
- if (url.isNull() || url.isEmpty() || !url.isValid()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid image");
- return false;
- }
- if (wouldTaintOrigin(image)) {
- exceptionState.throwSecurityError("The cross-origin image at " + url.elidedString() + " may not be loaded.");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
- if (!canvas || !canvas->buffer()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no canvas");
- return false;
- }
- if (wouldTaintOrigin(canvas)) {
- exceptionState.throwSecurityError("Tainted canvases may not be loaded.");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
- if (!video || !video->videoWidth() || !video->videoHeight()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no video");
- return false;
- }
- if (wouldTaintOrigin(video)) {
- exceptionState.throwSecurityError("The video element contains cross-origin data, and may not be loaded.");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count)
-{
- if (isContextLost() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- if (first < 0 || count < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "first or count < 0");
- return false;
- }
-
- if (!count) {
- markContextChanged();
- return false;
- }
-
- if (!validateRenderingState()) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset)
-{
- if (isContextLost() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT:
- break;
- case GL_UNSIGNED_INT:
- if (m_oesElementIndexUint)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
- return false;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
- return false;
- }
-
- if (count < 0 || offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "count or offset < 0");
- return false;
- }
-
- if (!count) {
- markContextChanged();
- return false;
- }
-
- if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
- return false;
- }
-
- if (!validateRenderingState()) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-// Helper function to validate draw*Instanced calls
-bool WebGLRenderingContext::validateDrawInstanced(const char* functionName, GC3Dsizei primcount)
-{
- if (primcount < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "primcount < 0");
- return false;
- }
-
- // Ensure at least one enabled vertex attrib has a divisor of 0.
- for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
- if (state.enabled && !state.divisor)
- return true;
- }
-
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "at least one enabled attribute must have a divisor of 0");
- return false;
-}
-
-void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1f(index, v0);
- break;
- case 2:
- m_context->vertexAttrib2f(index, v0, v1);
- break;
- case 3:
- m_context->vertexAttrib3f(index, v0, v1, v2);
- break;
- case 4:
- m_context->vertexAttrib4f(index, v0, v1, v2, v3);
- break;
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.value[0] = v0;
- attribValue.value[1] = v1;
- attribValue.value[2] = v2;
- attribValue.value[3] = v3;
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
-{
- if (isContextLost())
- return;
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return;
- }
- vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
-{
- if (isContextLost())
- return;
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return;
- }
- if (size < expectedSize) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1fv(index, v);
- break;
- case 2:
- m_context->vertexAttrib2fv(index, v);
- break;
- case 3:
- m_context->vertexAttrib3fv(index, v);
- break;
- case 4:
- m_context->vertexAttrib4fv(index, v);
- break;
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.initValue();
- for (int ii = 0; ii < expectedSize; ++ii)
- attribValue.value[ii] = v[ii];
-}
-
-void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext>*)
-{
- RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(EventTypeNames::webglcontextlost, false, true, "");
- canvas()->dispatchEvent(event);
- m_restoreAllowed = event->defaultPrevented();
- deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAllowed);
- if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecoverSyntheticLostContext) && m_restoreAllowed)
- m_restoreTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
-{
- ASSERT(isContextLost());
-
- // The rendering context is not restored unless the default behavior of the
- // webglcontextlost event was prevented earlier.
- //
- // Because of the way m_restoreTimer is set up for real vs. synthetic lost
- // context events, we don't have to worry about this test short-circuiting
- // the retry loop for real context lost events.
- if (!m_restoreAllowed)
- return;
-
- Frame* frame = canvas()->document().frame();
- if (!frame)
- return;
-
- Settings* settings = frame->settings();
-
- if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled()))
- return;
-
- // Reset the context attributes back to the requested attributes and re-apply restrictions
- m_attributes = adjustAttributes(m_requestedAttributes, settings);
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes));
-
- if (!context) {
- if (m_contextLostMode == RealLostContext) {
- m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
- } else {
- // This likely shouldn't happen but is the best way to report it to the WebGL app.
- synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context");
- }
- return;
- }
-
- RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
-
- // Construct a new drawing buffer with the new GraphicsContext3D.
- m_drawingBuffer->releaseResources();
- DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawingBuffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
- m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
-
- if (m_drawingBuffer->isZeroSized())
- return;
-
- m_drawingBuffer->bind();
-
- lost_context_errors_.clear();
-
- m_context = context;
- m_contextLost = false;
-
- setupFlags();
- initializeNewContext();
- canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextrestored, false, true, ""));
-}
-
-String WebGLRenderingContext::ensureNotNull(const String& text) const
-{
- if (text.isNull())
- return WTF::emptyString();
- return text;
-}
-
-WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
- : m_buffers(adoptArrayPtr(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 {
-
- String GetErrorString(GC3Denum error)
- {
- switch (error) {
- case GL_INVALID_ENUM:
- return "INVALID_ENUM";
- case GL_INVALID_VALUE:
- return "INVALID_VALUE";
- case GL_INVALID_OPERATION:
- return "INVALID_OPERATION";
- case GL_OUT_OF_MEMORY:
- return "OUT_OF_MEMORY";
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- return "INVALID_FRAMEBUFFER_OPERATION";
- case GC3D_CONTEXT_LOST_WEBGL:
- return "CONTEXT_LOST_WEBGL";
- default:
- return String::format("WebGL ERROR(0x%04X)", error);
- }
- }
-
-} // namespace anonymous
-
-void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
-{
- String errorType = GetErrorString(error);
- if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
- String message = String("WebGL: ") + errorType + ": " + String(functionName) + ": " + String(description);
- printGLErrorToConsole(message);
- }
- if (!isContextLost())
- m_context->synthesizeGLError(error);
- else {
- if (lost_context_errors_.find(error) == WTF::kNotFound)
- lost_context_errors_.append(error);
- }
- InspectorInstrumentation::didFireWebGLError(canvas(), errorType);
-}
-
-void WebGLRenderingContext::emitGLWarning(const char* functionName, const char* description)
-{
- if (m_synthesizedErrorsToConsole) {
- String message = String("WebGL: ") + String(functionName) + ": " + String(description);
- printGLErrorToConsole(message);
- }
- InspectorInstrumentation::didFireWebGLWarning(canvas());
-}
-
-void WebGLRenderingContext::applyStencilTest()
-{
- bool haveStencilBuffer = false;
-
- if (m_framebufferBinding)
- haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
- else {
- RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
- haveStencilBuffer = attributes->stencil();
- }
- enableOrDisable(GL_STENCIL_TEST,
- m_stencilEnabled && haveStencilBuffer);
-}
-
-void WebGLRenderingContext::enableOrDisable(GC3Denum capability, bool enable)
-{
- if (isContextLost())
- return;
- if (enable)
- m_context->enable(capability);
- else
- m_context->disable(capability);
-}
-
-IntSize WebGLRenderingContext::clampedCanvasSize()
-{
- return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
- clamp(canvas()->height(), 1, m_maxViewportDims[1]));
-}
-
-GC3Dint WebGLRenderingContext::maxDrawBuffers()
-{
- if (isContextLost() || !m_webglDrawBuffers)
- return 0;
- if (!m_maxDrawBuffers)
- m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
- return std::min(m_maxDrawBuffers, m_maxColorAttachments);
-}
-
-GC3Dint WebGLRenderingContext::maxColorAttachments()
-{
- if (isContextLost() || !m_webglDrawBuffers)
- return 0;
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- return m_maxColorAttachments;
-}
-
-void WebGLRenderingContext::setBackDrawBuffer(GC3Denum buf)
-{
- m_backDrawBuffer = buf;
-}
-
-void WebGLRenderingContext::restoreCurrentFramebuffer()
-{
- bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
-}
-
-void WebGLRenderingContext::restoreCurrentTexture2D()
-{
- bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
-}
-
-void WebGLRenderingContext::multisamplingChanged(bool enabled)
-{
- if (m_multisamplingAllowed != enabled) {
- m_multisamplingAllowed = enabled;
- forceLostContext(WebGLRenderingContext::AutoRecoverSyntheticLostContext);
- }
-}
-
-void WebGLRenderingContext::findNewMaxEnabledAttribIndex()
-{
- // Trace backwards from the current max to find the new max enabled attrib index
- int startIndex = m_onePlusMaxEnabledAttribIndex - 1;
- for (int i = startIndex; i >= 0; --i) {
- if (m_boundVertexArrayObject->getVertexAttribState(i).enabled) {
- m_onePlusMaxEnabledAttribIndex = i + 1;
- return;
- }
- }
- m_onePlusMaxEnabledAttribIndex = 0;
-}
-
-void WebGLRenderingContext::findNewMaxNonDefaultTextureUnit()
-{
- // Trace backwards from the current max to find the new max non-default texture unit
- int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1;
- for (int i = startIndex; i >= 0; --i) {
- if (m_textureUnits[i].m_texture2DBinding
- || m_textureUnits[i].m_textureCubeMapBinding) {
- m_onePlusMaxNonDefaultTextureUnit = i + 1;
- return;
- }
- }
- m_onePlusMaxNonDefaultTextureUnit = 0;
+ registerExtension<EXTShaderTextureLOD>(m_extShaderTextureLOD, DraftExtension);
+ registerExtension<WebGLCompressedTextureETC1>(m_webglCompressedTextureETC1, DraftExtension);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h
index e1e3911e9f1..db0e651b39c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h
@@ -26,497 +26,28 @@
#ifndef WebGLRenderingContext_h
#define WebGLRenderingContext_h
-#include "core/dom/ActiveDOMObject.h"
-#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/html/canvas/WebGLGetInfo.h"
-#include "core/page/Page.h"
-#include "platform/Timer.h"
-#include "platform/graphics/GraphicsContext3D.h"
-#include "platform/graphics/ImageBuffer.h"
-
-#include "wtf/Float32Array.h"
-#include "wtf/Int32Array.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink { class WebLayer; }
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-class ANGLEInstancedArrays;
-class DrawingBuffer;
-class EXTFragDepth;
-class EXTTextureFilterAnisotropic;
-class ExceptionState;
-class HTMLImageElement;
-class HTMLVideoElement;
-class ImageBuffer;
-class ImageData;
-class IntSize;
-class OESElementIndexUint;
-class OESStandardDerivatives;
-class OESTextureFloat;
-class OESTextureFloatLinear;
-class OESTextureHalfFloat;
-class OESTextureHalfFloatLinear;
-class OESVertexArrayObject;
-class WebGLActiveInfo;
-class WebGLBuffer;
-class WebGLCompressedTextureATC;
-class WebGLCompressedTexturePVRTC;
-class WebGLCompressedTextureS3TC;
-class WebGLContextAttributes;
-class WebGLContextGroup;
-class WebGLContextObject;
-class WebGLDebugRendererInfo;
-class WebGLDebugShaders;
-class WebGLDepthTexture;
-class WebGLDrawBuffers;
-class WebGLExtension;
-class WebGLFramebuffer;
-class WebGLLoseContext;
-class WebGLObject;
-class WebGLProgram;
-class WebGLRenderbuffer;
-class WebGLShader;
-class WebGLShaderPrecisionFormat;
-class WebGLSharedObject;
-class WebGLTexture;
-class WebGLUniformLocation;
-class WebGLVertexArrayObjectOES;
-
-class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject, private Page::MultisamplingChangedObserver {
+class WebGLRenderingContext FINAL : public WebGLRenderingContextBase, public ScriptWrappable {
public:
- static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
+ static PassOwnPtrWillBeRawPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
virtual ~WebGLRenderingContext();
- virtual bool is3d() const { return true; }
- virtual bool isAccelerated() const { return true; }
-
- int drawingBufferWidth() const;
- int drawingBufferHeight() const;
-
- void activeTexture(GC3Denum texture);
- void attachShader(WebGLProgram*, WebGLShader*);
- void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name);
- void bindBuffer(GC3Denum target, WebGLBuffer*);
- void bindFramebuffer(GC3Denum target, WebGLFramebuffer*);
- void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*);
- void bindTexture(GC3Denum target, WebGLTexture*);
- void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void blendEquation(GC3Denum mode);
- void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
- void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
- void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
-
- void bufferData(GC3Denum target, long long size, GC3Denum usage);
- void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage);
- void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage);
- void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data);
- void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data);
-
- GC3Denum checkFramebufferStatus(GC3Denum target);
- void clear(GC3Dbitfield mask);
- void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void clearDepth(GC3Dfloat);
- void clearStencil(GC3Dint);
- void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
- void compileShader(WebGLShader*);
-
- void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
- void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
-
- void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
- void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- PassRefPtr<WebGLBuffer> createBuffer();
- PassRefPtr<WebGLFramebuffer> createFramebuffer();
- PassRefPtr<WebGLProgram> createProgram();
- PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
- PassRefPtr<WebGLShader> createShader(GC3Denum type);
- PassRefPtr<WebGLTexture> createTexture();
-
- void cullFace(GC3Denum mode);
-
- void deleteBuffer(WebGLBuffer*);
- void deleteFramebuffer(WebGLFramebuffer*);
- void deleteProgram(WebGLProgram*);
- void deleteRenderbuffer(WebGLRenderbuffer*);
- void deleteShader(WebGLShader*);
- void deleteTexture(WebGLTexture*);
-
- void depthFunc(GC3Denum);
- void depthMask(GC3Dboolean);
- void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
- void detachShader(WebGLProgram*, WebGLShader*);
- void disable(GC3Denum cap);
- void disableVertexAttribArray(GC3Duint index);
- void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
- void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
-
- void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount);
-
- void enable(GC3Denum cap);
- void enableVertexAttribArray(GC3Duint index);
- void finish();
- void flush();
- void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*);
- void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level);
- void frontFace(GC3Denum mode);
- void generateMipmap(GC3Denum target);
-
- PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index);
- PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index);
- bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
- GC3Dint getAttribLocation(WebGLProgram*, const String& name);
- WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname);
- PassRefPtr<WebGLContextAttributes> getContextAttributes();
- GC3Denum getError();
- PassRefPtr<WebGLExtension> getExtension(const String& name);
- WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname);
- WebGLGetInfo getParameter(GC3Denum pname);
- WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname);
- String getProgramInfoLog(WebGLProgram*);
- WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname);
- WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname);
- String getShaderInfoLog(WebGLShader*);
- PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType);
- String getShaderSource(WebGLShader*);
- Vector<String> getSupportedExtensions();
- WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname);
- WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
- PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
- WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname);
- long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
-
- void hint(GC3Denum target, GC3Denum mode);
- GC3Dboolean isBuffer(WebGLBuffer*);
- bool isContextLost();
- GC3Dboolean isEnabled(GC3Denum cap);
- GC3Dboolean isFramebuffer(WebGLFramebuffer*);
- GC3Dboolean isProgram(WebGLProgram*);
- GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
- GC3Dboolean isShader(WebGLShader*);
- GC3Dboolean isTexture(WebGLTexture*);
-
- void lineWidth(GC3Dfloat);
- void linkProgram(WebGLProgram*);
- void pixelStorei(GC3Denum pname, GC3Dint param);
- void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
- void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels);
- void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
- void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
- void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void shaderSource(WebGLShader*, const String&);
- void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilMask(GC3Duint);
- void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
- void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
- void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
-
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&);
-
- void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
- void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
-
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&);
-
- void uniform1f(const WebGLUniformLocation*, GC3Dfloat x);
- void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform1fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform1i(const WebGLUniformLocation*, GC3Dint x);
- void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform1iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniform2f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y);
- void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform2fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform2i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y);
- void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform2iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniform3f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform3fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform3i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z);
- void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform3iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniform4f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform4fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform4i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
- void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform4iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
- void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
- void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
-
- void useProgram(WebGLProgram*);
- void validateProgram(WebGLProgram*);
-
- void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
- void vertexAttrib1fv(GC3Duint index, Float32Array* values);
- void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
- void vertexAttrib2fv(GC3Duint index, Float32Array* values);
- void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void vertexAttrib3fv(GC3Duint index, Float32Array* values);
- void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void vertexAttrib4fv(GC3Duint index, Float32Array* values);
- void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
- GC3Dsizei stride, long long offset);
-
- void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
-
- void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- // WEBKIT_lose_context support
- enum LostContextMode {
- // Lost context occurred at the graphics system level.
- RealLostContext,
-
- // Lost context provoked by WEBKIT_lose_context.
- SyntheticLostContext,
-
- // A synthetic lost context that should attempt to recover automatically
- AutoRecoverSyntheticLostContext
- };
- void forceLostContext(LostContextMode);
- void forceRestoreContext();
- void loseContextImpl(LostContextMode);
-
- GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
- WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
- virtual blink::WebLayer* platformLayer() const;
-
- void reshape(int width, int height);
-
- void markLayerComposited();
- virtual void paintRenderingResultsToCanvas();
- virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
-
- void removeSharedObject(WebGLSharedObject*);
- void removeContextObject(WebGLContextObject*);
-
- unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
-
- // ActiveDOMObject notifications
- virtual bool hasPendingActivity() const;
- virtual void stop();
-
- private:
- friend class WebGLDrawBuffers;
- friend class WebGLFramebuffer;
- friend class WebGLObject;
- friend class OESVertexArrayObject;
- friend class WebGLDebugShaders;
- friend class WebGLCompressedTextureATC;
- friend class WebGLCompressedTexturePVRTC;
- friend class WebGLCompressedTextureS3TC;
- friend class WebGLRenderingContextErrorMessageCallback;
- friend class WebGLVertexArrayObjectOES;
-
- WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes, GraphicsContext3D::Attributes);
- void initializeNewContext();
- void setupFlags();
-
- void addSharedObject(WebGLSharedObject*);
- void addContextObject(WebGLContextObject*);
- void detachAndRemoveAllObjects();
-
- void destroyGraphicsContext3D();
- void markContextChanged();
+ virtual unsigned version() const OVERRIDE { return 1; }
+ virtual String contextName() const OVERRIDE { return "WebGLRenderingContext"; }
+ virtual void registerContextExtensions() OVERRIDE;
- // Query if the GL implementation is NPOT strict.
- bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
- // Query if depth_stencil buffer is supported.
- bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
-
- // Helper to return the size in bytes of OpenGL data types
- // like GL_FLOAT, GL_INT, etc.
- unsigned int sizeInBytes(GC3Denum type);
-
- // Check if each enabled vertex attribute is bound to a buffer.
- bool validateRenderingState();
-
- bool validateWebGLObject(const char*, WebGLObject*);
-
- // Adds a compressed texture format.
- void addCompressedTextureFormat(GC3Denum);
- void removeAllCompressedTextureFormats();
-
- PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height);
-
- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
-
- WebGLRenderbuffer* ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer*);
-
- RefPtr<GraphicsContext3D> m_context;
- RefPtr<WebGLContextGroup> m_contextGroup;
-
- // Structure for rendering to a DrawingBuffer, instead of directly
- // to the back-buffer of m_context.
- RefPtr<DrawingBuffer> m_drawingBuffer;
-
- // Dispatches a context lost event once it is determined that one is needed.
- // This is used both for synthetic and real context losses. For real ones, it's
- // likely that there's no JavaScript on the stack, but that might be dependent
- // on how exactly the platform discovers that the context was lost. For better
- // portability we always defer the dispatch of the event.
- Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
- bool m_restoreAllowed;
- Timer<WebGLRenderingContext> m_restoreTimer;
-
- bool m_needsUpdate;
- bool m_markedCanvasDirty;
- HashSet<WebGLContextObject*> m_contextObjects;
-
- // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
- RefPtr<WebGLBuffer> m_boundArrayBuffer;
-
- RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
- RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
- void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
- {
- if (arrayObject)
- m_boundVertexArrayObject = arrayObject;
- else
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
- }
-
- class VertexAttribValue {
- public:
- VertexAttribValue()
- {
- initValue();
- }
-
- void initValue()
- {
- value[0] = 0.0f;
- value[1] = 0.0f;
- value[2] = 0.0f;
- value[3] = 1.0f;
- }
-
- GC3Dfloat value[4];
- };
- Vector<VertexAttribValue> m_vertexAttribValue;
- unsigned m_maxVertexAttribs;
- RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
- long m_vertexAttrib0BufferSize;
- GC3Dfloat m_vertexAttrib0BufferValue[4];
- bool m_forceAttrib0BufferRefill;
- bool m_vertexAttrib0UsedBefore;
-
- RefPtr<WebGLProgram> m_currentProgram;
- RefPtr<WebGLFramebuffer> m_framebufferBinding;
- RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
- 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;
-
- Vector<GC3Denum> m_compressedTextureFormats;
-
- // Fixed-size cache of reusable image buffers for video texImage2D calls.
- class LRUImageBufferCache {
- public:
- LRUImageBufferCache(int capacity);
- // The pointer returned is owned by the image buffer map.
- ImageBuffer* imageBuffer(const IntSize& size);
- private:
- void bubbleToFront(int idx);
- OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
- int m_capacity;
- };
- LRUImageBufferCache m_generatedImageCache;
-
- GC3Dint m_maxTextureSize;
- GC3Dint m_maxCubeMapTextureSize;
- GC3Dint m_maxRenderbufferSize;
- GC3Dint m_maxViewportDims[2];
- GC3Dint m_maxTextureLevel;
- GC3Dint m_maxCubeMapTextureLevel;
-
- GC3Dint m_maxDrawBuffers;
- GC3Dint m_maxColorAttachments;
- GC3Denum m_backDrawBuffer;
- bool m_drawBuffersWebGLRequirementsChecked;
- bool m_drawBuffersSupported;
-
- GC3Dint m_packAlignment;
- GC3Dint m_unpackAlignment;
- bool m_unpackFlipY;
- bool m_unpackPremultiplyAlpha;
- GC3Denum m_unpackColorspaceConversion;
- bool m_contextLost;
- LostContextMode m_contextLostMode;
- GraphicsContext3D::Attributes m_attributes;
- GraphicsContext3D::Attributes m_requestedAttributes;
-
- bool m_layerCleared;
- GC3Dfloat m_clearColor[4];
- bool m_scissorEnabled;
- GC3Dfloat m_clearDepth;
- GC3Dint m_clearStencil;
- GC3Dboolean m_colorMask[4];
- GC3Dboolean m_depthMask;
-
- bool m_stencilEnabled;
- GC3Duint m_stencilMask, m_stencilMaskBack;
- GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
- GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
-
- bool m_isGLES2NPOTStrict;
- bool m_isDepthStencilSupported;
-
- bool m_synthesizedErrorsToConsole;
- int m_numGLErrorsToConsoleAllowed;
-
- bool m_multisamplingAllowed;
- bool m_multisamplingObserverRegistered;
-
- GC3Duint m_onePlusMaxEnabledAttribIndex;
- unsigned long m_onePlusMaxNonDefaultTextureUnit;
+private:
+ WebGLRenderingContext(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
// Enabled extension objects.
RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
+ RefPtr<EXTBlendMinMax> m_extBlendMinMax;
RefPtr<EXTFragDepth> m_extFragDepth;
+ RefPtr<EXTShaderTextureLOD> m_extShaderTextureLOD;
RefPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
RefPtr<OESTextureFloat> m_oesTextureFloat;
RefPtr<OESTextureFloatLinear> m_oesTextureFloatLinear;
@@ -530,403 +61,15 @@ public:
RefPtr<WebGLDebugShaders> m_webglDebugShaders;
RefPtr<WebGLDrawBuffers> m_webglDrawBuffers;
RefPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
+ RefPtr<WebGLCompressedTextureETC1> m_webglCompressedTextureETC1;
RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
RefPtr<WebGLDepthTexture> m_webglDepthTexture;
-
- enum ExtensionFlags {
- ApprovedExtension = 0x00,
- DraftExtension = 0x01,
- PrivilegedExtension = 0x02,
- PrefixedExtension = 0x04,
- WebGLDebugRendererInfoExtension = 0x08,
- };
-
- class ExtensionTracker {
- public:
- ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
- : m_privileged(flags & PrivilegedExtension)
- , m_draft(flags & DraftExtension)
- , m_prefixed(flags & PrefixedExtension)
- , m_webglDebugRendererInfo(flags & WebGLDebugRendererInfoExtension)
- , m_prefixes(prefixes)
- {
- }
-
- virtual ~ExtensionTracker()
- {
- }
-
- bool prefixed() const
- {
- return m_prefixed;
- }
-
- bool privileged() const
- {
- return m_privileged;
- }
-
- bool draft() const
- {
- return m_draft;
- }
-
- bool webglDebugRendererInfo() const
- {
- return m_webglDebugRendererInfo;
- }
-
- bool matchesNameWithPrefixes(const String&) const;
-
- virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext*) const = 0;
- virtual bool supported(WebGLRenderingContext*) const = 0;
- virtual const char* extensionName() const = 0;
- virtual void loseExtension() = 0;
-
- private:
- bool m_privileged;
- bool m_draft;
- bool m_prefixed;
- bool m_webglDebugRendererInfo;
- const char* const* m_prefixes;
- };
-
- template <typename T>
- class TypedExtensionTracker : public ExtensionTracker {
- public:
- TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
- : ExtensionTracker(flags, prefixes)
- , m_extensionField(extensionField)
- {
- }
-
- ~TypedExtensionTracker()
- {
- if (m_extensionField) {
- m_extensionField->lose(true);
- m_extensionField = 0;
- }
- }
-
- virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext* context) const
- {
- if (!m_extensionField)
- m_extensionField = T::create(context);
-
- return m_extensionField;
- }
-
- virtual bool supported(WebGLRenderingContext* context) const
- {
- return T::supported(context);
- }
-
- virtual const char* extensionName() const
- {
- return T::extensionName();
- }
-
- virtual void loseExtension()
- {
- if (m_extensionField) {
- m_extensionField->lose(false);
- if (m_extensionField->isLost())
- m_extensionField = 0;
- }
- }
-
- private:
- RefPtr<T>& m_extensionField;
- };
-
- Vector<ExtensionTracker*> m_extensions;
-
- template <typename T>
- void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
- {
- m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes));
- }
-
- // Errors raised by synthesizeGLError() while the context is lost.
- Vector<GC3Denum> lost_context_errors_;
-
- // Helpers for getParameter and others
- WebGLGetInfo getBooleanParameter(GC3Denum);
- WebGLGetInfo getBooleanArrayParameter(GC3Denum);
- WebGLGetInfo getFloatParameter(GC3Denum);
- WebGLGetInfo getIntParameter(GC3Denum);
- WebGLGetInfo getUnsignedIntParameter(GC3Denum);
- WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum);
- WebGLGetInfo getWebGLIntArrayParameter(GC3Denum);
-
- // Clear the backbuffer if it was composited since the last operation.
- // clearMask is set to the bitfield of any clear that would happen anyway at this time
- // and the function returns true if that clear is now unnecessary.
- bool clearIfComposited(GC3Dbitfield clearMask = 0);
-
- // Helper to restore state that clearing the framebuffer may destroy.
- void restoreStateAfterClear();
-
- void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&);
- void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
- void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&);
- void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
-
- void handleTextureCompleteness(const char*, bool);
- void createFallbackBlackTextures1x1();
-
- // Helper function for copyTex{Sub}Image, check whether the internalformat
- // and the color buffer format of the current bound framebuffer combination
- // is valid.
- bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat);
-
- // Helper function to get the bound framebuffer's color buffer format.
- GC3Denum boundFramebufferColorFormat();
-
- // Helper function to get the bound framebuffer's width.
- int boundFramebufferWidth();
-
- // Helper function to get the bound framebuffer's height.
- int boundFramebufferHeight();
-
- // Helper function to verify limits on the length of uniform and attribute locations.
- bool validateLocationLength(const char* functionName, const String&);
-
- // Helper function to check if size is non-negative.
- // Generate GL error and return false for negative inputs; otherwise, return true.
- bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
-
- // Helper function to check if all characters in the string belong to the
- // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
- bool validateString(const char* functionName, const String&);
-
- // Helper function to check target and texture bound to the target.
- // Generate GL errors and return 0 if target is invalid or texture bound is
- // null. Otherwise, return the texture bound to the target.
- WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
-
- // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
-
- // Helper function to check input level for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if level is invalid.
- bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
-
- enum TexFuncValidationFunctionType {
- NotTexSubImage2D,
- TexSubImage2D,
- };
-
- enum TexFuncValidationSourceType {
- SourceArrayBufferView,
- SourceImageData,
- SourceHTMLImageElement,
- SourceHTMLCanvasElement,
- SourceHTMLVideoElement,
- };
-
- // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
- // Otherwise, it would return quickly without doing other work.
- bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
-
- // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
- // Generates GL error and returns false if width or height is invalid.
- bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height);
-
- // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type);
-
- enum NullDisposition {
- NullAllowed,
- NullNotAllowed
- };
-
- // Helper function to validate that the given ArrayBufferView
- // is of the correct type and contains enough data for the texImage call.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition);
-
- // Helper function to validate a given texture format is settable as in
- // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
- // copyTexSubImage2D.
- // Generates GL error and returns false if the format is not settable.
- bool validateSettableTexFormat(const char* functionName, GC3Denum format);
-
- // Helper function to validate compressed texture data is correct size
- // for the given format and dimensions.
- bool validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels);
-
- // Helper function for validating compressed texture formats.
- bool validateCompressedTexFormat(GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
-
- // Helper function to validate mode for draw{Arrays/Elements}.
- bool validateDrawMode(const char* functionName, GC3Denum);
-
- // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
- bool validateStencilSettings(const char* functionName);
-
- // Helper function to validate stencil or depth func.
- bool validateStencilOrDepthFunc(const char* functionName, GC3Denum);
-
- // Helper function for texParameterf and texParameteri.
- void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
-
- // Helper function to print GL errors to console.
- void printGLErrorToConsole(const String&);
-
- // Helper function to print warnings to console. Currently
- // used only to warn about use of obsolete functions.
- void printWarningToConsole(const String&);
-
- // Helper function to validate input parameters for framebuffer functions.
- // Generate GL error if parameters are illegal.
- bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
-
- // Helper function to validate blend equation mode.
- bool validateBlendEquation(const char* functionName, GC3Denum);
-
- // Helper function to validate blend func factors.
- bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
-
- // Helper function to validate a GL capability.
- bool validateCapability(const char* functionName, GC3Denum);
-
- // Helper function to validate input parameters for uniform functions.
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
-
- // Helper function to validate parameters for bufferData.
- // Return the current bound buffer to target, or 0 if parameters are invalid.
- WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
-
- // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
- bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
-
- // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
- bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
-
- // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
- bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
-
- // Helper function to validate drawArrays(Instanced) calls
- bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count);
-
- // Helper function to validate drawElements(Instanced) calls
- bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
-
- // Helper function to validate draw*Instanced calls
- bool validateDrawInstanced(const char* functionName, GC3Dsizei primcount);
-
- // Helper functions for vertexAttribNf{v}.
- void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
-
- // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
- // Return false if caller should return without further processing.
- bool deleteObject(WebGLObject*);
-
- // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
- // If the object has already been deleted, set deleted to true upon return.
- // Return false if caller should return without further processing.
- bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
-
- void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
- // Helper for restoration after context lost.
- void maybeRestoreContext(Timer<WebGLRenderingContext>*);
-
- // Determine if we are running privileged code in the browser, for example,
- // a Safari or Chrome extension.
- bool allowPrivilegedExtensions() const;
-
- // Determine if WEBGL_debug_renderer_info extension is enabled. For the
- // moment it can be enabled either through a chromium finch experiment
- // or for privileged code in the browser.
- bool allowWebGLDebugRendererInfo() const;
-
- enum ConsoleDisplayPreference {
- DisplayInConsole,
- DontDisplayInConsole
- };
-
- // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
- // to the JavaScript console.
- void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
- void emitGLWarning(const char* function, const char* reason);
-
- String ensureNotNull(const String&) const;
-
- // Enable or disable stencil test based on user setting and
- // whether the current FBO has a stencil buffer.
- void applyStencilTest();
-
- // Helper for enabling or disabling a capability.
- void enableOrDisable(GC3Denum capability, bool enable);
-
- // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
- IntSize clampedCanvasSize();
-
- // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
- // Later, return the cached value.
- GC3Dint maxDrawBuffers();
- GC3Dint maxColorAttachments();
-
- void setBackDrawBuffer(GC3Denum);
-
- void restoreCurrentFramebuffer();
- void restoreCurrentTexture2D();
-
- virtual void multisamplingChanged(bool);
-
- void findNewMaxEnabledAttribIndex();
- void findNewMaxNonDefaultTextureUnit();
-
- friend class WebGLStateRestorer;
- friend class WebGLRenderingContextEvictionManager;
-
- static Vector<WebGLRenderingContext*>& activeContexts();
- static Vector<WebGLRenderingContext*>& forciblyEvictedContexts();
-
- static void activateContext(WebGLRenderingContext*);
- static void deactivateContext(WebGLRenderingContext*, bool addToInactiveList);
- static void willDestroyContext(WebGLRenderingContext*);
- static void forciblyLoseOldestContext(const String& reason);
- // Return the least recently used context's position in the active context vector.
- // If the vector is empty, return the maximum allowed active context number.
- static size_t oldestContextIndex();
- static IntSize oldestContextSize();
};
-DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context, context->is3d(), context.is3d());
+DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context,
+ context->is3d() && WebGLRenderingContextBase::getWebGLVersion(context) == 1,
+ context.is3d() && WebGLRenderingContextBase::getWebGLVersion(&context) == 1);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl
index a006bae1c53..ce2d4837ff3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl
@@ -23,640 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-typedef unsigned long GLenum;
-typedef boolean GLboolean;
-typedef unsigned long GLbitfield;
-typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
-typedef short GLshort;
-typedef long GLint;
-typedef long GLsizei;
-typedef long long GLintptr;
-typedef long long GLsizeiptr;
-typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
-typedef unsigned short GLushort;
-typedef unsigned long GLuint;
-typedef /*unrestricted*/ float GLfloat;
-typedef /*unrestricted*/ float GLclampf;
+// http://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext
[
- DoNotCheckConstants
-] interface WebGLRenderingContext : CanvasRenderingContext {
-
- /* ClearBufferMask */
- const GLenum DEPTH_BUFFER_BIT = 0x00000100;
- const GLenum STENCIL_BUFFER_BIT = 0x00000400;
- const GLenum COLOR_BUFFER_BIT = 0x00004000;
-
- /* BeginMode */
- const GLenum POINTS = 0x0000;
- const GLenum LINES = 0x0001;
- const GLenum LINE_LOOP = 0x0002;
- const GLenum LINE_STRIP = 0x0003;
- const GLenum TRIANGLES = 0x0004;
- const GLenum TRIANGLE_STRIP = 0x0005;
- const GLenum TRIANGLE_FAN = 0x0006;
-
- /* AlphaFunction (not supported in ES20) */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* BlendingFactorDest */
- const GLenum ZERO = 0;
- const GLenum ONE = 1;
- const GLenum SRC_COLOR = 0x0300;
- const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
- const GLenum SRC_ALPHA = 0x0302;
- const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
- const GLenum DST_ALPHA = 0x0304;
- const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
-
- /* BlendingFactorSrc */
- /* ZERO */
- /* ONE */
- const GLenum DST_COLOR = 0x0306;
- const GLenum ONE_MINUS_DST_COLOR = 0x0307;
- const GLenum SRC_ALPHA_SATURATE = 0x0308;
- /* SRC_ALPHA */
- /* ONE_MINUS_SRC_ALPHA */
- /* DST_ALPHA */
- /* ONE_MINUS_DST_ALPHA */
-
- /* BlendEquationSeparate */
- const GLenum FUNC_ADD = 0x8006;
- const GLenum BLEND_EQUATION = 0x8009;
- const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
- const GLenum BLEND_EQUATION_ALPHA = 0x883D;
-
- /* BlendSubtract */
- const GLenum FUNC_SUBTRACT = 0x800A;
- const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
-
- /* Separate Blend Functions */
- const GLenum BLEND_DST_RGB = 0x80C8;
- const GLenum BLEND_SRC_RGB = 0x80C9;
- const GLenum BLEND_DST_ALPHA = 0x80CA;
- const GLenum BLEND_SRC_ALPHA = 0x80CB;
- const GLenum CONSTANT_COLOR = 0x8001;
- const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
- const GLenum CONSTANT_ALPHA = 0x8003;
- const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
- const GLenum BLEND_COLOR = 0x8005;
-
- /* Buffer Objects */
- const GLenum ARRAY_BUFFER = 0x8892;
- const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
- const GLenum ARRAY_BUFFER_BINDING = 0x8894;
- const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
-
- const GLenum STREAM_DRAW = 0x88E0;
- const GLenum STATIC_DRAW = 0x88E4;
- const GLenum DYNAMIC_DRAW = 0x88E8;
-
- const GLenum BUFFER_SIZE = 0x8764;
- const GLenum BUFFER_USAGE = 0x8765;
-
- const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
-
- /* CullFaceMode */
- const GLenum FRONT = 0x0404;
- const GLenum BACK = 0x0405;
- const GLenum FRONT_AND_BACK = 0x0408;
-
- /* DepthFunction */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* EnableCap */
- const GLenum TEXTURE_2D = 0x0DE1;
- const GLenum CULL_FACE = 0x0B44;
- const GLenum BLEND = 0x0BE2;
- const GLenum DITHER = 0x0BD0;
- const GLenum STENCIL_TEST = 0x0B90;
- const GLenum DEPTH_TEST = 0x0B71;
- const GLenum SCISSOR_TEST = 0x0C11;
- const GLenum POLYGON_OFFSET_FILL = 0x8037;
- const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
- const GLenum SAMPLE_COVERAGE = 0x80A0;
-
- /* ErrorCode */
- const GLenum NO_ERROR = 0;
- const GLenum INVALID_ENUM = 0x0500;
- const GLenum INVALID_VALUE = 0x0501;
- const GLenum INVALID_OPERATION = 0x0502;
- const GLenum OUT_OF_MEMORY = 0x0505;
-
- /* FrontFaceDirection */
- const GLenum CW = 0x0900;
- const GLenum CCW = 0x0901;
-
- /* GetPName */
- const GLenum LINE_WIDTH = 0x0B21;
- const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
- const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
- const GLenum CULL_FACE_MODE = 0x0B45;
- const GLenum FRONT_FACE = 0x0B46;
- const GLenum DEPTH_RANGE = 0x0B70;
- const GLenum DEPTH_WRITEMASK = 0x0B72;
- const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
- const GLenum DEPTH_FUNC = 0x0B74;
- const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
- const GLenum STENCIL_FUNC = 0x0B92;
- const GLenum STENCIL_FAIL = 0x0B94;
- const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
- const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
- const GLenum STENCIL_REF = 0x0B97;
- const GLenum STENCIL_VALUE_MASK = 0x0B93;
- const GLenum STENCIL_WRITEMASK = 0x0B98;
- const GLenum STENCIL_BACK_FUNC = 0x8800;
- const GLenum STENCIL_BACK_FAIL = 0x8801;
- const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
- const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
- const GLenum STENCIL_BACK_REF = 0x8CA3;
- const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
- const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
- const GLenum VIEWPORT = 0x0BA2;
- const GLenum SCISSOR_BOX = 0x0C10;
- /* SCISSOR_TEST */
- const GLenum COLOR_CLEAR_VALUE = 0x0C22;
- const GLenum COLOR_WRITEMASK = 0x0C23;
- const GLenum UNPACK_ALIGNMENT = 0x0CF5;
- const GLenum PACK_ALIGNMENT = 0x0D05;
- const GLenum MAX_TEXTURE_SIZE = 0x0D33;
- const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
- const GLenum SUBPIXEL_BITS = 0x0D50;
- const GLenum RED_BITS = 0x0D52;
- const GLenum GREEN_BITS = 0x0D53;
- const GLenum BLUE_BITS = 0x0D54;
- const GLenum ALPHA_BITS = 0x0D55;
- const GLenum DEPTH_BITS = 0x0D56;
- const GLenum STENCIL_BITS = 0x0D57;
- const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
- /* POLYGON_OFFSET_FILL */
- const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
- const GLenum TEXTURE_BINDING_2D = 0x8069;
- const GLenum SAMPLE_BUFFERS = 0x80A8;
- const GLenum SAMPLES = 0x80A9;
- const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
- const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
-
- /* GetTextureParameter */
- /* TEXTURE_MAG_FILTER */
- /* TEXTURE_MIN_FILTER */
- /* TEXTURE_WRAP_S */
- /* TEXTURE_WRAP_T */
-
- const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
-
- /* HintMode */
- const GLenum DONT_CARE = 0x1100;
- const GLenum FASTEST = 0x1101;
- const GLenum NICEST = 0x1102;
-
- /* HintTarget */
- const GLenum GENERATE_MIPMAP_HINT = 0x8192;
-
- /* DataType */
- const GLenum BYTE = 0x1400;
- const GLenum UNSIGNED_BYTE = 0x1401;
- const GLenum SHORT = 0x1402;
- const GLenum UNSIGNED_SHORT = 0x1403;
- const GLenum INT = 0x1404;
- const GLenum UNSIGNED_INT = 0x1405;
- const GLenum FLOAT = 0x1406;
-
- /* PixelFormat */
- const GLenum DEPTH_COMPONENT = 0x1902;
- const GLenum ALPHA = 0x1906;
- const GLenum RGB = 0x1907;
- const GLenum RGBA = 0x1908;
- const GLenum LUMINANCE = 0x1909;
- const GLenum LUMINANCE_ALPHA = 0x190A;
-
- /* PixelType */
- /* UNSIGNED_BYTE */
- const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
- const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
- const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
-
- /* Shaders */
- const GLenum FRAGMENT_SHADER = 0x8B30;
- const GLenum VERTEX_SHADER = 0x8B31;
- const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
- const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
- const GLenum MAX_VARYING_VECTORS = 0x8DFC;
- const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
- const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
- const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
- const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
- const GLenum SHADER_TYPE = 0x8B4F;
- const GLenum DELETE_STATUS = 0x8B80;
- const GLenum LINK_STATUS = 0x8B82;
- const GLenum VALIDATE_STATUS = 0x8B83;
- const GLenum ATTACHED_SHADERS = 0x8B85;
- const GLenum ACTIVE_UNIFORMS = 0x8B86;
- const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
- const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
- const GLenum CURRENT_PROGRAM = 0x8B8D;
-
- /* StencilFunction */
- const GLenum NEVER = 0x0200;
- const GLenum LESS = 0x0201;
- const GLenum EQUAL = 0x0202;
- const GLenum LEQUAL = 0x0203;
- const GLenum GREATER = 0x0204;
- const GLenum NOTEQUAL = 0x0205;
- const GLenum GEQUAL = 0x0206;
- const GLenum ALWAYS = 0x0207;
-
- /* StencilOp */
- /* ZERO */
- const GLenum KEEP = 0x1E00;
- const GLenum REPLACE = 0x1E01;
- const GLenum INCR = 0x1E02;
- const GLenum DECR = 0x1E03;
- const GLenum INVERT = 0x150A;
- const GLenum INCR_WRAP = 0x8507;
- const GLenum DECR_WRAP = 0x8508;
-
- /* StringName */
- const GLenum VENDOR = 0x1F00;
- const GLenum RENDERER = 0x1F01;
- const GLenum VERSION = 0x1F02;
-
- /* TextureMagFilter */
- const GLenum NEAREST = 0x2600;
- const GLenum LINEAR = 0x2601;
-
- /* TextureMinFilter */
- /* NEAREST */
- /* LINEAR */
- const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
- const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
- const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
- const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
-
- /* TextureParameterName */
- const GLenum TEXTURE_MAG_FILTER = 0x2800;
- const GLenum TEXTURE_MIN_FILTER = 0x2801;
- const GLenum TEXTURE_WRAP_S = 0x2802;
- const GLenum TEXTURE_WRAP_T = 0x2803;
-
- /* TextureTarget */
- /* TEXTURE_2D */
- const GLenum TEXTURE = 0x1702;
-
- const GLenum TEXTURE_CUBE_MAP = 0x8513;
- const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
- const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
-
- /* TextureUnit */
- const GLenum TEXTURE0 = 0x84C0;
- const GLenum TEXTURE1 = 0x84C1;
- const GLenum TEXTURE2 = 0x84C2;
- const GLenum TEXTURE3 = 0x84C3;
- const GLenum TEXTURE4 = 0x84C4;
- const GLenum TEXTURE5 = 0x84C5;
- const GLenum TEXTURE6 = 0x84C6;
- const GLenum TEXTURE7 = 0x84C7;
- const GLenum TEXTURE8 = 0x84C8;
- const GLenum TEXTURE9 = 0x84C9;
- const GLenum TEXTURE10 = 0x84CA;
- const GLenum TEXTURE11 = 0x84CB;
- const GLenum TEXTURE12 = 0x84CC;
- const GLenum TEXTURE13 = 0x84CD;
- const GLenum TEXTURE14 = 0x84CE;
- const GLenum TEXTURE15 = 0x84CF;
- const GLenum TEXTURE16 = 0x84D0;
- const GLenum TEXTURE17 = 0x84D1;
- const GLenum TEXTURE18 = 0x84D2;
- const GLenum TEXTURE19 = 0x84D3;
- const GLenum TEXTURE20 = 0x84D4;
- const GLenum TEXTURE21 = 0x84D5;
- const GLenum TEXTURE22 = 0x84D6;
- const GLenum TEXTURE23 = 0x84D7;
- const GLenum TEXTURE24 = 0x84D8;
- const GLenum TEXTURE25 = 0x84D9;
- const GLenum TEXTURE26 = 0x84DA;
- const GLenum TEXTURE27 = 0x84DB;
- const GLenum TEXTURE28 = 0x84DC;
- const GLenum TEXTURE29 = 0x84DD;
- const GLenum TEXTURE30 = 0x84DE;
- const GLenum TEXTURE31 = 0x84DF;
- const GLenum ACTIVE_TEXTURE = 0x84E0;
-
- /* TextureWrapMode */
- const GLenum REPEAT = 0x2901;
- const GLenum CLAMP_TO_EDGE = 0x812F;
- const GLenum MIRRORED_REPEAT = 0x8370;
-
- /* Uniform Types */
- const GLenum FLOAT_VEC2 = 0x8B50;
- const GLenum FLOAT_VEC3 = 0x8B51;
- const GLenum FLOAT_VEC4 = 0x8B52;
- const GLenum INT_VEC2 = 0x8B53;
- const GLenum INT_VEC3 = 0x8B54;
- const GLenum INT_VEC4 = 0x8B55;
- const GLenum BOOL = 0x8B56;
- const GLenum BOOL_VEC2 = 0x8B57;
- const GLenum BOOL_VEC3 = 0x8B58;
- const GLenum BOOL_VEC4 = 0x8B59;
- const GLenum FLOAT_MAT2 = 0x8B5A;
- const GLenum FLOAT_MAT3 = 0x8B5B;
- const GLenum FLOAT_MAT4 = 0x8B5C;
- const GLenum SAMPLER_2D = 0x8B5E;
- const GLenum SAMPLER_CUBE = 0x8B60;
-
- /* Vertex Arrays */
- const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
- const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
- const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
- const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
- const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
- const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
- const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
-
- /* Shader Source */
- const GLenum COMPILE_STATUS = 0x8B81;
-
- /* Shader Precision-Specified Types */
- const GLenum LOW_FLOAT = 0x8DF0;
- const GLenum MEDIUM_FLOAT = 0x8DF1;
- const GLenum HIGH_FLOAT = 0x8DF2;
- const GLenum LOW_INT = 0x8DF3;
- const GLenum MEDIUM_INT = 0x8DF4;
- const GLenum HIGH_INT = 0x8DF5;
-
- /* Framebuffer Object. */
- const GLenum FRAMEBUFFER = 0x8D40;
- const GLenum RENDERBUFFER = 0x8D41;
-
- const GLenum RGBA4 = 0x8056;
- const GLenum RGB5_A1 = 0x8057;
- const GLenum RGB565 = 0x8D62;
- const GLenum DEPTH_COMPONENT16 = 0x81A5;
- const GLenum STENCIL_INDEX = 0x1901;
- const GLenum STENCIL_INDEX8 = 0x8D48;
- const GLenum DEPTH_STENCIL = 0x84F9;
-
- const GLenum RENDERBUFFER_WIDTH = 0x8D42;
- const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
- const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
- const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
- const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
- const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
- const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
- const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
- const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
-
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
-
- const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
- const GLenum DEPTH_ATTACHMENT = 0x8D00;
- const GLenum STENCIL_ATTACHMENT = 0x8D20;
- const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
-
- const GLenum NONE = 0;
-
- const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
- const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
- const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
- const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
- const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
-
- const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
- const GLenum RENDERBUFFER_BINDING = 0x8CA7;
- const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
-
- const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
-
- /* WebGL-specific enums */
- const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
- const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
- const GLenum CONTEXT_LOST_WEBGL = 0x9242;
- const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
- const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
-
- readonly attribute GLsizei drawingBufferWidth;
- readonly attribute GLsizei drawingBufferHeight;
-
- [StrictTypeChecking] void activeTexture(GLenum texture);
- [StrictTypeChecking] void attachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking] void bindAttribLocation(WebGLProgram program, GLuint index, DOMString name);
- [StrictTypeChecking] void bindBuffer(GLenum target, WebGLBuffer buffer);
- [StrictTypeChecking] void bindFramebuffer(GLenum target, WebGLFramebuffer framebuffer);
- [StrictTypeChecking] void bindRenderbuffer(GLenum target, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void bindTexture(GLenum target, WebGLTexture texture);
- [StrictTypeChecking] void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void blendEquation(GLenum mode);
- [StrictTypeChecking] void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
- [StrictTypeChecking] void blendFunc(GLenum sfactor, GLenum dfactor);
- [StrictTypeChecking] void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
- [StrictTypeChecking] void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
- [StrictTypeChecking] void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
- [StrictTypeChecking] void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
- [StrictTypeChecking] void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
- [StrictTypeChecking] void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
-
- [StrictTypeChecking] GLenum checkFramebufferStatus(GLenum target);
- [StrictTypeChecking] void clear(GLbitfield mask);
- [StrictTypeChecking] void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void clearDepth(GLclampf depth);
- [StrictTypeChecking] void clearStencil(GLint s);
- [StrictTypeChecking] void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
- [StrictTypeChecking] void compileShader(WebGLShader shader);
-
- [StrictTypeChecking] void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
- [StrictTypeChecking] void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, ArrayBufferView data);
-
- [StrictTypeChecking] void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
- [StrictTypeChecking] void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-
- [StrictTypeChecking] WebGLBuffer createBuffer();
- [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
- [StrictTypeChecking] WebGLProgram createProgram();
- [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
- [StrictTypeChecking] WebGLShader createShader(GLenum type);
- [StrictTypeChecking] WebGLTexture createTexture();
-
- [StrictTypeChecking] void cullFace(GLenum mode);
-
- [StrictTypeChecking] void deleteBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] void deleteFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] void deleteProgram(WebGLProgram program);
- [StrictTypeChecking] void deleteRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void deleteShader(WebGLShader shader);
- [StrictTypeChecking] void deleteTexture(WebGLTexture texture);
-
- [StrictTypeChecking] void depthFunc(GLenum func);
- [StrictTypeChecking] void depthMask(GLboolean flag);
- [StrictTypeChecking] void depthRange(GLclampf zNear, GLclampf zFar);
- [StrictTypeChecking] void detachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking] void disable(GLenum cap);
- [StrictTypeChecking] void disableVertexAttribArray(GLuint index);
- [StrictTypeChecking] void drawArrays(GLenum mode, GLint first, GLsizei count);
- [StrictTypeChecking] void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
-
- [StrictTypeChecking] void enable(GLenum cap);
- [StrictTypeChecking] void enableVertexAttribArray(GLuint index);
- [StrictTypeChecking] void finish();
- [StrictTypeChecking] void flush();
- [StrictTypeChecking] void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture texture, GLint level);
- [StrictTypeChecking] void frontFace(GLenum mode);
- [StrictTypeChecking] void generateMipmap(GLenum target);
-
- [StrictTypeChecking] WebGLActiveInfo getActiveAttrib(WebGLProgram program, GLuint index);
- [StrictTypeChecking] WebGLActiveInfo getActiveUniform(WebGLProgram program, GLuint index);
-
- [StrictTypeChecking, Custom] void getAttachedShaders(WebGLProgram program);
-
- [StrictTypeChecking] GLint getAttribLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom] any getBufferParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
-
- [StrictTypeChecking] GLenum getError();
-
- // object getExtension(DOMString name);
- [StrictTypeChecking, Custom] any getExtension(DOMString name);
-
- [StrictTypeChecking, Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
- [StrictTypeChecking, Custom] any getParameter(GLenum pname);
- [StrictTypeChecking, Custom] any getProgramParameter(WebGLProgram program, GLenum pname);
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getProgramInfoLog(WebGLProgram program);
- [StrictTypeChecking, Custom] any getRenderbufferParameter(GLenum target, GLenum pname);
- [StrictTypeChecking, Custom] any getShaderParameter(WebGLShader shader, GLenum pname);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getShaderInfoLog(WebGLShader shader);
-
- [StrictTypeChecking] WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getShaderSource(WebGLShader shader);
-
- [StrictTypeChecking, Custom] sequence<DOMString> getSupportedExtensions();
-
- [StrictTypeChecking, Custom] any getTexParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking, Custom] any getUniform(WebGLProgram program, WebGLUniformLocation location);
-
- [StrictTypeChecking] WebGLUniformLocation getUniformLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom] any getVertexAttrib(GLuint index, GLenum pname);
-
- [StrictTypeChecking] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
-
- [StrictTypeChecking] void hint(GLenum target, GLenum mode);
- [StrictTypeChecking] GLboolean isBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] GLboolean isContextLost();
- [StrictTypeChecking] GLboolean isEnabled(GLenum cap);
- [StrictTypeChecking] GLboolean isFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] GLboolean isProgram(WebGLProgram program);
- [StrictTypeChecking] GLboolean isRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] GLboolean isShader(WebGLShader shader);
- [StrictTypeChecking] GLboolean isTexture(WebGLTexture texture);
- [StrictTypeChecking] void lineWidth(GLfloat width);
- [StrictTypeChecking] void linkProgram(WebGLProgram program);
- [StrictTypeChecking] void pixelStorei(GLenum pname, GLint param);
- [StrictTypeChecking] void polygonOffset(GLfloat factor, GLfloat units);
-
- [StrictTypeChecking] void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels);
-
- [StrictTypeChecking] void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
- [StrictTypeChecking] void sampleCoverage(GLclampf value, GLboolean invert);
- [StrictTypeChecking] void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
- [StrictTypeChecking] void shaderSource(WebGLShader shader, DOMString string);
- [StrictTypeChecking] void stencilFunc(GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilMask(GLuint mask);
- [StrictTypeChecking] void stencilMaskSeparate(GLenum face, GLuint mask);
- [StrictTypeChecking] void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
- [StrictTypeChecking] void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-
- [StrictTypeChecking] void texParameterf(GLenum target, GLenum pname, GLfloat param);
- [StrictTypeChecking] void texParameteri(GLenum target, GLenum pname, GLint param);
-
- // Supported forms:
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLVideoElement? video);
-
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLVideoElement? video);
-
- [StrictTypeChecking] void uniform1f(WebGLUniformLocation location, GLfloat x);
- [StrictTypeChecking, Custom] void uniform1fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform1i(WebGLUniformLocation location, GLint x);
- [StrictTypeChecking, Custom] void uniform1iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking] void uniform2f(WebGLUniformLocation location, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom] void uniform2fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform2i(WebGLUniformLocation location, GLint x, GLint y);
- [StrictTypeChecking, Custom] void uniform2iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking] void uniform3f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom] void uniform3fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform3i(WebGLUniformLocation location, GLint x, GLint y, GLint z);
- [StrictTypeChecking, Custom] void uniform3iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking] void uniform4f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom] void uniform4fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform4i(WebGLUniformLocation location, GLint x, GLint y, GLint z, GLint w);
- [StrictTypeChecking, Custom] void uniform4iv(WebGLUniformLocation location, Int32Array v);
-
- [StrictTypeChecking, Custom] void uniformMatrix2fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom] void uniformMatrix3fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom] void uniformMatrix4fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
-
- [StrictTypeChecking] void useProgram(WebGLProgram program);
- [StrictTypeChecking] void validateProgram(WebGLProgram program);
-
- [StrictTypeChecking] void vertexAttrib1f(GLuint indx, GLfloat x);
- [StrictTypeChecking, Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
- GLsizei stride, GLintptr offset);
-
- [StrictTypeChecking] void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
-};
+ DoNotCheckConstants,
+ TypeChecking=Interface|Nullable,
+ WillBeGarbageCollected,
+] interface WebGLRenderingContext { };
+WebGLRenderingContext implements WebGLRenderingContextBase;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
new file mode 100644
index 00000000000..b587a6899c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
@@ -0,0 +1,5728 @@
+/*
+ * 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 "core/html/canvas/WebGLRenderingContextBase.h"
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/fetch/ImageResource.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLCanvasElement.h"
+#include "core/html/HTMLImageElement.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/html/ImageData.h"
+#include "core/html/canvas/ANGLEInstancedArrays.h"
+#include "core/html/canvas/EXTBlendMinMax.h"
+#include "core/html/canvas/EXTFragDepth.h"
+#include "core/html/canvas/EXTShaderTextureLOD.h"
+#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
+#include "core/html/canvas/OESElementIndexUint.h"
+#include "core/html/canvas/OESStandardDerivatives.h"
+#include "core/html/canvas/OESTextureFloat.h"
+#include "core/html/canvas/OESTextureFloatLinear.h"
+#include "core/html/canvas/OESTextureHalfFloat.h"
+#include "core/html/canvas/OESTextureHalfFloatLinear.h"
+#include "core/html/canvas/OESVertexArrayObject.h"
+#include "core/html/canvas/WebGLActiveInfo.h"
+#include "core/html/canvas/WebGLBuffer.h"
+#include "core/html/canvas/WebGLCompressedTextureATC.h"
+#include "core/html/canvas/WebGLCompressedTextureETC1.h"
+#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
+#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
+#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/html/canvas/WebGLContextEvent.h"
+#include "core/html/canvas/WebGLContextGroup.h"
+#include "core/html/canvas/WebGLDebugRendererInfo.h"
+#include "core/html/canvas/WebGLDebugShaders.h"
+#include "core/html/canvas/WebGLDepthTexture.h"
+#include "core/html/canvas/WebGLDrawBuffers.h"
+#include "core/html/canvas/WebGLFramebuffer.h"
+#include "core/html/canvas/WebGLLoseContext.h"
+#include "core/html/canvas/WebGLProgram.h"
+#include "core/html/canvas/WebGLRenderbuffer.h"
+#include "core/html/canvas/WebGLShader.h"
+#include "core/html/canvas/WebGLShaderPrecisionFormat.h"
+#include "core/html/canvas/WebGLTexture.h"
+#include "core/html/canvas/WebGLUniformLocation.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/rendering/RenderBox.h"
+#include "platform/CheckedInt.h"
+#include "platform/NotImplemented.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/UnacceleratedImageBufferSurface.h"
+#include "platform/graphics/gpu/DrawingBuffer.h"
+#include "public/platform/Platform.h"
+
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Uint32Array.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+const double secondsBetweenRestoreAttempts = 1.0;
+const int maxGLErrorsAllowedToConsole = 256;
+const unsigned maxGLActiveContexts = 16;
+
+Vector<WebGLRenderingContextBase*>& WebGLRenderingContextBase::activeContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContextBase*>, activeContexts, ());
+ return activeContexts;
+}
+
+Vector<WebGLRenderingContextBase*>& WebGLRenderingContextBase::forciblyEvictedContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContextBase*>, forciblyEvictedContexts, ());
+ return forciblyEvictedContexts;
+}
+
+void WebGLRenderingContextBase::forciblyLoseOldestContext(const String& reason)
+{
+ size_t candidateID = oldestContextIndex();
+ if (candidateID >= activeContexts().size())
+ return;
+
+ WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
+
+ activeContexts().remove(candidateID);
+
+ candidate->printWarningToConsole(reason);
+ InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
+
+ // This will call deactivateContext once the context has actually been lost.
+ candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
+}
+
+size_t WebGLRenderingContextBase::oldestContextIndex()
+{
+ if (!activeContexts().size())
+ return maxGLActiveContexts;
+
+ WebGLRenderingContextBase* candidate = activeContexts().first();
+ blink::WebGraphicsContext3D* candidateWGC3D = candidate->isContextLost() ? 0 : candidate->webContext();
+ size_t candidateID = 0;
+ for (size_t ii = 1; ii < activeContexts().size(); ++ii) {
+ WebGLRenderingContextBase* context = activeContexts()[ii];
+ blink::WebGraphicsContext3D* contextWGC3D = context->isContextLost() ? 0 : context->webContext();
+ if (contextWGC3D && candidateWGC3D && contextWGC3D->lastFlushID() < candidateWGC3D->lastFlushID()) {
+ candidate = context;
+ candidateID = ii;
+ }
+ }
+
+ return candidateID;
+}
+
+IntSize WebGLRenderingContextBase::oldestContextSize()
+{
+ IntSize size;
+
+ size_t candidateID = oldestContextIndex();
+ if (candidateID < activeContexts().size()) {
+ WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
+ size.setWidth(candidate->drawingBufferWidth());
+ size.setHeight(candidate->drawingBufferHeight());
+ }
+
+ return size;
+}
+
+void WebGLRenderingContextBase::activateContext(WebGLRenderingContextBase* context)
+{
+ unsigned removedContexts = 0;
+ while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) {
+ forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost.");
+ removedContexts++;
+ }
+
+ if (!activeContexts().contains(context))
+ activeContexts().append(context);
+}
+
+void WebGLRenderingContextBase::deactivateContext(WebGLRenderingContextBase* context, bool addToEvictedList)
+{
+ size_t position = activeContexts().find(context);
+ if (position != WTF::kNotFound)
+ activeContexts().remove(position);
+
+ if (addToEvictedList && !forciblyEvictedContexts().contains(context))
+ forciblyEvictedContexts().append(context);
+}
+
+void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* context)
+{
+ size_t position = forciblyEvictedContexts().find(context);
+ if (position != WTF::kNotFound)
+ forciblyEvictedContexts().remove(position);
+
+ deactivateContext(context, false);
+
+ // Try to re-enable the oldest inactive contexts.
+ while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) {
+ WebGLRenderingContextBase* evictedContext = forciblyEvictedContexts().first();
+ if (!evictedContext->m_restoreAllowed) {
+ forciblyEvictedContexts().remove(0);
+ continue;
+ }
+
+ IntSize desiredSize = DrawingBuffer::adjustSize(evictedContext->clampedCanvasSize(), IntSize(), evictedContext->m_maxTextureSize);
+
+ // If there's room in the pixel budget for this context, restore it.
+ if (!desiredSize.isEmpty()) {
+ forciblyEvictedContexts().remove(0);
+ evictedContext->forceRestoreContext();
+ activeContexts().append(evictedContext);
+ }
+ break;
+ }
+}
+
+class WebGLRenderingContextEvictionManager : public ContextEvictionManager {
+public:
+ void forciblyLoseOldestContext(const String& reason) {
+ WebGLRenderingContextBase::forciblyLoseOldestContext(reason);
+ };
+ IntSize oldestContextSize() {
+ return WebGLRenderingContextBase::oldestContextSize();
+ };
+};
+
+namespace {
+
+ class ScopedDrawingBufferBinder {
+ public:
+ ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
+ : m_drawingBuffer(drawingBuffer)
+ , m_framebufferBinding(framebufferBinding)
+ {
+ // Commit DrawingBuffer if needed (e.g., for multisampling)
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->commit();
+ }
+
+ ~ScopedDrawingBufferBinder()
+ {
+ // Restore DrawingBuffer if needed
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->bind();
+ }
+
+ private:
+ DrawingBuffer* m_drawingBuffer;
+ WebGLFramebuffer* m_framebufferBinding;
+ };
+
+ Platform3DObject objectOrZero(WebGLObject* object)
+ {
+ return object ? object->object() : 0;
+ }
+
+ GLint clamp(GLint value, GLint min, GLint max)
+ {
+ if (value < min)
+ value = min;
+ if (value > max)
+ value = max;
+ return value;
+ }
+
+ // Return true if a character belongs to the ASCII subset as defined in
+ // GLSL ES 1.0 spec section 3.1.
+ bool validateCharacter(unsigned char c)
+ {
+ // Printing characters are valid except " $ ` @ \ ' DEL.
+ if (c >= 32 && c <= 126
+ && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
+ return true;
+ // Horizontal tab, line feed, vertical tab, form feed, carriage return
+ // are also valid.
+ if (c >= 9 && c <= 13)
+ return true;
+ return false;
+ }
+
+ bool isPrefixReserved(const String& name)
+ {
+ if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
+ return true;
+ return false;
+ }
+
+ // Strips comments from shader text. This allows non-ASCII characters
+ // to be used in comments without potentially breaking OpenGL
+ // implementations not expecting characters outside the GLSL ES set.
+ class StripComments {
+ public:
+ StripComments(const String& str)
+ : m_parseState(BeginningOfLine)
+ , m_sourceString(str)
+ , m_length(str.length())
+ , m_position(0)
+ {
+ parse();
+ }
+
+ String result()
+ {
+ return m_builder.toString();
+ }
+
+ private:
+ bool hasMoreCharacters() const
+ {
+ return (m_position < m_length);
+ }
+
+ void parse()
+ {
+ while (hasMoreCharacters()) {
+ process(current());
+ // process() might advance the position.
+ if (hasMoreCharacters())
+ advance();
+ }
+ }
+
+ void process(UChar);
+
+ bool peek(UChar& character) const
+ {
+ if (m_position + 1 >= m_length)
+ return false;
+ character = m_sourceString[m_position + 1];
+ return true;
+ }
+
+ UChar current()
+ {
+ ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
+ return m_sourceString[m_position];
+ }
+
+ void advance()
+ {
+ ++m_position;
+ }
+
+ static bool isNewline(UChar character)
+ {
+ // Don't attempt to canonicalize newline related characters.
+ return (character == '\n' || character == '\r');
+ }
+
+ void emit(UChar character)
+ {
+ m_builder.append(character);
+ }
+
+ enum ParseState {
+ // Have not seen an ASCII non-whitespace character yet on
+ // this line. Possible that we might see a preprocessor
+ // directive.
+ BeginningOfLine,
+
+ // Have seen at least one ASCII non-whitespace character
+ // on this line.
+ MiddleOfLine,
+
+ // Handling a preprocessor directive. Passes through all
+ // characters up to the end of the line. Disables comment
+ // processing.
+ InPreprocessorDirective,
+
+ // Handling a single-line comment. The comment text is
+ // replaced with a single space.
+ InSingleLineComment,
+
+ // Handling a multi-line comment. Newlines are passed
+ // through to preserve line numbers.
+ InMultiLineComment
+ };
+
+ ParseState m_parseState;
+ String m_sourceString;
+ unsigned m_length;
+ unsigned m_position;
+ StringBuilder m_builder;
+ };
+
+ void StripComments::process(UChar c)
+ {
+ if (isNewline(c)) {
+ // No matter what state we are in, pass through newlines
+ // so we preserve line numbers.
+ emit(c);
+
+ if (m_parseState != InMultiLineComment)
+ m_parseState = BeginningOfLine;
+
+ return;
+ }
+
+ UChar temp = 0;
+ switch (m_parseState) {
+ case BeginningOfLine:
+ if (WTF::isASCIISpace(c)) {
+ emit(c);
+ break;
+ }
+
+ if (c == '#') {
+ m_parseState = InPreprocessorDirective;
+ emit(c);
+ break;
+ }
+
+ // Transition to normal state and re-handle character.
+ m_parseState = MiddleOfLine;
+ process(c);
+ break;
+
+ case MiddleOfLine:
+ if (c == '/' && peek(temp)) {
+ if (temp == '/') {
+ m_parseState = InSingleLineComment;
+ emit(' ');
+ advance();
+ break;
+ }
+
+ if (temp == '*') {
+ m_parseState = InMultiLineComment;
+ // Emit the comment start in case the user has
+ // an unclosed comment and we want to later
+ // signal an error.
+ emit('/');
+ emit('*');
+ advance();
+ break;
+ }
+ }
+
+ emit(c);
+ break;
+
+ case InPreprocessorDirective:
+ // No matter what the character is, just pass it
+ // through. Do not parse comments in this state. This
+ // might not be the right thing to do long term, but it
+ // should handle the #error preprocessor directive.
+ emit(c);
+ break;
+
+ case InSingleLineComment:
+ // The newline code at the top of this function takes care
+ // of resetting our state when we get out of the
+ // single-line comment. Swallow all other characters.
+ break;
+
+ case InMultiLineComment:
+ if (c == '*' && peek(temp) && temp == '/') {
+ emit('*');
+ emit('/');
+ m_parseState = MiddleOfLine;
+ advance();
+ break;
+ }
+
+ // Swallow all other characters. Unclear whether we may
+ // want or need to just emit a space per character to try
+ // to preserve column numbers for debugging purposes.
+ break;
+ }
+ }
+} // namespace anonymous
+
+class ScopedTexture2DRestorer {
+public:
+ ScopedTexture2DRestorer(WebGLRenderingContextBase* context)
+ : m_context(context)
+ {
+ }
+
+ ~ScopedTexture2DRestorer()
+ {
+ m_context->restoreCurrentTexture2D();
+ }
+
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+class WebGLRenderingContextLostCallback : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextLostCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+ virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContextBase::RealLostContext); }
+ virtual ~WebGLRenderingContextLostCallback() {}
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+class WebGLRenderingContextErrorMessageCallback : public blink::WebGraphicsContext3D::WebGraphicsErrorMessageCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+ virtual void onErrorMessage(const blink::WebString& message, blink::WGC3Dint)
+ {
+ if (m_context->m_synthesizedErrorsToConsole)
+ m_context->printGLErrorToConsole(message);
+ InspectorInstrumentation::didFireWebGLErrorOrWarning(m_context->canvas(), message);
+ }
+ virtual ~WebGLRenderingContextErrorMessageCallback() { }
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes)
+ : CanvasRenderingContext(passedCanvas)
+ , ActiveDOMObject(&passedCanvas->document())
+ , m_drawingBuffer(nullptr)
+ , m_dispatchContextLostEventTimer(this, &WebGLRenderingContextBase::dispatchContextLostEvent)
+ , m_restoreAllowed(false)
+ , m_restoreTimer(this, &WebGLRenderingContextBase::maybeRestoreContext)
+ , m_generatedImageCache(4)
+ , m_contextLost(false)
+ , m_contextLostMode(SyntheticLostContext)
+ , m_requestedAttributes(requestedAttributes->clone())
+ , m_synthesizedErrorsToConsole(true)
+ , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
+ , m_multisamplingAllowed(false)
+ , m_multisamplingObserverRegistered(false)
+ , m_onePlusMaxEnabledAttribIndex(0)
+ , m_onePlusMaxNonDefaultTextureUnit(0)
+ , m_savingImage(false)
+{
+ ASSERT(context);
+
+ m_contextGroup = WebGLContextGroup::create();
+ m_contextGroup->addContext(this);
+
+ m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
+ context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims);
+
+ m_drawingBuffer = createDrawingBuffer(context);
+ if (!m_drawingBuffer)
+ return;
+
+ m_drawingBuffer->bind();
+ setupFlags();
+ initializeNewContext();
+}
+
+PassRefPtr<DrawingBuffer> WebGLRenderingContextBase::createDrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context)
+{
+ RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
+
+ blink::WebGraphicsContext3D::Attributes attrs;
+ attrs.alpha = m_requestedAttributes->alpha();
+ attrs.depth = m_requestedAttributes->depth();
+ attrs.stencil = m_requestedAttributes->stencil();
+ attrs.antialias = m_requestedAttributes->antialias();
+ attrs.premultipliedAlpha = m_requestedAttributes->premultipliedAlpha();
+ DrawingBuffer::PreserveDrawingBuffer preserve = m_requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
+ return DrawingBuffer::create(context, clampedCanvasSize(), preserve, attrs, contextEvictionManager.release());
+}
+
+void WebGLRenderingContextBase::initializeNewContext()
+{
+ ASSERT(!isContextLost());
+ m_needsUpdate = true;
+ m_markedCanvasDirty = false;
+ m_activeTextureUnit = 0;
+ m_packAlignment = 4;
+ m_unpackAlignment = 4;
+ m_unpackFlipY = false;
+ m_unpackPremultiplyAlpha = false;
+ m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
+ m_boundArrayBuffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+ m_depthMask = true;
+ m_stencilEnabled = false;
+ m_stencilMask = 0xFFFFFFFF;
+ m_stencilMaskBack = 0xFFFFFFFF;
+ m_stencilFuncRef = 0;
+ m_stencilFuncRefBack = 0;
+ m_stencilFuncMask = 0xFFFFFFFF;
+ m_stencilFuncMaskBack = 0xFFFFFFFF;
+ m_layerCleared = false;
+ m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
+
+ m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
+ m_scissorEnabled = false;
+ m_clearDepth = 1;
+ m_clearStencil = 0;
+ m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
+
+ GLint numCombinedTextureImageUnits = 0;
+ webContext()->getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+ m_textureUnits.clear();
+ m_textureUnits.resize(numCombinedTextureImageUnits);
+
+ GLint numVertexAttribs = 0;
+ webContext()->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
+ m_maxVertexAttribs = numVertexAttribs;
+
+ m_maxTextureSize = 0;
+ webContext()->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+ m_maxCubeMapTextureSize = 0;
+ webContext()->getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+ m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
+ m_maxRenderbufferSize = 0;
+ webContext()->getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
+
+ // These two values from EXT_draw_buffers are lazily queried.
+ m_maxDrawBuffers = 0;
+ m_maxColorAttachments = 0;
+
+ m_backDrawBuffer = GL_BACK;
+
+ m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
+ addContextObject(m_defaultVertexArrayObject.get());
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+
+ m_vertexAttribValue.resize(m_maxVertexAttribs);
+
+ createFallbackBlackTextures1x1();
+
+ webContext()->viewport(0, 0, drawingBufferWidth(), drawingBufferHeight());
+ webContext()->scissor(0, 0, drawingBufferWidth(), drawingBufferHeight());
+
+ m_contextLostCallbackAdapter = adoptPtr(new WebGLRenderingContextLostCallback(this));
+ m_errorMessageCallbackAdapter = adoptPtr(new WebGLRenderingContextErrorMessageCallback(this));
+
+ webContext()->setContextLostCallback(m_contextLostCallbackAdapter.get());
+ webContext()->setErrorMessageCallback(m_errorMessageCallbackAdapter.get());
+
+ // This ensures that the context has a valid "lastFlushID" and won't be mistakenly identified as the "least recently used" context.
+ webContext()->flush();
+
+ for (int i = 0; i < WebGLExtensionNameCount; ++i)
+ m_extensionEnabled[i] = false;
+
+ activateContext(this);
+}
+
+void WebGLRenderingContextBase::setupFlags()
+{
+ ASSERT(m_drawingBuffer);
+ if (Page* p = canvas()->document().page()) {
+ m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled();
+
+ if (!m_multisamplingObserverRegistered && m_requestedAttributes->antialias()) {
+ m_multisamplingAllowed = m_drawingBuffer->multisample();
+ p->addMultisamplingChangedObserver(this);
+ m_multisamplingObserverRegistered = true;
+ }
+ }
+
+ m_isGLES2NPOTStrict = !extensionsUtil()->isExtensionEnabled("GL_OES_texture_npot");
+ m_isDepthStencilSupported = extensionsUtil()->isExtensionEnabled("GL_OES_packed_depth_stencil");
+}
+
+void WebGLRenderingContextBase::addCompressedTextureFormat(GLenum format)
+{
+ if (!m_compressedTextureFormats.contains(format))
+ m_compressedTextureFormats.append(format);
+}
+
+void WebGLRenderingContextBase::removeAllCompressedTextureFormats()
+{
+ m_compressedTextureFormats.clear();
+}
+
+// Helper function for V8 bindings to identify what version of WebGL a CanvasRenderingContext supports.
+unsigned WebGLRenderingContextBase::getWebGLVersion(const CanvasRenderingContext* context)
+{
+ if (!context->is3d())
+ return 0;
+ return static_cast<const WebGLRenderingContextBase*>(context)->version();
+}
+
+WebGLRenderingContextBase::~WebGLRenderingContextBase()
+{
+ // Remove all references to WebGLObjects so if they are the last reference
+ // they will be freed before the last context is removed from the context group.
+ m_boundArrayBuffer = nullptr;
+ m_defaultVertexArrayObject = nullptr;
+ m_boundVertexArrayObject = nullptr;
+ m_vertexAttrib0Buffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+
+ for (size_t i = 0; i < m_textureUnits.size(); ++i) {
+ m_textureUnits[i].m_texture2DBinding = nullptr;
+ m_textureUnits[i].m_textureCubeMapBinding = nullptr;
+ }
+
+ m_blackTexture2D = nullptr;
+ m_blackTextureCubeMap = nullptr;
+
+ detachAndRemoveAllObjects();
+
+ // release all extensions
+ for (size_t i = 0; i < m_extensions.size(); ++i)
+ delete m_extensions[i];
+
+ // Context must be removed from the group prior to the destruction of the
+ // WebGraphicsContext3D, otherwise shared objects may not be properly deleted.
+ m_contextGroup->removeContext(this);
+
+ destroyContext();
+
+#if !ENABLE(OILPAN)
+ if (m_multisamplingObserverRegistered) {
+ Page* page = canvas()->document().page();
+ if (page)
+ page->removeMultisamplingChangedObserver(this);
+ }
+#endif
+
+ willDestroyContext(this);
+}
+
+void WebGLRenderingContextBase::destroyContext()
+{
+ m_contextLost = true;
+
+ if (!m_drawingBuffer)
+ return;
+
+ m_extensionsUtil.clear();
+
+ webContext()->setContextLostCallback(0);
+ webContext()->setErrorMessageCallback(0);
+
+ ASSERT(m_drawingBuffer);
+ m_drawingBuffer->beginDestruction();
+ m_drawingBuffer.clear();
+}
+
+void WebGLRenderingContextBase::markContextChanged(ContentChangeType changeType)
+{
+ if (m_framebufferBinding || isContextLost())
+ return;
+
+ m_drawingBuffer->markContentsChanged();
+
+ m_layerCleared = false;
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing()) {
+ m_markedCanvasDirty = true;
+ canvas()->clearCopiedImage();
+ renderBox->contentChanged(changeType);
+ } else {
+ if (!m_markedCanvasDirty) {
+ m_markedCanvasDirty = true;
+ canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+ }
+ }
+}
+
+bool WebGLRenderingContextBase::clearIfComposited(GLbitfield mask)
+{
+ if (isContextLost())
+ return false;
+
+ if (!m_drawingBuffer->layerComposited() || m_layerCleared
+ || m_requestedAttributes->preserveDrawingBuffer() || (mask && m_framebufferBinding))
+ return false;
+
+ RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
+
+ // Determine if it's possible to combine the clear the user asked for and this clear.
+ bool combinedClear = mask && !m_scissorEnabled;
+
+ webContext()->disable(GL_SCISSOR_TEST);
+ if (combinedClear && (mask & GL_COLOR_BUFFER_BIT)) {
+ webContext()->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
+ m_colorMask[1] ? m_clearColor[1] : 0,
+ m_colorMask[2] ? m_clearColor[2] : 0,
+ m_colorMask[3] ? m_clearColor[3] : 0);
+ } else {
+ webContext()->clearColor(0, 0, 0, 0);
+ }
+ webContext()->colorMask(true, true, true, true);
+ GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
+ if (contextAttributes->depth()) {
+ if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT))
+ webContext()->clearDepth(1.0f);
+ clearMask |= GL_DEPTH_BUFFER_BIT;
+ webContext()->depthMask(true);
+ }
+ if (contextAttributes->stencil()) {
+ if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
+ webContext()->clearStencil(m_clearStencil & m_stencilMask);
+ else
+ webContext()->clearStencil(0);
+ clearMask |= GL_STENCIL_BUFFER_BIT;
+ webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
+ }
+
+ m_drawingBuffer->clearFramebuffers(clearMask);
+
+ restoreStateAfterClear();
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ m_layerCleared = true;
+
+ return combinedClear;
+}
+
+void WebGLRenderingContextBase::restoreStateAfterClear()
+{
+ if (isContextLost())
+ return;
+
+ // Restore the state that the context set.
+ if (m_scissorEnabled)
+ webContext()->enable(GL_SCISSOR_TEST);
+ webContext()->clearColor(m_clearColor[0], m_clearColor[1],
+ m_clearColor[2], m_clearColor[3]);
+ webContext()->colorMask(m_colorMask[0], m_colorMask[1],
+ m_colorMask[2], m_colorMask[3]);
+ webContext()->clearDepth(m_clearDepth);
+ webContext()->clearStencil(m_clearStencil);
+ webContext()->stencilMaskSeparate(GL_FRONT, m_stencilMask);
+ webContext()->depthMask(m_depthMask);
+}
+
+void WebGLRenderingContextBase::markLayerComposited()
+{
+ if (!isContextLost())
+ m_drawingBuffer->markLayerComposited();
+}
+
+void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
+{
+ if (isContextLost()) {
+ canvas()->clearPresentationCopy();
+ return;
+ }
+
+ if (canvas()->document().printing())
+ canvas()->clearPresentationCopy();
+
+ // Until the canvas is written to by the application, the clear that
+ // happened after it was composited should be ignored by the compositor.
+ if (m_drawingBuffer->layerComposited() && !m_requestedAttributes->preserveDrawingBuffer()) {
+ m_drawingBuffer->paintCompositedResultsToCanvas(canvas()->buffer());
+
+ canvas()->makePresentationCopy();
+ } else
+ canvas()->clearPresentationCopy();
+
+ clearIfComposited();
+
+ if (!m_markedCanvasDirty && !m_layerCleared)
+ return;
+
+ canvas()->clearCopiedImage();
+ m_markedCanvasDirty = false;
+
+ ScopedTexture2DRestorer restorer(this);
+
+ m_drawingBuffer->commit();
+ if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get(), m_savingImage)) {
+ canvas()->ensureUnacceleratedImageBuffer();
+ if (canvas()->hasImageBuffer())
+ m_drawingBuffer->paintRenderingResultsToCanvas(canvas()->buffer());
+ }
+
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ else
+ m_drawingBuffer->bind();
+}
+
+PassRefPtrWillBeRawPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
+{
+ if (isContextLost())
+ return nullptr;
+
+ clearIfComposited();
+ m_drawingBuffer->commit();
+ int width, height;
+ RefPtr<Uint8ClampedArray> imageDataPixels = m_drawingBuffer->paintRenderingResultsToImageData(width, height);
+ if (!imageDataPixels)
+ return nullptr;
+
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ else
+ m_drawingBuffer->bind();
+
+ return ImageData::create(IntSize(width, height), imageDataPixels);
+}
+
+void WebGLRenderingContextBase::reshape(int width, int height)
+{
+ if (isContextLost())
+ return;
+
+ // This is an approximation because at WebGLRenderingContextBase level we don't
+ // know if the underlying FBO uses textures or renderbuffers.
+ GLint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
+ // Limit drawing buffer size to 4k to avoid memory exhaustion.
+ const int sizeUpperLimit = 4096;
+ maxSize = std::min(maxSize, sizeUpperLimit);
+ GLint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
+ GLint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
+ width = clamp(width, 1, maxWidth);
+ height = clamp(height, 1, maxHeight);
+
+ if (m_needsUpdate) {
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing())
+ renderBox->contentChanged(CanvasChanged);
+ m_needsUpdate = false;
+ }
+
+ // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
+ // clear (and this matches what reshape will do).
+ m_drawingBuffer->reset(IntSize(width, height));
+ restoreStateAfterClear();
+
+ webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()));
+ webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+}
+
+int WebGLRenderingContextBase::drawingBufferWidth() const
+{
+ return isContextLost() ? 0 : m_drawingBuffer->size().width();
+}
+
+int WebGLRenderingContextBase::drawingBufferHeight() const
+{
+ return isContextLost() ? 0 : m_drawingBuffer->size().height();
+}
+
+unsigned WebGLRenderingContextBase::sizeInBytes(GLenum type)
+{
+ switch (type) {
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void WebGLRenderingContextBase::activeTexture(GLenum texture)
+{
+ if (isContextLost())
+ return;
+ if (texture - GL_TEXTURE0 >= m_textureUnits.size()) {
+ synthesizeGLError(GL_INVALID_ENUM, "activeTexture", "texture unit out of range");
+ return;
+ }
+ m_activeTextureUnit = texture - GL_TEXTURE0;
+ webContext()->activeTexture(texture);
+
+ m_drawingBuffer->setActiveTextureUnit(texture);
+
+}
+
+void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader* shader)
+{
+ if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
+ return;
+ if (!program->attachShader(shader)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachment already has shader");
+ return;
+ }
+ webContext()->attachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onAttached();
+}
+
+void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
+ return;
+ if (!validateLocationLength("bindAttribLocation", name))
+ return;
+ if (!validateString("bindAttribLocation", name))
+ return;
+ if (isPrefixReserved(name)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "bindAttribLocation", "index out of range");
+ return;
+ }
+ webContext()->bindAttribLocation(objectOrZero(program), index, name.utf8().data());
+}
+
+bool WebGLRenderingContextBase::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
+{
+ deleted = false;
+ if (isContextLost())
+ return false;
+ if (object) {
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "object not from this context");
+ return false;
+ }
+ deleted = !object->object();
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::bindBuffer(GLenum target, WebGLBuffer* buffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+ synthesizeGLError(GL_INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
+ return;
+ }
+ if (target == GL_ARRAY_BUFFER)
+ m_boundArrayBuffer = buffer;
+ else if (target == GL_ELEMENT_ARRAY_BUFFER)
+ m_boundVertexArrayObject->setElementArrayBuffer(buffer);
+ else {
+ synthesizeGLError(GL_INVALID_ENUM, "bindBuffer", "invalid target");
+ return;
+ }
+
+ webContext()->bindBuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setTarget(target);
+}
+
+void WebGLRenderingContextBase::bindFramebuffer(GLenum target, WebGLFramebuffer* buffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (target != GL_FRAMEBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
+ return;
+ }
+ m_framebufferBinding = buffer;
+ m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
+ if (!m_framebufferBinding) {
+ // Instead of binding fb 0, bind the drawing buffer.
+ m_drawingBuffer->bind();
+ } else {
+ webContext()->bindFramebuffer(target, objectOrZero(buffer));
+ }
+ if (buffer)
+ buffer->setHasEverBeenBound();
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::bindRenderbuffer(GLenum target, WebGLRenderbuffer* renderBuffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
+ return;
+ if (deleted)
+ renderBuffer = 0;
+ if (target != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target");
+ return;
+ }
+ m_renderbufferBinding = renderBuffer;
+ webContext()->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ if (renderBuffer)
+ renderBuffer->setHasEverBeenBound();
+}
+
+void WebGLRenderingContextBase::bindTexture(GLenum target, WebGLTexture* texture)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindTexture", texture, deleted))
+ return;
+ if (deleted)
+ texture = 0;
+ if (texture && texture->getTarget() && texture->getTarget() != target) {
+ synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
+ return;
+ }
+ GLint maxLevel = 0;
+ if (target == GL_TEXTURE_2D) {
+ m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
+ maxLevel = m_maxTextureLevel;
+
+ if (!m_activeTextureUnit)
+ m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
+
+ } else if (target == GL_TEXTURE_CUBE_MAP) {
+ m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
+ synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
+ return;
+ }
+
+ webContext()->bindTexture(target, objectOrZero(texture));
+ if (texture) {
+ texture->setTarget(target, maxLevel);
+ m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
+ } else {
+ // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index
+ if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) {
+ findNewMaxNonDefaultTextureUnit();
+ }
+ }
+
+ // Note: previously we used to automatically set the TEXTURE_WRAP_R
+ // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
+ // ES 2.0 doesn't expose this flag (a bug in the specification) and
+ // otherwise the application has no control over the seams in this
+ // dimension. However, it appears that supporting this properly on all
+ // platforms is fairly involved (will require a HashMap from texture ID
+ // in all ports), and we have not had any complaints, so the logic has
+ // been removed.
+
+}
+
+void WebGLRenderingContextBase::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ if (isContextLost())
+ return;
+ webContext()->blendColor(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::blendEquation(GLenum mode)
+{
+ if (isContextLost() || !validateBlendEquation("blendEquation", mode))
+ return;
+ webContext()->blendEquation(mode);
+}
+
+void WebGLRenderingContextBase::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ if (isContextLost() || !validateBlendEquation("blendEquationSeparate", modeRGB) || !validateBlendEquation("blendEquationSeparate", modeAlpha))
+ return;
+ webContext()->blendEquationSeparate(modeRGB, modeAlpha);
+}
+
+
+void WebGLRenderingContextBase::blendFunc(GLenum sfactor, GLenum dfactor)
+{
+ if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
+ return;
+ webContext()->blendFunc(sfactor, dfactor);
+}
+
+void WebGLRenderingContextBase::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ // Note: Alpha does not have the same restrictions as RGB.
+ if (isContextLost() || !validateBlendFuncFactors("blendFuncSeparate", srcRGB, dstRGB))
+ return;
+ webContext()->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void WebGLRenderingContextBase::bufferDataImpl(GLenum target, long long size, const void* data, GLenum usage)
+{
+ WebGLBuffer* buffer = validateBufferDataTarget("bufferData", target);
+ if (!buffer)
+ return;
+
+ switch (usage) {
+ case GL_STREAM_DRAW:
+ case GL_STATIC_DRAW:
+ case GL_DYNAMIC_DRAW:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "bufferData", "invalid usage");
+ return;
+ }
+
+ if (!validateValueFitNonNegInt32("bufferData", "size", size))
+ return;
+
+ webContext()->bufferData(target, static_cast<GLsizeiptr>(size), data, usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, long long size, GLenum usage)
+{
+ if (isContextLost())
+ return;
+ if (!size) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0");
+ return;
+ }
+ bufferDataImpl(target, size, 0, usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, ArrayBuffer* data, GLenum usage)
+{
+ if (isContextLost())
+ return;
+ if (!data) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
+ return;
+ }
+ bufferDataImpl(target, data->byteLength(), data->data(), usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, ArrayBufferView* data, GLenum usage)
+{
+ if (isContextLost())
+ return;
+ if (!data) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
+ return;
+ }
+ bufferDataImpl(target, data->byteLength(), data->baseAddress(), usage);
+}
+
+void WebGLRenderingContextBase::bufferSubDataImpl(GLenum target, long long offset, GLsizeiptr size, const void* data)
+{
+ WebGLBuffer* buffer = validateBufferDataTarget("bufferSubData", target);
+ if (!buffer)
+ return;
+ if (!validateValueFitNonNegInt32("bufferSubData", "offset", offset))
+ return;
+ if (!data)
+ return;
+
+ webContext()->bufferSubData(target, static_cast<GLintptr>(offset), size, data);
+}
+
+void WebGLRenderingContextBase::bufferSubData(GLenum target, long long offset, ArrayBuffer* data)
+{
+ if (isContextLost())
+ return;
+ if (!data)
+ return;
+ bufferSubDataImpl(target, offset, data->byteLength(), data->data());
+}
+
+void WebGLRenderingContextBase::bufferSubData(GLenum target, long long offset, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!data)
+ return;
+ bufferSubDataImpl(target, offset, data->byteLength(), data->baseAddress());
+}
+
+GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target)
+{
+ if (isContextLost())
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ if (target != GL_FRAMEBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid target");
+ return 0;
+ }
+ if (!m_framebufferBinding || !m_framebufferBinding->object())
+ return GL_FRAMEBUFFER_COMPLETE;
+ const char* reason = "framebuffer incomplete";
+ GLenum result = m_framebufferBinding->checkStatus(&reason);
+ if (result != GL_FRAMEBUFFER_COMPLETE) {
+ emitGLWarning("checkFramebufferStatus", reason);
+ return result;
+ }
+ result = webContext()->checkFramebufferStatus(target);
+ return result;
+}
+
+void WebGLRenderingContextBase::clear(GLbitfield mask)
+{
+ if (isContextLost())
+ return;
+ if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+ return;
+ }
+ if (!clearIfComposited(mask))
+ webContext()->clear(mask);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::clearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+ if (isContextLost())
+ return;
+ if (std::isnan(r))
+ r = 0;
+ if (std::isnan(g))
+ g = 0;
+ if (std::isnan(b))
+ b = 0;
+ if (std::isnan(a))
+ a = 1;
+ m_clearColor[0] = r;
+ m_clearColor[1] = g;
+ m_clearColor[2] = b;
+ m_clearColor[3] = a;
+ webContext()->clearColor(r, g, b, a);
+}
+
+void WebGLRenderingContextBase::clearDepth(GLfloat depth)
+{
+ if (isContextLost())
+ return;
+ m_clearDepth = depth;
+ webContext()->clearDepth(depth);
+}
+
+void WebGLRenderingContextBase::clearStencil(GLint s)
+{
+ if (isContextLost())
+ return;
+ m_clearStencil = s;
+ webContext()->clearStencil(s);
+}
+
+void WebGLRenderingContextBase::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ if (isContextLost())
+ return;
+ m_colorMask[0] = red;
+ m_colorMask[1] = green;
+ m_colorMask[2] = blue;
+ m_colorMask[3] = alpha;
+ webContext()->colorMask(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::compileShader(WebGLShader* shader)
+{
+ if (isContextLost() || !validateWebGLObject("compileShader", shader))
+ return;
+ webContext()->compileShader(objectOrZero(shader));
+}
+
+void WebGLRenderingContextBase::compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("compressedTexImage2D", target, level))
+ return;
+
+ if (!validateCompressedTexFormat(internalformat)) {
+ synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
+ return;
+ }
+ if (border) {
+ synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
+ return;
+ }
+ if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
+ return;
+ if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isGLES2NPOTStrict()) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ }
+ webContext()->compressedTexImage2D(target, level, internalformat, width, height,
+ border, data->byteLength(), data->baseAddress());
+ tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContextBase::compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
+ return;
+ if (!validateCompressedTexFormat(format)) {
+ synthesizeGLError(GL_INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
+ return;
+ }
+ if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
+ if (!tex)
+ return;
+
+ if (format != tex->getInternalFormat(target, level)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
+ return;
+ }
+
+ if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
+ return;
+
+ webContext()->compressedTexSubImage2D(target, level, xoffset, yoffset,
+ width, height, format, data->byteLength(), data->baseAddress());
+}
+
+bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionName, GLenum format)
+{
+ if (WebGLImageConversion::getClearBitsByFormat(format) & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to");
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GL_UNSIGNED_BYTE))
+ return;
+ if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
+ synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ webContext()->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, GL_UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
+ if (!tex)
+ return;
+ if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
+ return;
+ // Before checking if it is in the range, check if overflow happens first.
+ Checked<GLint, RecordOverflow> maxX = xoffset;
+ maxX += width;
+ Checked<GLint, RecordOverflow> maxY = yoffset;
+ maxY += height;
+ if (maxX.hasOverflowed() || maxY.hasOverflowed()) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
+ return;
+ }
+ if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > tex->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
+ return;
+ }
+ GLenum internalformat = tex->getInternalFormat(target, level);
+ if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
+ synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+PassRefPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLRenderingContextBase::createFramebuffer()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
+ addContextObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLTexture> WebGLRenderingContextBase::createTexture()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLTexture> o = WebGLTexture::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLProgram> WebGLRenderingContextBase::createProgram()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLProgram> o = WebGLProgram::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderingContextBase::createRenderbuffer()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+WebGLRenderbuffer* WebGLRenderingContextBase::ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer* renderbuffer)
+{
+ if (isContextLost())
+ return 0;
+ if (!renderbuffer->emulatedStencilBuffer()) {
+ renderbuffer->setEmulatedStencilBuffer(createRenderbuffer());
+ webContext()->bindRenderbuffer(target, objectOrZero(renderbuffer->emulatedStencilBuffer()));
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+ }
+ return renderbuffer->emulatedStencilBuffer();
+}
+
+PassRefPtr<WebGLShader> WebGLRenderingContextBase::createShader(GLenum type)
+{
+ if (isContextLost())
+ return nullptr;
+ if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
+ synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
+ return nullptr;
+ }
+
+ RefPtr<WebGLShader> o = WebGLShader::create(this, type);
+ addSharedObject(o.get());
+ return o;
+}
+
+void WebGLRenderingContextBase::cullFace(GLenum mode)
+{
+ if (isContextLost())
+ return;
+ switch (mode) {
+ case GL_FRONT_AND_BACK:
+ case GL_FRONT:
+ case GL_BACK:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "cullFace", "invalid mode");
+ return;
+ }
+ webContext()->cullFace(mode);
+}
+
+bool WebGLRenderingContextBase::deleteObject(WebGLObject* object)
+{
+ if (isContextLost() || !object)
+ return false;
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "delete", "object does not belong to this context");
+ return false;
+ }
+ if (object->object()) {
+ // We need to pass in context here because we want
+ // things in this context unbound.
+ object->deleteObject(webContext());
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::deleteBuffer(WebGLBuffer* buffer)
+{
+ if (!deleteObject(buffer))
+ return;
+ if (m_boundArrayBuffer == buffer)
+ m_boundArrayBuffer = nullptr;
+
+ m_boundVertexArrayObject->unbindBuffer(buffer);
+}
+
+void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!deleteObject(framebuffer))
+ return;
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = nullptr;
+ m_drawingBuffer->setFramebufferBinding(0);
+ // Have to call bindFramebuffer here to bind back to internal fbo.
+ m_drawingBuffer->bind();
+ }
+}
+
+void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
+{
+ deleteObject(program);
+ // We don't reset m_currentProgram to 0 here because the deletion of the
+ // current program is delayed.
+}
+
+void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!deleteObject(renderbuffer))
+ return;
+ if (renderbuffer == m_renderbufferBinding)
+ m_renderbufferBinding = nullptr;
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
+}
+
+void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
+{
+ deleteObject(shader);
+}
+
+void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
+{
+ if (!deleteObject(texture))
+ return;
+
+ int maxBoundTextureIndex = -1;
+ for (size_t i = 0; i < m_onePlusMaxNonDefaultTextureUnit; ++i) {
+ if (texture == m_textureUnits[i].m_texture2DBinding) {
+ m_textureUnits[i].m_texture2DBinding = nullptr;
+ maxBoundTextureIndex = i;
+ if (!i)
+ m_drawingBuffer->setTexture2DBinding(0);
+ }
+ if (texture == m_textureUnits[i].m_textureCubeMapBinding) {
+ m_textureUnits[i].m_textureCubeMapBinding = nullptr;
+ maxBoundTextureIndex = i;
+ }
+ }
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
+
+ // If the deleted was bound to the the current maximum index, trace backwards to find the new max texture index
+ if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBoundTextureIndex + 1)) {
+ findNewMaxNonDefaultTextureUnit();
+ }
+}
+
+void WebGLRenderingContextBase::depthFunc(GLenum func)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilOrDepthFunc("depthFunc", func))
+ return;
+ webContext()->depthFunc(func);
+}
+
+void WebGLRenderingContextBase::depthMask(GLboolean flag)
+{
+ if (isContextLost())
+ return;
+ m_depthMask = flag;
+ webContext()->depthMask(flag);
+}
+
+void WebGLRenderingContextBase::depthRange(GLfloat zNear, GLfloat zFar)
+{
+ if (isContextLost())
+ return;
+ if (zNear > zFar) {
+ synthesizeGLError(GL_INVALID_OPERATION, "depthRange", "zNear > zFar");
+ return;
+ }
+ webContext()->depthRange(zNear, zFar);
+}
+
+void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader* shader)
+{
+ if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
+ return;
+ if (!program->detachShader(shader)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not attached");
+ return;
+ }
+ webContext()->detachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onDetached(webContext());
+}
+
+void WebGLRenderingContextBase::disable(GLenum cap)
+{
+ if (isContextLost() || !validateCapability("disable", cap))
+ return;
+ if (cap == GL_STENCIL_TEST) {
+ m_stencilEnabled = false;
+ applyStencilTest();
+ return;
+ }
+ if (cap == GL_SCISSOR_TEST) {
+ m_scissorEnabled = false;
+ m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+ }
+ webContext()->disable(cap);
+}
+
+void WebGLRenderingContextBase::disableVertexAttribArray(GLuint index)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "disableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = false;
+
+ // If the disabled index is the current maximum, trace backwards to find the new max enabled attrib index
+ if (m_onePlusMaxEnabledAttribIndex == index + 1) {
+ findNewMaxEnabledAttribIndex();
+ }
+
+ webContext()->disableVertexAttribArray(index);
+}
+
+bool WebGLRenderingContextBase::validateRenderingState(const char* functionName)
+{
+ if (!m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no valid shader program in use");
+ return false;
+ }
+
+ // Look in each enabled vertex attrib and check if they've been bound to a buffer.
+ for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+ if (state.enabled
+ && (!state.bufferBinding || !state.bufferBinding->object())) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, String::format("attribute %d is enabled but has no buffer bound", i).utf8().data());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateWebGLObject(const char* functionName, WebGLObject* object)
+{
+ if (!object || !object->object()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no object or object deleted");
+ return false;
+ }
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "object does not belong to this context");
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ if (!validateDrawArrays("drawArrays", mode, first, count))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawArrays", true);
+ webContext()->drawArrays(mode, first, count);
+ handleTextureCompleteness("drawArrays", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawElements(GLenum mode, GLsizei count, GLenum type, long long offset)
+{
+ if (!validateDrawElements("drawElements", mode, count, type, offset))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawElements", true);
+ webContext()->drawElements(mode, count, type, static_cast<GLintptr>(offset));
+ handleTextureCompleteness("drawElements", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+ if (!validateDrawArrays("drawArraysInstancedANGLE", mode, first, count))
+ return;
+
+ if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawArraysInstancedANGLE", true);
+ webContext()->drawArraysInstancedANGLE(mode, first, count, primcount);
+ handleTextureCompleteness("drawArraysInstancedANGLE", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount)
+{
+ if (!validateDrawElements("drawElementsInstancedANGLE", mode, count, type, offset))
+ return;
+
+ if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawElementsInstancedANGLE", true);
+ webContext()->drawElementsInstancedANGLE(mode, count, type, static_cast<GLintptr>(offset), primcount);
+ handleTextureCompleteness("drawElementsInstancedANGLE", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::enable(GLenum cap)
+{
+ if (isContextLost() || !validateCapability("enable", cap))
+ return;
+ if (cap == GL_STENCIL_TEST) {
+ m_stencilEnabled = true;
+ applyStencilTest();
+ return;
+ }
+ if (cap == GL_SCISSOR_TEST) {
+ m_scissorEnabled = true;
+ m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+ }
+ webContext()->enable(cap);
+}
+
+void WebGLRenderingContextBase::enableVertexAttribArray(GLuint index)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "enableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = true;
+
+ m_onePlusMaxEnabledAttribIndex = max(index + 1, m_onePlusMaxEnabledAttribIndex);
+
+ webContext()->enableVertexAttribArray(index);
+}
+
+void WebGLRenderingContextBase::finish()
+{
+ if (isContextLost())
+ return;
+ webContext()->flush(); // Intentionally a flush, not a finish.
+}
+
+void WebGLRenderingContextBase::flush()
+{
+ if (isContextLost())
+ return;
+ webContext()->flush();
+}
+
+void WebGLRenderingContextBase::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer* buffer)
+{
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
+ return;
+ if (renderbuffertarget != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
+ return;
+ }
+ if (buffer && !buffer->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ switch (attachment) {
+ case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+ if (isDepthStencilSupported() || !buffer) {
+ webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
+ } else {
+ WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(renderbuffertarget, buffer);
+ if (!emulatedStencilBuffer) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "out of memory");
+ return;
+ }
+ webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
+ }
+ break;
+ default:
+ webContext()->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level)
+{
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
+ return;
+ if (level) {
+ synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0");
+ return;
+ }
+ if (texture && !texture->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject textureObject = objectOrZero(texture);
+ switch (attachment) {
+ case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+ webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, textureObject, level);
+ webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
+ break;
+ case GL_DEPTH_ATTACHMENT:
+ webContext()->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ case GL_STENCIL_ATTACHMENT:
+ webContext()->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ default:
+ webContext()->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::frontFace(GLenum mode)
+{
+ if (isContextLost())
+ return;
+ switch (mode) {
+ case GL_CW:
+ case GL_CCW:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "frontFace", "invalid mode");
+ return;
+ }
+ webContext()->frontFace(mode);
+}
+
+void WebGLRenderingContextBase::generateMipmap(GLenum target)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
+ if (!tex)
+ return;
+ if (!tex->canGenerateMipmaps()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
+ return;
+ }
+ if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
+ return;
+
+ // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
+ // on Mac. Remove the hack once this driver bug is fixed.
+#if OS(MACOSX)
+ bool needToResetMinFilter = false;
+ if (tex->getMinFilter() != GL_NEAREST_MIPMAP_LINEAR) {
+ webContext()->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+ needToResetMinFilter = true;
+ }
+#endif
+ webContext()->generateMipmap(target);
+#if OS(MACOSX)
+ if (needToResetMinFilter)
+ webContext()->texParameteri(target, GL_TEXTURE_MIN_FILTER, tex->getMinFilter());
+#endif
+ tex->generateMipmapLevelInfo();
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* program, GLuint index)
+{
+ if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
+ return nullptr;
+ blink::WebGraphicsContext3D::ActiveInfo info;
+ if (!webContext()->getActiveAttrib(objectOrZero(program), index, info))
+ return nullptr;
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveUniform(WebGLProgram* program, GLuint index)
+{
+ if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
+ return nullptr;
+ blink::WebGraphicsContext3D::ActiveInfo info;
+ if (!webContext()->getActiveUniform(objectOrZero(program), index, info))
+ return nullptr;
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+bool WebGLRenderingContextBase::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader> >& shaderObjects)
+{
+ shaderObjects.clear();
+ if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
+ return false;
+
+ const GLenum shaderType[] = {
+ GL_VERTEX_SHADER,
+ GL_FRAGMENT_SHADER
+ };
+ for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GLenum); ++i) {
+ WebGLShader* shader = program->getAttachedShader(shaderType[i]);
+ if (shader)
+ shaderObjects.append(shader);
+ }
+ return true;
+}
+
+GLint WebGLRenderingContextBase::getAttribLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
+ return -1;
+ if (!validateLocationLength("getAttribLocation", name))
+ return -1;
+ if (!validateString("getAttribLocation", name))
+ return -1;
+ if (isPrefixReserved(name))
+ return -1;
+ if (!program->linkStatus()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked");
+ return 0;
+ }
+ return webContext()->getAttribLocation(objectOrZero(program), name.utf8().data());
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBufferParameter(GLenum target, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid target");
+ return WebGLGetInfo();
+ }
+
+ if (pname != GL_BUFFER_SIZE && pname != GL_BUFFER_USAGE) {
+ synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+
+ GLint value = 0;
+ webContext()->getBufferParameteriv(target, pname, &value);
+ if (pname == GL_BUFFER_SIZE)
+ return WebGLGetInfo(value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+}
+
+PassRefPtr<WebGLContextAttributes> WebGLRenderingContextBase::getContextAttributes()
+{
+ if (isContextLost())
+ return nullptr;
+ // We always need to return a new WebGLContextAttributes object to
+ // prevent the user from mutating any cached version.
+ blink::WebGraphicsContext3D::Attributes attrs = m_drawingBuffer->getActualAttributes();
+ RefPtr<WebGLContextAttributes> attributes = m_requestedAttributes->clone();
+ // Some requested attributes may not be honored, so we need to query the underlying
+ // context/drawing buffer and adjust accordingly.
+ if (m_requestedAttributes->depth() && !attrs.depth)
+ attributes->setDepth(false);
+ if (m_requestedAttributes->stencil() && !attrs.stencil)
+ attributes->setStencil(false);
+ attributes->setAntialias(m_drawingBuffer->multisample());
+ return attributes.release();
+}
+
+GLenum WebGLRenderingContextBase::getError()
+{
+ if (m_lostContextErrors.size()) {
+ GLenum err = m_lostContextErrors.first();
+ m_lostContextErrors.remove(0);
+ return err;
+ }
+
+ if (isContextLost())
+ return GL_NO_ERROR;
+
+ return webContext()->getError();
+}
+
+const char* const* WebGLRenderingContextBase::ExtensionTracker::prefixes() const
+{
+ static const char* const unprefixed[] = { "", 0, };
+ return m_prefixes ? m_prefixes : unprefixed;
+}
+
+bool WebGLRenderingContextBase::ExtensionTracker::matchesNameWithPrefixes(const String& name) const
+{
+ const char* const* prefixSet = prefixes();
+ for (; *prefixSet; ++prefixSet) {
+ String prefixedName = String(*prefixSet) + extensionName();
+ if (equalIgnoringCase(prefixedName, name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WebGLRenderingContextBase::extensionSupportedAndAllowed(const ExtensionTracker* tracker)
+{
+ if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
+ return false;
+ if (!tracker->supported(this))
+ return false;
+ return true;
+}
+
+
+PassRefPtr<WebGLExtension> WebGLRenderingContextBase::getExtension(const String& name)
+{
+ if (isContextLost())
+ return nullptr;
+
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ ExtensionTracker* tracker = m_extensions[i];
+ if (tracker->matchesNameWithPrefixes(name)) {
+ if (!extensionSupportedAndAllowed(tracker))
+ return nullptr;
+
+ RefPtr<WebGLExtension> extension = tracker->getExtension(this);
+ if (extension)
+ m_extensionEnabled[extension->name()] = true;
+ return extension.release();
+ }
+ }
+
+ return nullptr;
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname)
+{
+ if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+ return WebGLGetInfo();
+
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
+ return WebGLGetInfo();
+ }
+
+ WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
+ if (!object) {
+ if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+ return WebGLGetInfo(GL_NONE);
+ // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+ // specifies INVALID_OPERATION.
+ synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+
+ ASSERT(object->isTexture() || object->isRenderbuffer());
+ if (object->isTexture()) {
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GL_TEXTURE);
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(static_cast<WebGLTexture*>(object)));
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ {
+ GLint value = 0;
+ webContext()->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ return WebGLGetInfo(value);
+ }
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
+ return WebGLGetInfo();
+ }
+ } else {
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GL_RENDERBUFFER);
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(static_cast<WebGLRenderbuffer*>(object)));
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
+ return WebGLGetInfo();
+ }
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getParameter(GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ const int intZero = 0;
+ switch (pname) {
+ case GL_ACTIVE_TEXTURE:
+ return getUnsignedIntParameter(pname);
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_ALPHA_BITS:
+ return getIntParameter(pname);
+ case GL_ARRAY_BUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
+ case GL_BLEND:
+ return getBooleanParameter(pname);
+ case GL_BLEND_COLOR:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_BLEND_DST_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_DST_RGB:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_EQUATION_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_EQUATION_RGB:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_SRC_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_SRC_RGB:
+ return getUnsignedIntParameter(pname);
+ case GL_BLUE_BITS:
+ return getIntParameter(pname);
+ case GL_COLOR_CLEAR_VALUE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_COLOR_WRITEMASK:
+ return getBooleanArrayParameter(pname);
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
+ case GL_CULL_FACE:
+ return getBooleanParameter(pname);
+ case GL_CULL_FACE_MODE:
+ return getUnsignedIntParameter(pname);
+ case GL_CURRENT_PROGRAM:
+ return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
+ case GL_DEPTH_BITS:
+ if (!m_framebufferBinding && !m_requestedAttributes->depth())
+ return WebGLGetInfo(intZero);
+ return getIntParameter(pname);
+ case GL_DEPTH_CLEAR_VALUE:
+ return getFloatParameter(pname);
+ case GL_DEPTH_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GL_DEPTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_DEPTH_TEST:
+ return getBooleanParameter(pname);
+ case GL_DEPTH_WRITEMASK:
+ return getBooleanParameter(pname);
+ case GL_DITHER:
+ return getBooleanParameter(pname);
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->boundElementArrayBuffer()));
+ case GL_FRAMEBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
+ case GL_FRONT_FACE:
+ return getUnsignedIntParameter(pname);
+ case GL_GENERATE_MIPMAP_HINT:
+ return getUnsignedIntParameter(pname);
+ case GL_GREEN_BITS:
+ return getIntParameter(pname);
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ return getIntParameter(pname);
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ return getIntParameter(pname);
+ case GL_LINE_WIDTH:
+ return getFloatParameter(pname);
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GL_MAX_RENDERBUFFER_SIZE:
+ return getIntParameter(pname);
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GL_MAX_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GL_MAX_VARYING_VECTORS:
+ return getIntParameter(pname);
+ case GL_MAX_VERTEX_ATTRIBS:
+ return getIntParameter(pname);
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GL_MAX_VIEWPORT_DIMS:
+ return getWebGLIntArrayParameter(pname);
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ // FIXME: should we always return 0 for this?
+ return getIntParameter(pname);
+ case GL_PACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GL_POLYGON_OFFSET_FACTOR:
+ return getFloatParameter(pname);
+ case GL_POLYGON_OFFSET_FILL:
+ return getBooleanParameter(pname);
+ case GL_POLYGON_OFFSET_UNITS:
+ return getFloatParameter(pname);
+ case GL_RED_BITS:
+ return getIntParameter(pname);
+ case GL_RENDERBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ case GL_RENDERER:
+ return WebGLGetInfo(String("WebKit WebGL"));
+ case GL_SAMPLE_BUFFERS:
+ return getIntParameter(pname);
+ case GL_SAMPLE_COVERAGE_INVERT:
+ return getBooleanParameter(pname);
+ case GL_SAMPLE_COVERAGE_VALUE:
+ return getFloatParameter(pname);
+ case GL_SAMPLES:
+ return getIntParameter(pname);
+ case GL_SCISSOR_BOX:
+ return getWebGLIntArrayParameter(pname);
+ case GL_SCISSOR_TEST:
+ return getBooleanParameter(pname);
+ case GL_SHADING_LANGUAGE_VERSION:
+ return WebGLGetInfo("WebGL GLSL ES 1.0 (" + String(webContext()->getString(GL_SHADING_LANGUAGE_VERSION)) + ")");
+ case GL_STENCIL_BACK_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_REF:
+ return getIntParameter(pname);
+ case GL_STENCIL_BACK_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BITS:
+ if (!m_framebufferBinding && !m_requestedAttributes->stencil())
+ return WebGLGetInfo(intZero);
+ return getIntParameter(pname);
+ case GL_STENCIL_CLEAR_VALUE:
+ return getIntParameter(pname);
+ case GL_STENCIL_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_REF:
+ return getIntParameter(pname);
+ case GL_STENCIL_TEST:
+ return getBooleanParameter(pname);
+ case GL_STENCIL_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GL_SUBPIXEL_BITS:
+ return getIntParameter(pname);
+ case GL_TEXTURE_BINDING_2D:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
+ case GL_UNPACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GC3D_UNPACK_FLIP_Y_WEBGL:
+ return WebGLGetInfo(m_unpackFlipY);
+ case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ return WebGLGetInfo(m_unpackPremultiplyAlpha);
+ case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ return WebGLGetInfo(m_unpackColorspaceConversion);
+ case GL_VENDOR:
+ return WebGLGetInfo(String("WebKit"));
+ case GL_VERSION:
+ return WebGLGetInfo("WebGL 1.0 (" + String(webContext()->getString(GL_VERSION)) + ")");
+ case GL_VIEWPORT:
+ return getWebGLIntArrayParameter(pname);
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (extensionEnabled(OESStandardDerivativesName))
+ return getUnsignedIntParameter(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
+ if (extensionEnabled(WebGLDebugRendererInfoName))
+ return WebGLGetInfo(webContext()->getString(GL_RENDERER));
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
+ if (extensionEnabled(WebGLDebugRendererInfoName))
+ return WebGLGetInfo(webContext()->getString(GL_VENDOR));
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return WebGLGetInfo();
+ case GL_VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
+ if (extensionEnabled(OESVertexArrayObjectName)) {
+ if (!m_boundVertexArrayObject->isDefaultObject())
+ return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
+ return WebGLGetInfo();
+ }
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
+ return WebGLGetInfo();
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (extensionEnabled(EXTTextureFilterAnisotropicName))
+ return getUnsignedIntParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return WebGLGetInfo();
+ case GL_MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
+ if (extensionEnabled(WebGLDrawBuffersName))
+ return WebGLGetInfo(maxColorAttachments());
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+ return WebGLGetInfo();
+ case GL_MAX_DRAW_BUFFERS_EXT:
+ if (extensionEnabled(WebGLDrawBuffersName))
+ return WebGLGetInfo(maxDrawBuffers());
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+ return WebGLGetInfo();
+ default:
+ if (extensionEnabled(WebGLDrawBuffersName)
+ && pname >= GL_DRAW_BUFFER0_EXT
+ && pname < static_cast<GLenum>(GL_DRAW_BUFFER0_EXT + maxDrawBuffers())) {
+ GLint value = GL_NONE;
+ if (m_framebufferBinding)
+ value = m_framebufferBinding->getDrawBuffer(pname);
+ else // emulated backbuffer
+ value = m_backDrawBuffer;
+ return WebGLGetInfo(value);
+ }
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getProgramParameter(WebGLProgram* program, GLenum pname)
+{
+ if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
+ return WebGLGetInfo();
+
+ GLint value = 0;
+ switch (pname) {
+ case GL_DELETE_STATUS:
+ return WebGLGetInfo(program->isDeleted());
+ case GL_VALIDATE_STATUS:
+ webContext()->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+ case GL_LINK_STATUS:
+ return WebGLGetInfo(program->linkStatus());
+ case GL_ATTACHED_SHADERS:
+ case GL_ACTIVE_ATTRIBUTES:
+ case GL_ACTIVE_UNIFORMS:
+ webContext()->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(value);
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContextBase::getProgramInfoLog(WebGLProgram* program)
+{
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getProgramInfoLog", program))
+ return "";
+ return ensureNotNull(webContext()->getProgramInfoLog(objectOrZero(program)));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getRenderbufferParameter(GLenum target, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target");
+ return WebGLGetInfo();
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
+ return WebGLGetInfo();
+ }
+
+ GLint value = 0;
+ switch (pname) {
+ case GL_RENDERBUFFER_WIDTH:
+ case GL_RENDERBUFFER_HEIGHT:
+ case GL_RENDERBUFFER_RED_SIZE:
+ case GL_RENDERBUFFER_GREEN_SIZE:
+ case GL_RENDERBUFFER_BLUE_SIZE:
+ case GL_RENDERBUFFER_ALPHA_SIZE:
+ case GL_RENDERBUFFER_DEPTH_SIZE:
+ webContext()->getRenderbufferParameteriv(target, pname, &value);
+ return WebGLGetInfo(value);
+ case GL_RENDERBUFFER_STENCIL_SIZE:
+ if (m_renderbufferBinding->emulatedStencilBuffer()) {
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding->emulatedStencilBuffer()));
+ webContext()->getRenderbufferParameteriv(target, pname, &value);
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+ } else {
+ webContext()->getRenderbufferParameteriv(target, pname, &value);
+ }
+ return WebGLGetInfo(value);
+ case GL_RENDERBUFFER_INTERNAL_FORMAT:
+ return WebGLGetInfo(m_renderbufferBinding->internalFormat());
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getShaderParameter(WebGLShader* shader, GLenum pname)
+{
+ if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
+ return WebGLGetInfo();
+ GLint value = 0;
+ switch (pname) {
+ case GL_DELETE_STATUS:
+ return WebGLGetInfo(shader->isDeleted());
+ case GL_COMPILE_STATUS:
+ webContext()->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+ case GL_SHADER_TYPE:
+ webContext()->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContextBase::getShaderInfoLog(WebGLShader* shader)
+{
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getShaderInfoLog", shader))
+ return "";
+ return ensureNotNull(webContext()->getShaderInfoLog(objectOrZero(shader)));
+}
+
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContextBase::getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType)
+{
+ if (isContextLost())
+ return nullptr;
+ switch (shaderType) {
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
+ return nullptr;
+ }
+ switch (precisionType) {
+ case GL_LOW_FLOAT:
+ case GL_MEDIUM_FLOAT:
+ case GL_HIGH_FLOAT:
+ case GL_LOW_INT:
+ case GL_MEDIUM_INT:
+ case GL_HIGH_INT:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
+ return nullptr;
+ }
+
+ GLint range[2] = {0, 0};
+ GLint precision = 0;
+ webContext()->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
+ return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
+}
+
+String WebGLRenderingContextBase::getShaderSource(WebGLShader* shader)
+{
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getShaderSource", shader))
+ return "";
+ return ensureNotNull(shader->source());
+}
+
+Vector<String> WebGLRenderingContextBase::getSupportedExtensions()
+{
+ Vector<String> result;
+ if (isContextLost())
+ return result;
+
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ ExtensionTracker* tracker = m_extensions[i];
+ if (extensionSupportedAndAllowed(tracker)) {
+ const char* const* prefixes = tracker->prefixes();
+ for (; *prefixes; ++prefixes) {
+ String prefixedName = String(*prefixes) + tracker->extensionName();
+ result.append(prefixedName);
+ }
+ }
+ }
+
+ return result;
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getTexParameter(GLenum target, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
+ if (!tex)
+ return WebGLGetInfo();
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ {
+ GLint value = 0;
+ webContext()->getTexParameteriv(target, pname, &value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+ }
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (extensionEnabled(EXTTextureFilterAnisotropicName)) {
+ GLfloat value = 0.f;
+ webContext()->getTexParameterfv(target, pname, &value);
+ return WebGLGetInfo(value);
+ }
+ synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return WebGLGetInfo();
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
+{
+ if (isContextLost() || !validateWebGLObject("getUniform", program))
+ return WebGLGetInfo();
+ if (!uniformLocation || uniformLocation->program() != program) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
+ return WebGLGetInfo();
+ }
+ GLint location = uniformLocation->location();
+
+ // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
+ GLint activeUniforms = 0;
+ webContext()->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
+ for (GLint i = 0; i < activeUniforms; i++) {
+ blink::WebGraphicsContext3D::ActiveInfo info;
+ if (!webContext()->getActiveUniform(objectOrZero(program), i, info))
+ return WebGLGetInfo();
+ String name = info.name;
+ StringBuilder nameBuilder;
+ // Strip "[0]" from the name if it's an array.
+ if (info.size > 1 && name.endsWith("[0]"))
+ info.name = name.left(name.length() - 3);
+ // If it's an array, we need to iterate through each element, appending "[index]" to the name.
+ for (GLint index = 0; index < info.size; ++index) {
+ nameBuilder.clear();
+ nameBuilder.append(info.name);
+ if (info.size > 1 && index >= 1) {
+ nameBuilder.append('[');
+ nameBuilder.append(String::number(index));
+ nameBuilder.append(']');
+ }
+ // Now need to look this up by name again to find its location
+ GLint loc = webContext()->getUniformLocation(objectOrZero(program), nameBuilder.toString().utf8().data());
+ if (loc == location) {
+ // Found it. Use the type in the ActiveInfo to determine the return type.
+ GLenum baseType;
+ unsigned length;
+ switch (info.type) {
+ case GL_BOOL:
+ baseType = GL_BOOL;
+ length = 1;
+ break;
+ case GL_BOOL_VEC2:
+ baseType = GL_BOOL;
+ length = 2;
+ break;
+ case GL_BOOL_VEC3:
+ baseType = GL_BOOL;
+ length = 3;
+ break;
+ case GL_BOOL_VEC4:
+ baseType = GL_BOOL;
+ length = 4;
+ break;
+ case GL_INT:
+ baseType = GL_INT;
+ length = 1;
+ break;
+ case GL_INT_VEC2:
+ baseType = GL_INT;
+ length = 2;
+ break;
+ case GL_INT_VEC3:
+ baseType = GL_INT;
+ length = 3;
+ break;
+ case GL_INT_VEC4:
+ baseType = GL_INT;
+ length = 4;
+ break;
+ case GL_FLOAT:
+ baseType = GL_FLOAT;
+ length = 1;
+ break;
+ case GL_FLOAT_VEC2:
+ baseType = GL_FLOAT;
+ length = 2;
+ break;
+ case GL_FLOAT_VEC3:
+ baseType = GL_FLOAT;
+ length = 3;
+ break;
+ case GL_FLOAT_VEC4:
+ baseType = GL_FLOAT;
+ length = 4;
+ break;
+ case GL_FLOAT_MAT2:
+ baseType = GL_FLOAT;
+ length = 4;
+ break;
+ case GL_FLOAT_MAT3:
+ baseType = GL_FLOAT;
+ length = 9;
+ break;
+ case GL_FLOAT_MAT4:
+ baseType = GL_FLOAT;
+ length = 16;
+ break;
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ baseType = GL_INT;
+ length = 1;
+ break;
+ default:
+ // Can't handle this type
+ synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type");
+ return WebGLGetInfo();
+ }
+ switch (baseType) {
+ case GL_FLOAT: {
+ GLfloat value[16] = {0};
+ webContext()->getUniformfv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Float32Array::create(value, length));
+ }
+ case GL_INT: {
+ GLint value[4] = {0};
+ webContext()->getUniformiv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Int32Array::create(value, length));
+ }
+ case GL_BOOL: {
+ GLint value[4] = {0};
+ webContext()->getUniformiv(objectOrZero(program), location, value);
+ if (length > 1) {
+ bool boolValue[16] = {0};
+ for (unsigned j = 0; j < length; j++)
+ boolValue[j] = static_cast<bool>(value[j]);
+ return WebGLGetInfo(boolValue, length);
+ }
+ return WebGLGetInfo(static_cast<bool>(value[0]));
+ }
+ default:
+ notImplemented();
+ }
+ }
+ }
+ }
+ // If we get here, something went wrong in our unfortunately complex logic above
+ synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error");
+ return WebGLGetInfo();
+}
+
+PassRefPtr<WebGLUniformLocation> WebGLRenderingContextBase::getUniformLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
+ return nullptr;
+ if (!validateLocationLength("getUniformLocation", name))
+ return nullptr;
+ if (!validateString("getUniformLocation", name))
+ return nullptr;
+ if (isPrefixReserved(name))
+ return nullptr;
+ if (!program->linkStatus()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getUniformLocation", "program not linked");
+ return nullptr;
+ }
+ GLint uniformLocation = webContext()->getUniformLocation(objectOrZero(program), name.utf8().data());
+ if (uniformLocation == -1)
+ return nullptr;
+ return WebGLUniformLocation::create(program, uniformLocation);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getVertexAttrib(GLuint index, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range");
+ return WebGLGetInfo();
+ }
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+
+ if (extensionEnabled(ANGLEInstancedArraysName) && pname == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
+ return WebGLGetInfo(state.divisor);
+
+ switch (pname) {
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ if (!state.bufferBinding || !state.bufferBinding->object())
+ return WebGLGetInfo();
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ return WebGLGetInfo(state.enabled);
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ return WebGLGetInfo(state.normalized);
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ return WebGLGetInfo(state.size);
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ return WebGLGetInfo(state.originalStride);
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ return WebGLGetInfo(state.type);
+ case GL_CURRENT_VERTEX_ATTRIB:
+ return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+long long WebGLRenderingContextBase::getVertexAttribOffset(GLuint index, GLenum pname)
+{
+ if (isContextLost())
+ return 0;
+ if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) {
+ synthesizeGLError(GL_INVALID_ENUM, "getVertexAttribOffset", "invalid parameter name");
+ return 0;
+ }
+ GLsizeiptr result = webContext()->getVertexAttribOffset(index, pname);
+ return static_cast<long long>(result);
+}
+
+void WebGLRenderingContextBase::hint(GLenum target, GLenum mode)
+{
+ if (isContextLost())
+ return;
+ bool isValid = false;
+ switch (target) {
+ case GL_GENERATE_MIPMAP_HINT:
+ isValid = true;
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (extensionEnabled(OESStandardDerivativesName))
+ isValid = true;
+ break;
+ }
+ if (!isValid) {
+ synthesizeGLError(GL_INVALID_ENUM, "hint", "invalid target");
+ return;
+ }
+ webContext()->hint(target, mode);
+}
+
+GLboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
+{
+ if (!buffer || isContextLost())
+ return 0;
+
+ if (!buffer->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isBuffer(buffer->object());
+}
+
+bool WebGLRenderingContextBase::isContextLost() const
+{
+ return m_contextLost;
+}
+
+GLboolean WebGLRenderingContextBase::isEnabled(GLenum cap)
+{
+ if (isContextLost() || !validateCapability("isEnabled", cap))
+ return 0;
+ if (cap == GL_STENCIL_TEST)
+ return m_stencilEnabled;
+ return webContext()->isEnabled(cap);
+}
+
+GLboolean WebGLRenderingContextBase::isFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!framebuffer || isContextLost())
+ return 0;
+
+ if (!framebuffer->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isFramebuffer(framebuffer->object());
+}
+
+GLboolean WebGLRenderingContextBase::isProgram(WebGLProgram* program)
+{
+ if (!program || isContextLost())
+ return 0;
+
+ return webContext()->isProgram(program->object());
+}
+
+GLboolean WebGLRenderingContextBase::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!renderbuffer || isContextLost())
+ return 0;
+
+ if (!renderbuffer->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isRenderbuffer(renderbuffer->object());
+}
+
+GLboolean WebGLRenderingContextBase::isShader(WebGLShader* shader)
+{
+ if (!shader || isContextLost())
+ return 0;
+
+ return webContext()->isShader(shader->object());
+}
+
+GLboolean WebGLRenderingContextBase::isTexture(WebGLTexture* texture)
+{
+ if (!texture || isContextLost())
+ return 0;
+
+ if (!texture->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isTexture(texture->object());
+}
+
+void WebGLRenderingContextBase::lineWidth(GLfloat width)
+{
+ if (isContextLost())
+ return;
+ webContext()->lineWidth(width);
+}
+
+void WebGLRenderingContextBase::linkProgram(WebGLProgram* program)
+{
+ if (isContextLost() || !validateWebGLObject("linkProgram", program))
+ return;
+
+ webContext()->linkProgram(objectOrZero(program));
+ program->increaseLinkCount();
+}
+
+void WebGLRenderingContextBase::pixelStorei(GLenum pname, GLint param)
+{
+ if (isContextLost())
+ return;
+ switch (pname) {
+ case GC3D_UNPACK_FLIP_Y_WEBGL:
+ m_unpackFlipY = param;
+ break;
+ case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ m_unpackPremultiplyAlpha = param;
+ break;
+ case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ if (static_cast<GLenum>(param) == GC3D_BROWSER_DEFAULT_WEBGL || param == GL_NONE) {
+ m_unpackColorspaceConversion = static_cast<GLenum>(param);
+ } else {
+ synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
+ return;
+ }
+ break;
+ case GL_PACK_ALIGNMENT:
+ case GL_UNPACK_ALIGNMENT:
+ if (param == 1 || param == 2 || param == 4 || param == 8) {
+ if (pname == GL_PACK_ALIGNMENT) {
+ m_packAlignment = param;
+ m_drawingBuffer->setPackAlignment(param);
+ } else { // GL_UNPACK_ALIGNMENT:
+ m_unpackAlignment = param;
+ }
+ webContext()->pixelStorei(pname, param);
+ } else {
+ synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "pixelStorei", "invalid parameter name");
+ return;
+ }
+}
+
+void WebGLRenderingContextBase::polygonOffset(GLfloat factor, GLfloat units)
+{
+ if (isContextLost())
+ return;
+ webContext()->polygonOffset(factor, units);
+}
+
+void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels)
+{
+ if (isContextLost())
+ return;
+ // Due to WebGL's same-origin restrictions, it is not possible to
+ // taint the origin using the WebGL API.
+ ASSERT(canvas()->originClean());
+ // Validate input parameters.
+ if (!pixels) {
+ synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
+ return;
+ }
+ switch (format) {
+ case GL_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
+ return;
+ }
+
+ ArrayBufferView::ViewType expectedViewType;
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ expectedViewType = ArrayBufferView::TypeUint8;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ expectedViewType = ArrayBufferView::TypeUint16;
+ break;
+ case GL_FLOAT:
+ expectedViewType = ArrayBufferView::TypeFloat32;
+ break;
+ case GL_HALF_FLOAT_OES:
+ expectedViewType = ArrayBufferView::TypeUint16;
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
+ return;
+ }
+ if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
+ // Check against the implementation color read format and type.
+ blink::WGC3Dint implFormat = 0, implType = 0;
+ webContext()->getIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &implFormat);
+ webContext()->getIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &implType);
+ if (!implFormat || !implType || format != static_cast<GLenum>(implFormat) || type != static_cast<GLenum>(implType)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type not RGBA/UNSIGNED_BYTE or implementation-defined values");
+ return;
+ }
+ }
+ // Validate array type against pixel type.
+ if (pixels->type() != expectedViewType) {
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView was the wrong type for the pixel format");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
+ return;
+ }
+ // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+ unsigned totalBytesRequired = 0;
+ unsigned padding = 0;
+ GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+ if (error != GL_NO_ERROR) {
+ synthesizeGLError(error, "readPixels", "invalid dimensions");
+ return;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
+ return;
+ }
+
+ clearIfComposited();
+ void* data = pixels->baseAddress();
+
+ {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ webContext()->readPixels(x, y, width, height, format, type, data);
+ }
+
+#if OS(MACOSX)
+ // 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 (!m_framebufferBinding && !m_drawingBuffer->getActualAttributes().alpha) {
+ unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
+ for (GLsizei iy = 0; iy < height; ++iy) {
+ for (GLsizei ix = 0; ix < width; ++ix) {
+ pixels[3] = 255;
+ pixels += 4;
+ }
+ pixels += padding;
+ }
+ }
+#endif
+}
+
+void WebGLRenderingContextBase::renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (target != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid target");
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
+ return;
+ }
+ if (!validateSize("renderbufferStorage", width, height))
+ return;
+ switch (internalformat) {
+ case GL_DEPTH_COMPONENT16:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_STENCIL_INDEX8:
+ webContext()->renderbufferStorage(target, internalformat, width, height);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->deleteEmulatedStencilBuffer(webContext());
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ if (isDepthStencilSupported()) {
+ webContext()->renderbufferStorage(target, GL_DEPTH24_STENCIL8_OES, width, height);
+ } else {
+ WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(target, m_renderbufferBinding.get());
+ if (!emulatedStencilBuffer) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, "renderbufferStorage", "out of memory");
+ return;
+ }
+ webContext()->renderbufferStorage(target, GL_DEPTH_COMPONENT16, width, height);
+ webContext()->bindRenderbuffer(target, objectOrZero(emulatedStencilBuffer));
+ webContext()->renderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+ emulatedStencilBuffer->setSize(width, height);
+ emulatedStencilBuffer->setInternalFormat(GL_STENCIL_INDEX8);
+ }
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+ return;
+ }
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::sampleCoverage(GLfloat value, GLboolean invert)
+{
+ if (isContextLost())
+ return;
+ webContext()->sampleCoverage(value, invert);
+}
+
+void WebGLRenderingContextBase::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize("scissor", width, height))
+ return;
+ webContext()->scissor(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, const String& string)
+{
+ if (isContextLost() || !validateWebGLObject("shaderSource", shader))
+ return;
+ String stringWithoutComments = StripComments(string).result();
+ if (!validateString("shaderSource", stringWithoutComments))
+ return;
+ shader->setSource(string);
+ webContext()->shaderSource(objectOrZero(shader), stringWithoutComments.utf8().data());
+}
+
+void WebGLRenderingContextBase::stencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilOrDepthFunc("stencilFunc", func))
+ return;
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ webContext()->stencilFunc(func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilOrDepthFunc("stencilFuncSeparate", func))
+ return;
+ switch (face) {
+ case GL_FRONT_AND_BACK:
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ break;
+ case GL_FRONT:
+ m_stencilFuncRef = ref;
+ m_stencilFuncMask = mask;
+ break;
+ case GL_BACK:
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "stencilFuncSeparate", "invalid face");
+ return;
+ }
+ webContext()->stencilFuncSeparate(face, func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilMask(GLuint mask)
+{
+ if (isContextLost())
+ return;
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ webContext()->stencilMask(mask);
+}
+
+void WebGLRenderingContextBase::stencilMaskSeparate(GLenum face, GLuint mask)
+{
+ if (isContextLost())
+ return;
+ switch (face) {
+ case GL_FRONT_AND_BACK:
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ break;
+ case GL_FRONT:
+ m_stencilMask = mask;
+ break;
+ case GL_BACK:
+ m_stencilMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "stencilMaskSeparate", "invalid face");
+ return;
+ }
+ webContext()->stencilMaskSeparate(face, mask);
+}
+
+void WebGLRenderingContextBase::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ if (isContextLost())
+ return;
+ webContext()->stencilOp(fail, zfail, zpass);
+}
+
+void WebGLRenderingContextBase::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ if (isContextLost())
+ return;
+ webContext()->stencilOpSeparate(face, fail, zfail, zpass);
+}
+
+GLenum WebGLRenderingContextBase::convertTexInternalFormat(GLenum internalformat, GLenum type)
+{
+ // Convert to sized internal formats that are renderable with GL_CHROMIUM_color_buffer_float_rgb(a).
+ if (type == GL_FLOAT && internalformat == GL_RGBA
+ && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"))
+ return GL_RGBA32F_EXT;
+ if (type == GL_FLOAT && internalformat == GL_RGB
+ && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"))
+ return GL_RGB32F_EXT;
+ return internalformat;
+}
+
+void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ // FIXME: Handle errors.
+ WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
+ ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
+ ASSERT(tex);
+ ASSERT(!level || !WebGLTexture::isNPOT(width, height));
+ ASSERT(!pixels || validateSettableTexFormat("texImage2D", internalformat));
+ webContext()->texImage2D(target, level, convertTexInternalFormat(internalformat, type), width, height, border, format, type, pixels);
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
+}
+
+void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ Vector<uint8_t> data;
+ WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData, exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
+{
+ if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
+ return false;
+
+ WebGLTexture* texture = validateTextureBinding(functionName, target, true);
+ if (!texture)
+ return false;
+
+ if (functionType == NotTexSubImage2D) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not power of 2");
+ return false;
+ }
+ // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
+ // by checking if the ArrayBufferView is null or not.
+ if (sourceType != SourceArrayBufferView) {
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+ }
+ } else {
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+ if (!validateSize(functionName, xoffset, yoffset))
+ return false;
+ // Before checking if it is in the range, check if overflow happens first.
+ if (xoffset + width < 0 || yoffset + height < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions");
+ return false;
+ }
+ if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
+ return false;
+ }
+ if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type and format do not match texture");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateValueFitNonNegInt32(const char* functionName, const char* paramName, long long value)
+{
+ if (value < 0) {
+ String errorMsg = String(paramName) + " < 0";
+ synthesizeGLError(GL_INVALID_VALUE, functionName, errorMsg.ascii().data());
+ return false;
+ }
+ if (value > static_cast<long long>(std::numeric_limits<int>::max())) {
+ String errorMsg = String(paramName) + " more than 32-bit";
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, errorMsg.ascii().data());
+ return false;
+ }
+ return true;
+}
+
+PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(Image* image, int width, int height, const char* functionName)
+{
+ IntSize size(width, height);
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, functionName, "out of memory");
+ return nullptr;
+ }
+
+ IntRect srcRect(IntPoint(), image->size());
+ IntRect destRect(0, 0, size.width(), size.height());
+ buf->context()->drawImage(image, destRect, srcRect);
+ return buf->copyImage(ImageBuffer::fastCopyImageMode());
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
+ || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
+ return;
+ void* data = pixels ? pixels->baseAddress() : 0;
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, width, height, border, format, type, data, exceptionState);
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
+ return;
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLImageElement("texImage2D", image, exceptionState))
+ return;
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texImage2D");
+
+ if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
+ return;
+
+ texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exceptionState) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
+ return;
+
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+
+ // If possible, copy from the canvas element directly to the texture
+ // via the GPU, without a read-back to system memory.
+ if (GL_TEXTURE_2D == target && texture) {
+ ScopedTexture2DRestorer restorer(this);
+
+ if (!canvas->is3D()) {
+ ImageBuffer* buffer = canvas->buffer();
+ if (buffer && buffer->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
+ level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ return;
+ }
+ } else {
+ WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
+ ScopedTexture2DRestorer restorer(gl);
+ if (gl && gl->m_drawingBuffer->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
+ level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ return;
+ }
+ }
+ }
+
+ RefPtrWillBeRawPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
+ else
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
+{
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
+ return nullptr;
+ }
+ IntRect destRect(0, 0, size.width(), size.height());
+ // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+ video->paintCurrentFrameInContext(buf->context(), destRect);
+ return buf->copyImage(backingStoreCopy);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, exceptionState)
+ || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
+ return;
+
+ // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+ // Otherwise, it will fall back to the normal SW path.
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+ if (GL_TEXTURE_2D == target && texture) {
+ if (video->copyVideoTextureToPlatformTexture(webContext(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
+ return;
+ }
+ }
+
+ // Normal pure SW path.
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
+ if (!image)
+ return;
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
+ if (!tex)
+ return;
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ break;
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ if ((isFloat && paramf != GL_CLAMP_TO_EDGE && paramf != GL_MIRRORED_REPEAT && paramf != GL_REPEAT)
+ || (!isFloat && parami != GL_CLAMP_TO_EDGE && parami != GL_MIRRORED_REPEAT && parami != GL_REPEAT)) {
+ synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter");
+ return;
+ }
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (!extensionEnabled(EXTTextureFilterAnisotropicName)) {
+ synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter name");
+ return;
+ }
+ if (isFloat) {
+ tex->setParameterf(pname, paramf);
+ webContext()->texParameterf(target, pname, paramf);
+ } else {
+ tex->setParameteri(pname, parami);
+ webContext()->texParameteri(target, pname, parami);
+ }
+}
+
+void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ texParameter(target, pname, param, 0, true);
+}
+
+void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param)
+{
+ texParameter(target, pname, 0, param, false);
+}
+
+void WebGLRenderingContextBase::texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
+{
+ // FIXME: Handle errors.
+ ASSERT(!isContextLost());
+ ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
+ ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
+ ASSERT(validateSettableTexFormat("texSubImage2D", format));
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ if (!tex) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT((xoffset + width) >= 0);
+ ASSERT((yoffset + height) >= 0);
+ ASSERT(tex->getWidth(target, level) >= (xoffset + width));
+ ASSERT(tex->getHeight(target, level) >= (yoffset + height));
+ ASSERT(tex->getInternalFormat(target, level) == format);
+ ASSERT(tex->getType(target, level) == type);
+ webContext()->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGLRenderingContextBase::texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ Vector<uint8_t> data;
+ WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
+ return;
+ }
+ WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texSubImage2DBase(target, level, xoffset, yoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data.data() : imagePixelData, exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
+ return;
+ void* data = pixels->baseAddress();
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!WebGLImageConversion::extractTextureData(width, height, format, type,
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, exceptionState);
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, exceptionState))
+ return;
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texSubImage2D");
+
+ if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtrWillBeRawPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
+ else
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, exceptionState)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
+ if (!image)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform1f(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
+ return;
+
+ webContext()->uniform1fv(location->location(), v->length(), v->data());
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
+ return;
+
+ webContext()->uniform1fv(location->location(), size, v);
+}
+
+void WebGLRenderingContextBase::uniform1i(const WebGLUniformLocation* location, GLint x)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform1i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform1i(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
+ return;
+
+ webContext()->uniform1iv(location->location(), v->length(), v->data());
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
+ return;
+
+ webContext()->uniform1iv(location->location(), size, v);
+}
+
+void WebGLRenderingContextBase::uniform2f(const WebGLUniformLocation* location, GLfloat x, GLfloat y)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform2f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform2f(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
+ return;
+
+ webContext()->uniform2fv(location->location(), v->length() / 2, v->data());
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
+ return;
+
+ webContext()->uniform2fv(location->location(), size / 2, v);
+}
+
+void WebGLRenderingContextBase::uniform2i(const WebGLUniformLocation* location, GLint x, GLint y)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform2i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform2i(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
+ return;
+
+ webContext()->uniform2iv(location->location(), v->length() / 2, v->data());
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
+ return;
+
+ webContext()->uniform2iv(location->location(), size / 2, v);
+}
+
+void WebGLRenderingContextBase::uniform3f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform3f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform3f(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
+ return;
+
+ webContext()->uniform3fv(location->location(), v->length() / 3, v->data());
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
+ return;
+
+ webContext()->uniform3fv(location->location(), size / 3, v);
+}
+
+void WebGLRenderingContextBase::uniform3i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform3i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform3i(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
+ return;
+
+ webContext()->uniform3iv(location->location(), v->length() / 3, v->data());
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
+ return;
+
+ webContext()->uniform3iv(location->location(), size / 3, v);
+}
+
+void WebGLRenderingContextBase::uniform4f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform4f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform4f(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
+ return;
+
+ webContext()->uniform4fv(location->location(), v->length() / 4, v->data());
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
+ return;
+
+ webContext()->uniform4fv(location->location(), size / 4, v);
+}
+
+void WebGLRenderingContextBase::uniform4i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z, GLint w)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform4i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform4i(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
+ return;
+
+ webContext()->uniform4iv(location->location(), v->length() / 4, v->data());
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
+ return;
+
+ webContext()->uniform4iv(location->location(), size / 4, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
+ return;
+ webContext()->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
+ return;
+ webContext()->uniformMatrix2fv(location->location(), size / 4, transpose, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
+ return;
+ webContext()->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
+ return;
+ webContext()->uniformMatrix3fv(location->location(), size / 9, transpose, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
+ return;
+ webContext()->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
+ return;
+ webContext()->uniformMatrix4fv(location->location(), size / 16, transpose, v);
+}
+
+void WebGLRenderingContextBase::useProgram(WebGLProgram* program)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("useProgram", program, deleted))
+ return;
+ if (deleted)
+ program = 0;
+ if (program && !program->linkStatus()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "useProgram", "program not valid");
+ return;
+ }
+ if (m_currentProgram != program) {
+ if (m_currentProgram)
+ m_currentProgram->onDetached(webContext());
+ m_currentProgram = program;
+ webContext()->useProgram(objectOrZero(program));
+ if (program)
+ program->onAttached();
+ }
+}
+
+void WebGLRenderingContextBase::validateProgram(WebGLProgram* program)
+{
+ if (isContextLost() || !validateWebGLObject("validateProgram", program))
+ return;
+ webContext()->validateProgram(objectOrZero(program));
+}
+
+void WebGLRenderingContextBase::vertexAttrib1f(GLuint index, GLfloat v0)
+{
+ vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1)
+{
+ vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
+}
+
+void WebGLRenderingContextBase::vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, long long offset)
+{
+ if (isContextLost())
+ return;
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_FLOAT:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "index out of range");
+ return;
+ }
+ if (size < 1 || size > 4 || stride < 0 || stride > 255) {
+ synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "bad size or stride");
+ return;
+ }
+ if (!validateValueFitNonNegInt32("vertexAttribPointer", "offset", offset))
+ return;
+ if (!m_boundArrayBuffer) {
+ synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
+ return;
+ }
+ // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
+ unsigned typeSize = sizeInBytes(type);
+ if (!typeSize) {
+ synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if ((stride % typeSize) || (static_cast<GLintptr>(offset) % typeSize)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
+ return;
+ }
+ GLsizei bytesPerElement = size * typeSize;
+
+ m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GLintptr>(offset), m_boundArrayBuffer);
+ webContext()->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GLintptr>(offset));
+}
+
+void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ if (isContextLost())
+ return;
+
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index out of range");
+ return;
+ }
+
+ m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
+ webContext()->vertexAttribDivisorANGLE(index, divisor);
+}
+
+void WebGLRenderingContextBase::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize("viewport", width, height))
+ return;
+ webContext()->viewport(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::forceLostContext(WebGLRenderingContextBase::LostContextMode mode)
+{
+ if (isContextLost()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
+ return;
+ }
+
+ m_contextGroup->loseContextGroup(mode);
+}
+
+void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostContextMode mode)
+{
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): begin");
+#endif
+
+ if (isContextLost())
+ return;
+
+ m_contextLost = true;
+ m_contextLostMode = mode;
+
+ if (mode == RealLostContext) {
+ // Inform the embedder that a lost context was received. In response, the embedder might
+ // decide to take action such as asking the user for permission to use WebGL again.
+ if (LocalFrame* frame = canvas()->document().frame())
+ frame->loader().client()->didLoseWebGLContext(webContext()->getGraphicsResetStatusARB());
+ }
+
+ // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
+ m_drawingBuffer->setTexture2DBinding(0);
+ m_drawingBuffer->setFramebufferBinding(0);
+
+ detachAndRemoveAllObjects();
+
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): after detachAndRemoveAllObjects()");
+#endif
+
+ // Lose all the extensions.
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ ExtensionTracker* tracker = m_extensions[i];
+ tracker->loseExtension();
+ }
+
+ for (size_t i = 0; i < WebGLExtensionNameCount; ++i)
+ m_extensionEnabled[i] = false;
+
+ removeAllCompressedTextureFormats();
+
+ if (mode != RealLostContext)
+ destroyContext();
+
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): after destroyContext()");
+#endif
+
+ ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
+ synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
+
+ // Don't allow restoration unless the context lost event has both been
+ // dispatched and its default behavior prevented.
+ m_restoreAllowed = false;
+
+ // Always defer the dispatch of the context lost event, to implement
+ // the spec behavior of queueing a task.
+ m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE);
+
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): end");
+#endif
+}
+
+void WebGLRenderingContextBase::forceRestoreContext()
+{
+ if (!isContextLost()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not lost");
+ return;
+ }
+
+ if (!m_restoreAllowed) {
+ if (m_contextLostMode == SyntheticLostContext)
+ synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context restoration not allowed");
+ return;
+ }
+
+ if (!m_restoreTimer.isActive())
+ m_restoreTimer.startOneShot(0, FROM_HERE);
+}
+
+blink::WebLayer* WebGLRenderingContextBase::platformLayer() const
+{
+ return isContextLost() ? 0 : m_drawingBuffer->platformLayer();
+}
+
+Extensions3DUtil* WebGLRenderingContextBase::extensionsUtil()
+{
+ ASSERT(!isContextLost());
+ if (!m_extensionsUtil)
+ m_extensionsUtil = Extensions3DUtil::create(webContext());
+ return m_extensionsUtil.get();
+}
+
+void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject* object)
+{
+ m_contextGroup->removeObject(object);
+}
+
+void WebGLRenderingContextBase::addSharedObject(WebGLSharedObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextGroup->addObject(object);
+}
+
+void WebGLRenderingContextBase::removeContextObject(WebGLContextObject* object)
+{
+ m_contextObjects.remove(object);
+}
+
+void WebGLRenderingContextBase::addContextObject(WebGLContextObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextObjects.add(object);
+}
+
+void WebGLRenderingContextBase::detachAndRemoveAllObjects()
+{
+ while (m_contextObjects.size() > 0) {
+ HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
+ (*it)->detachContext();
+ }
+}
+
+bool WebGLRenderingContextBase::hasPendingActivity() const
+{
+ return false;
+}
+
+void WebGLRenderingContextBase::stop()
+{
+ if (!isContextLost()) {
+ forceLostContext(SyntheticLostContext);
+ destroyContext();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBooleanParameter(GLenum pname)
+{
+ GLboolean value = 0;
+ if (!isContextLost())
+ webContext()->getBooleanv(pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBooleanArrayParameter(GLenum pname)
+{
+ if (pname != GL_COLOR_WRITEMASK) {
+ notImplemented();
+ return WebGLGetInfo(0, 0);
+ }
+ GLboolean value[4] = {0};
+ if (!isContextLost())
+ webContext()->getBooleanv(pname, value);
+ bool boolValue[4];
+ for (int ii = 0; ii < 4; ++ii)
+ boolValue[ii] = static_cast<bool>(value[ii]);
+ return WebGLGetInfo(boolValue, 4);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getFloatParameter(GLenum pname)
+{
+ GLfloat value = 0;
+ if (!isContextLost())
+ webContext()->getFloatv(pname, &value);
+ return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getIntParameter(GLenum pname)
+{
+ GLint value = 0;
+ if (!isContextLost())
+ webContext()->getIntegerv(pname, &value);
+ return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getUnsignedIntParameter(GLenum pname)
+{
+ GLint value = 0;
+ if (!isContextLost())
+ webContext()->getIntegerv(pname, &value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getWebGLFloatArrayParameter(GLenum pname)
+{
+ GLfloat value[4] = {0};
+ if (!isContextLost())
+ webContext()->getFloatv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_DEPTH_RANGE:
+ length = 2;
+ break;
+ case GL_BLEND_COLOR:
+ case GL_COLOR_CLEAR_VALUE:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return WebGLGetInfo(Float32Array::create(value, length));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getWebGLIntArrayParameter(GLenum pname)
+{
+ GLint value[4] = {0};
+ if (!isContextLost())
+ webContext()->getIntegerv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GL_MAX_VIEWPORT_DIMS:
+ length = 2;
+ break;
+ case GL_SCISSOR_BOX:
+ case GL_VIEWPORT:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return WebGLGetInfo(Int32Array::create(value, length));
+}
+
+void WebGLRenderingContextBase::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ bool resetActiveUnit = false;
+ WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((extensionEnabled(OESTextureFloatLinearName) ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
+ | (extensionEnabled(OESTextureHalfFloatLinearName) ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
+ for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) {
+ if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
+ || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
+ if (ii != m_activeTextureUnit) {
+ webContext()->activeTexture(ii);
+ resetActiveUnit = true;
+ } else if (resetActiveUnit) {
+ webContext()->activeTexture(ii);
+ resetActiveUnit = false;
+ }
+ WebGLTexture* tex2D;
+ WebGLTexture* texCubeMap;
+ if (prepareToDraw) {
+ String msg(String("texture bound to texture unit ") + String::number(ii)
+ + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
+ + " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
+ emitGLWarning(functionName, msg.utf8().data());
+ 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(flag))
+ webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D));
+ if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
+ webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+ }
+ }
+ if (resetActiveUnit)
+ webContext()->activeTexture(m_activeTextureUnit);
+}
+
+void WebGLRenderingContextBase::createFallbackBlackTextures1x1()
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ unsigned char black[] = {0, 0, 0, 255};
+ m_blackTexture2D = createTexture();
+ webContext()->bindTexture(GL_TEXTURE_2D, m_blackTexture2D->object());
+ webContext()->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->bindTexture(GL_TEXTURE_2D, 0);
+ m_blackTextureCubeMap = createTexture();
+ webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+bool WebGLRenderingContextBase::isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat)
+{
+ unsigned need = WebGLImageConversion::getChannelBitsByFormat(texInternalFormat);
+ unsigned have = WebGLImageConversion::getChannelBitsByFormat(colorBufferFormat);
+ return (need & have) == need;
+}
+
+GLenum WebGLRenderingContextBase::boundFramebufferColorFormat()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->colorBufferFormat();
+ if (m_requestedAttributes->alpha())
+ return GL_RGBA;
+ return GL_RGB;
+}
+
+WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap)
+{
+ WebGLTexture* tex = 0;
+ switch (target) {
+ case GL_TEXTURE_2D:
+ tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get();
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (!useSixEnumsForCubeMap) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ if (useSixEnumsForCubeMap) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+ return 0;
+ }
+ if (!tex)
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture");
+ return tex;
+}
+
+bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string)
+{
+ const unsigned maxWebGLLocationLength = 256;
+ if (string.length() > maxWebGLLocationLength) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateSize(const char* functionName, GLint x, GLint y)
+{
+ if (x < 0 || y < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateString(const char* functionName, const String& string)
+{
+ for (size_t i = 0; i < string.length(); ++i) {
+ if (!validateCharacter(string[i])) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "string not ASCII");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level)
+{
+ switch (format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ case GL_DEPTH_COMPONENT:
+ if (extensionEnabled(WebGLDepthTextureName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "depth texture formats not enabled");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture format");
+ return false;
+ }
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ break;
+ case GL_FLOAT:
+ if (extensionEnabled(OESTextureFloatName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GL_HALF_FLOAT_OES:
+ if (extensionEnabled(OESTextureHalfFloatName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_24_8_OES:
+ case GL_UNSIGNED_SHORT:
+ if (extensionEnabled(WebGLDepthTextureName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+
+ // Verify that the combination of format and type is supported.
+ switch (format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_FLOAT
+ && type != GL_HALF_FLOAT_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for format");
+ return false;
+ }
+ break;
+ case GL_RGB:
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_UNSIGNED_SHORT_5_6_5
+ && type != GL_FLOAT
+ && type != GL_HALF_FLOAT_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGB format");
+ return false;
+ }
+ break;
+ case GL_RGBA:
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_UNSIGNED_SHORT_4_4_4_4
+ && type != GL_UNSIGNED_SHORT_5_5_5_1
+ && type != GL_FLOAT
+ && type != GL_HALF_FLOAT_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGBA format");
+ return false;
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ if (!extensionEnabled(WebGLDepthTextureName)) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
+ return false;
+ }
+ if (type != GL_UNSIGNED_SHORT
+ && type != GL_UNSIGNED_INT) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
+ return false;
+ }
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ if (!extensionEnabled(WebGLDepthTextureName)) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
+ return false;
+ }
+ if (type != GL_UNSIGNED_INT_24_8_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GLenum target, GLint level)
+{
+ if (level < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level < 0");
+ return false;
+ }
+ switch (target) {
+ case GL_TEXTURE_2D:
+ if (level >= m_maxTextureLevel) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (level >= m_maxCubeMapTextureLevel) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ }
+ // This function only checks if level is legal, so we return true and don't
+ // generate INVALID_ENUM if target is illegal.
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
+ GLenum target, GLint level, GLsizei width, GLsizei height)
+{
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ switch (target) {
+ case GL_TEXTURE_2D:
+ if (width > (m_maxTextureSize >> level) || height > (m_maxTextureSize >> level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range");
+ return false;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (functionType != TexSubImage2D && width != height) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ // No need to check height here. For texImage width == height.
+ // For texSubImage that will be checked when checking yoffset + height is in range.
+ if (width > (m_maxCubeMapTextureSize >> level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range for cube map");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target,
+ GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
+{
+ // We absolutely have to validate the format and type combination.
+ // The texImage2D entry points taking HTMLImage, etc. will produce
+ // temporary data based on this combination, so it must be legal.
+ if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+ return false;
+
+ if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
+ return false;
+
+ if (format != internalformat) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "format != internalformat");
+ return false;
+ }
+
+ if (border) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "border != 0");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition disposition)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ if (!pixels) {
+ if (disposition == NullAllowed)
+ return true;
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+
+ if (!validateTexFuncFormatAndType(functionName, format, type, level))
+ return false;
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (pixels->type() != ArrayBufferView::TypeUint8) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
+ return false;
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ if (pixels->type() != ArrayBufferView::TypeUint16) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
+ return false;
+ }
+ break;
+ case GL_FLOAT: // OES_texture_float
+ if (pixels->type() != ArrayBufferView::TypeFloat32) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
+ return false;
+ }
+ break;
+ case GL_HALF_FLOAT_OES: // OES_texture_half_float
+ // As per the specification, ArrayBufferView should be null or a Uint16Array when
+ // OES_texture_half_float is enabled.
+ if (pixels && pixels->type() != ArrayBufferView::TypeUint16) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL and not Uint16Array");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ unsigned totalBytesRequired;
+ GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+ if (error != GL_NO_ERROR) {
+ synthesizeGLError(error, functionName, "invalid texture dimensions");
+ return false;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ if (m_unpackAlignment != 1) {
+ error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
+ if (pixels->byteLength() == totalBytesRequired) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
+ return false;
+ }
+ }
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFormat(GLenum format)
+{
+ return m_compressedTextureFormats.contains(format);
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels)
+{
+ if (!pixels) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ unsigned bytesRequired = 0;
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ const int kBlockSize = 8;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ int numBlocks = numBlocksAcross * numBlocksDown;
+ bytesRequired = numBlocks * kBlockSize;
+ }
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ const int kBlockSize = 16;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ int numBlocks = numBlocksAcross * numBlocksDown;
+ bytesRequired = numBlocks * kBlockSize;
+ }
+ break;
+ case GC3D_COMPRESSED_ATC_RGB_AMD:
+ case GL_ETC1_RGB8_OES:
+ {
+ bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 8;
+ }
+ break;
+ case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ {
+ bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 16;
+ }
+ break;
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ bytesRequired = (max(width, 8) * max(height, 8) * 4 + 7) / 8;
+ }
+ break;
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ {
+ bytesRequired = (max(width, 16) * max(height, 8) * 2 + 7) / 8;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format");
+ return false;
+ }
+
+ if (pixels->byteLength() != bytesRequired) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
+{
+ if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
+ return false;
+
+ bool widthValid = false;
+ bool heightValid = false;
+
+ switch (format) {
+ case GC3D_COMPRESSED_ATC_RGB_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
+ heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
+ break;
+ }
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
+ // Must be a power of two
+ widthValid = (width & (width - 1)) == 0;
+ heightValid = (height & (height - 1)) == 0;
+ break;
+ }
+ case GL_ETC1_RGB8_OES: {
+ widthValid = true;
+ heightValid = true;
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (!widthValid || !heightValid) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture* tex)
+{
+ if (xoffset < 0 || yoffset < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "xoffset or yoffset < 0");
+ return false;
+ }
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
+ return false;
+ }
+ if (width - xoffset > tex->getWidth(target, level)
+ || height - yoffset > tex->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+ }
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
+ if ((xoffset != 0) || (yoffset != 0)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset and yoffset must be zero");
+ return false;
+ }
+ if (width != tex->getWidth(target, level)
+ || height != tex->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions must match existing level");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+ }
+ case GC3D_COMPRESSED_ATC_RGB_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ case GL_ETC1_RGB8_OES: {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "unable to update sub-images with this format");
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateDrawMode(const char* functionName, GLenum mode)
+{
+ switch (mode) {
+ case GL_POINTS:
+ case GL_LINE_STRIP:
+ case GL_LINE_LOOP:
+ case GL_LINES:
+ case GL_TRIANGLE_STRIP:
+ case GL_TRIANGLE_FAN:
+ case GL_TRIANGLES:
+ return true;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid draw mode");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateStencilSettings(const char* functionName)
+{
+ if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "front and back stencils settings do not match");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateStencilOrDepthFunc(const char* functionName, GLenum func)
+{
+ switch (func) {
+ case GL_NEVER:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ return true;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid function");
+ return false;
+ }
+}
+
+void WebGLRenderingContextBase::printGLErrorToConsole(const String& message)
+{
+ if (!m_numGLErrorsToConsoleAllowed)
+ return;
+
+ --m_numGLErrorsToConsoleAllowed;
+ printWarningToConsole(message);
+
+ if (!m_numGLErrorsToConsoleAllowed)
+ printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
+
+ return;
+}
+
+void WebGLRenderingContextBase::printWarningToConsole(const String& message)
+{
+ if (!canvas())
+ return;
+ canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
+}
+
+bool WebGLRenderingContextBase::validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment)
+{
+ if (target != GL_FRAMEBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+ switch (attachment) {
+ case GL_COLOR_ATTACHMENT0:
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+ break;
+ default:
+ if (extensionEnabled(WebGLDrawBuffersName)
+ && attachment > GL_COLOR_ATTACHMENT0
+ && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateBlendEquation(const char* functionName, GLenum mode)
+{
+ switch (mode) {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ return true;
+ case GL_MIN_EXT:
+ case GL_MAX_EXT:
+ if (extensionEnabled(EXTBlendMinMaxName))
+ return true;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst)
+{
+ if (((src == GL_CONSTANT_COLOR || src == GL_ONE_MINUS_CONSTANT_COLOR)
+ && (dst == GL_CONSTANT_ALPHA || dst == GL_ONE_MINUS_CONSTANT_ALPHA))
+ || ((dst == GL_CONSTANT_COLOR || dst == GL_ONE_MINUS_CONSTANT_COLOR)
+ && (src == GL_CONSTANT_ALPHA || src == GL_ONE_MINUS_CONSTANT_ALPHA))) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "incompatible src and dst");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCapability(const char* functionName, GLenum cap)
+{
+ switch (cap) {
+ case GL_BLEND:
+ case GL_CULL_FACE:
+ case GL_DEPTH_TEST:
+ case GL_DITHER:
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ case GL_SAMPLE_COVERAGE:
+ case GL_SCISSOR_TEST:
+ case GL_STENCIL_TEST:
+ return true;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid capability");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GLsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GLsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GLsizei size, GLsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v, GLsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, void* v, GLsizei size, GLsizei requiredMinSize)
+{
+ if (!location)
+ return false;
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "location is not from current program");
+ return false;
+ }
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ if (transpose) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "transpose not FALSE");
+ return false;
+ }
+ if (size < requiredMinSize || (size % requiredMinSize)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
+ return false;
+ }
+ return true;
+}
+
+WebGLBuffer* WebGLRenderingContextBase::validateBufferDataTarget(const char* functionName, GLenum target)
+{
+ WebGLBuffer* buffer = 0;
+ switch (target) {
+ case GL_ELEMENT_ARRAY_BUFFER:
+ buffer = m_boundVertexArrayObject->boundElementArrayBuffer().get();
+ break;
+ case GL_ARRAY_BUFFER:
+ buffer = m_boundArrayBuffer.get();
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+ return 0;
+ }
+ if (!buffer) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
+ return 0;
+ }
+ return buffer;
+}
+
+bool WebGLRenderingContextBase::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ if (!image || !image->cachedImage()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no image");
+ return false;
+ }
+ const KURL& url = image->cachedImage()->response().url();
+ if (url.isNull() || url.isEmpty() || !url.isValid()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid image");
+ return false;
+ }
+
+ if (wouldTaintOrigin(image)) {
+ exceptionState.throwSecurityError("The cross-origin image at " + url.elidedString() + " may not be loaded.");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ if (!canvas || !canvas->buffer()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no canvas");
+ return false;
+ }
+ if (wouldTaintOrigin(canvas)) {
+ exceptionState.throwSecurityError("Tainted canvases may not be loaded.");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no video");
+ return false;
+ }
+
+ if (wouldTaintOrigin(video)) {
+ exceptionState.throwSecurityError("The video element contains cross-origin data, and may not be loaded.");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count)
+{
+ if (isContextLost() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ if (first < 0 || count < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "first or count < 0");
+ return false;
+ }
+
+ if (!count) {
+ markContextChanged(CanvasChanged);
+ return false;
+ }
+
+ if (!validateRenderingState(functionName)) {
+ return false;
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset)
+{
+ if (isContextLost() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT:
+ break;
+ case GL_UNSIGNED_INT:
+ if (extensionEnabled(OESElementIndexUintName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
+ return false;
+ }
+
+ if (count < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "count < 0");
+ return false;
+ }
+ if (!validateValueFitNonNegInt32(functionName, "offset", offset))
+ return false;
+
+ if (!count) {
+ markContextChanged(CanvasChanged);
+ return false;
+ }
+
+ if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
+ return false;
+ }
+
+ if (!validateRenderingState(functionName)) {
+ return false;
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+// Helper function to validate draw*Instanced calls
+bool WebGLRenderingContextBase::validateDrawInstanced(const char* functionName, GLsizei primcount)
+{
+ if (primcount < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "primcount < 0");
+ return false;
+ }
+
+ // Ensure at least one enabled vertex attrib has a divisor of 0.
+ for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+ if (state.enabled && !state.divisor)
+ return true;
+ }
+
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "at least one enabled attribute must have a divisor of 0");
+ return false;
+}
+
+void WebGLRenderingContextBase::vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ switch (expectedSize) {
+ case 1:
+ webContext()->vertexAttrib1f(index, v0);
+ break;
+ case 2:
+ webContext()->vertexAttrib2f(index, v0, v1);
+ break;
+ case 3:
+ webContext()->vertexAttrib3f(index, v0, v1, v2);
+ break;
+ case 4:
+ webContext()->vertexAttrib4f(index, v0, v1, v2, v3);
+ break;
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.value[0] = v0;
+ attribValue.value[1] = v1;
+ attribValue.value[2] = v2;
+ attribValue.value[3] = v3;
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array* v, GLsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return;
+ }
+ vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat* v, GLsizei size, GLsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return;
+ }
+ if (size < expectedSize) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ switch (expectedSize) {
+ case 1:
+ webContext()->vertexAttrib1fv(index, v);
+ break;
+ case 2:
+ webContext()->vertexAttrib2fv(index, v);
+ break;
+ case 3:
+ webContext()->vertexAttrib3fv(index, v);
+ break;
+ case 4:
+ webContext()->vertexAttrib4fv(index, v);
+ break;
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.initValue();
+ for (int ii = 0; ii < expectedSize; ++ii)
+ attribValue.value[ii] = v[ii];
+}
+
+void WebGLRenderingContextBase::dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*)
+{
+ RefPtrWillBeRawPtr<WebGLContextEvent> event = WebGLContextEvent::create(EventTypeNames::webglcontextlost, false, true, "");
+ canvas()->dispatchEvent(event);
+ m_restoreAllowed = event->defaultPrevented();
+ deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAllowed);
+ if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecoverSyntheticLostContext) && m_restoreAllowed)
+ m_restoreTimer.startOneShot(0, FROM_HERE);
+}
+
+void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextBase>*)
+{
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): begin");
+#endif
+ ASSERT(isContextLost());
+
+ // The rendering context is not restored unless the default behavior of the
+ // webglcontextlost event was prevented earlier.
+ //
+ // Because of the way m_restoreTimer is set up for real vs. synthetic lost
+ // context events, we don't have to worry about this test short-circuiting
+ // the retry loop for real context lost events.
+ if (!m_restoreAllowed)
+ return;
+
+ LocalFrame* frame = canvas()->document().frame();
+ if (!frame)
+ return;
+
+ Settings* settings = frame->settings();
+
+ if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled()))
+ return;
+
+ // If the context was lost due to RealLostContext, we need to destroy the old DrawingBuffer before creating new DrawingBuffer to ensure resource budget enough.
+ if (m_drawingBuffer) {
+ m_drawingBuffer->beginDestruction();
+ m_drawingBuffer.clear();
+ }
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): destroyed old DrawingBuffer");
+#endif
+
+ blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument().url().string(), settings);
+ OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes, 0));
+ RefPtr<DrawingBuffer> drawingBuffer;
+ // Even if a non-null WebGraphicsContext3D is created, until it's made current, it isn't known whether the context is still lost.
+ if (context) {
+ // Construct a new drawing buffer with the new WebGraphicsContext3D.
+ drawingBuffer = createDrawingBuffer(context.release());
+ // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is set to null.
+ }
+ if (!drawingBuffer) {
+ if (m_contextLostMode == RealLostContext) {
+ m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE);
+ } else {
+ // This likely shouldn't happen but is the best way to report it to the WebGL app.
+ synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context");
+ }
+ return;
+ }
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): created new DrawingBuffer");
+#endif
+
+ m_drawingBuffer = drawingBuffer.release();
+ m_drawingBuffer->bind();
+ m_lostContextErrors.clear();
+ m_contextLost = false;
+
+ setupFlags();
+ initializeNewContext();
+ markContextChanged(CanvasContextChanged);
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): before dispatchEvent");
+#endif
+ canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextrestored, false, true, ""));
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): end");
+#endif
+}
+
+String WebGLRenderingContextBase::ensureNotNull(const String& text) const
+{
+ if (text.isNull())
+ return WTF::emptyString();
+ return text;
+}
+
+WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity]))
+ , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+ int i;
+ for (i = 0; i < m_capacity; ++i) {
+ ImageBuffer* buf = m_buffers[i].get();
+ if (!buf)
+ break;
+ if (buf->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 WebGLRenderingContextBase::LRUImageBufferCache::bubbleToFront(int idx)
+{
+ for (int i = idx; i > 0; --i)
+ m_buffers[i].swap(m_buffers[i-1]);
+}
+
+namespace {
+
+ String GetErrorString(GLenum error)
+ {
+ switch (error) {
+ case GL_INVALID_ENUM:
+ return "INVALID_ENUM";
+ case GL_INVALID_VALUE:
+ return "INVALID_VALUE";
+ case GL_INVALID_OPERATION:
+ return "INVALID_OPERATION";
+ case GL_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "INVALID_FRAMEBUFFER_OPERATION";
+ case GC3D_CONTEXT_LOST_WEBGL:
+ return "CONTEXT_LOST_WEBGL";
+ default:
+ return String::format("WebGL ERROR(0x%04X)", error);
+ }
+ }
+
+} // namespace anonymous
+
+void WebGLRenderingContextBase::synthesizeGLError(GLenum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
+{
+ String errorType = GetErrorString(error);
+ if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
+ String message = String("WebGL: ") + errorType + ": " + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(message);
+ }
+ if (!isContextLost())
+ webContext()->synthesizeGLError(error);
+ else {
+ if (m_lostContextErrors.find(error) == WTF::kNotFound)
+ m_lostContextErrors.append(error);
+ }
+ InspectorInstrumentation::didFireWebGLError(canvas(), errorType);
+}
+
+void WebGLRenderingContextBase::emitGLWarning(const char* functionName, const char* description)
+{
+ if (m_synthesizedErrorsToConsole) {
+ String message = String("WebGL: ") + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(message);
+ }
+ InspectorInstrumentation::didFireWebGLWarning(canvas());
+}
+
+void WebGLRenderingContextBase::applyStencilTest()
+{
+ bool haveStencilBuffer = false;
+
+ if (m_framebufferBinding)
+ haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
+ else {
+ RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
+ haveStencilBuffer = attributes->stencil();
+ }
+ enableOrDisable(GL_STENCIL_TEST,
+ m_stencilEnabled && haveStencilBuffer);
+}
+
+void WebGLRenderingContextBase::enableOrDisable(GLenum capability, bool enable)
+{
+ if (isContextLost())
+ return;
+ if (enable)
+ webContext()->enable(capability);
+ else
+ webContext()->disable(capability);
+}
+
+IntSize WebGLRenderingContextBase::clampedCanvasSize()
+{
+ return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
+ clamp(canvas()->height(), 1, m_maxViewportDims[1]));
+}
+
+GLint WebGLRenderingContextBase::maxDrawBuffers()
+{
+ if (isContextLost() || !extensionEnabled(WebGLDrawBuffersName))
+ return 0;
+ if (!m_maxDrawBuffers)
+ webContext()->getIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
+ if (!m_maxColorAttachments)
+ webContext()->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
+ return std::min(m_maxDrawBuffers, m_maxColorAttachments);
+}
+
+GLint WebGLRenderingContextBase::maxColorAttachments()
+{
+ if (isContextLost() || !extensionEnabled(WebGLDrawBuffersName))
+ return 0;
+ if (!m_maxColorAttachments)
+ webContext()->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ return m_maxColorAttachments;
+}
+
+void WebGLRenderingContextBase::setBackDrawBuffer(GLenum buf)
+{
+ m_backDrawBuffer = buf;
+}
+
+void WebGLRenderingContextBase::restoreCurrentFramebuffer()
+{
+ bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
+}
+
+void WebGLRenderingContextBase::restoreCurrentTexture2D()
+{
+ bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
+}
+
+void WebGLRenderingContextBase::multisamplingChanged(bool enabled)
+{
+ if (m_multisamplingAllowed != enabled) {
+ m_multisamplingAllowed = enabled;
+ forceLostContext(WebGLRenderingContextBase::AutoRecoverSyntheticLostContext);
+ }
+}
+
+void WebGLRenderingContextBase::findNewMaxEnabledAttribIndex()
+{
+ // Trace backwards from the current max to find the new max enabled attrib index
+ int startIndex = m_onePlusMaxEnabledAttribIndex - 1;
+ for (int i = startIndex; i >= 0; --i) {
+ if (m_boundVertexArrayObject->getVertexAttribState(i).enabled) {
+ m_onePlusMaxEnabledAttribIndex = i + 1;
+ return;
+ }
+ }
+ m_onePlusMaxEnabledAttribIndex = 0;
+}
+
+void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit()
+{
+ // Trace backwards from the current max to find the new max non-default texture unit
+ int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1;
+ for (int i = startIndex; i >= 0; --i) {
+ if (m_textureUnits[i].m_texture2DBinding
+ || m_textureUnits[i].m_textureCubeMapBinding) {
+ m_onePlusMaxNonDefaultTextureUnit = i + 1;
+ return;
+ }
+ }
+ m_onePlusMaxNonDefaultTextureUnit = 0;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
new file mode 100644
index 00000000000..ca08a621efc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
@@ -0,0 +1,914 @@
+/*
+ * 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 WebGLRenderingContextBase_h
+#define WebGLRenderingContextBase_h
+
+#include "core/dom/ActiveDOMObject.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/html/canvas/WebGLExtensionName.h"
+#include "core/html/canvas/WebGLGetInfo.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderBoxModelObject.h"
+#include "platform/Timer.h"
+#include "platform/graphics/GraphicsTypes3D.h"
+#include "platform/graphics/ImageBuffer.h"
+#include "platform/graphics/gpu/DrawingBuffer.h"
+#include "platform/graphics/gpu/Extensions3DUtil.h"
+#include "platform/graphics/gpu/WebGLImageConversion.h"
+#include "public/platform/WebGraphicsContext3D.h"
+#include "wtf/Float32Array.h"
+#include "wtf/Int32Array.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+class WebLayer;
+}
+
+namespace WebCore {
+
+class ANGLEInstancedArrays;
+class EXTBlendMinMax;
+class EXTFragDepth;
+class EXTShaderTextureLOD;
+class EXTTextureFilterAnisotropic;
+class ExceptionState;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageBuffer;
+class ImageData;
+class IntSize;
+class OESElementIndexUint;
+class OESStandardDerivatives;
+class OESTextureFloat;
+class OESTextureFloatLinear;
+class OESTextureHalfFloat;
+class OESTextureHalfFloatLinear;
+class OESVertexArrayObject;
+class WebGLActiveInfo;
+class WebGLBuffer;
+class WebGLCompressedTextureATC;
+class WebGLCompressedTextureETC1;
+class WebGLCompressedTexturePVRTC;
+class WebGLCompressedTextureS3TC;
+class WebGLContextAttributes;
+class WebGLContextGroup;
+class WebGLContextObject;
+class WebGLDebugRendererInfo;
+class WebGLDebugShaders;
+class WebGLDepthTexture;
+class WebGLDrawBuffers;
+class WebGLExtension;
+class WebGLFramebuffer;
+class WebGLLoseContext;
+class WebGLObject;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLShader;
+class WebGLShaderPrecisionFormat;
+class WebGLSharedObject;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebGLVertexArrayObjectOES;
+
+class WebGLRenderingContextLostCallback;
+class WebGLRenderingContextErrorMessageCallback;
+
+class WebGLRenderingContextBase: public CanvasRenderingContext, public ActiveDOMObject, public Page::MultisamplingChangedObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WebGLRenderingContextBase);
+public:
+ virtual ~WebGLRenderingContextBase();
+
+ virtual bool is3d() const OVERRIDE { return true; }
+ virtual bool isAccelerated() const OVERRIDE { return true; }
+ virtual unsigned version() const = 0;
+ virtual String contextName() const = 0;
+ virtual void registerContextExtensions() = 0;
+
+ static unsigned getWebGLVersion(const CanvasRenderingContext*);
+
+ int drawingBufferWidth() const;
+ int drawingBufferHeight() const;
+
+ void activeTexture(GLenum texture);
+ void attachShader(WebGLProgram*, WebGLShader*);
+ void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
+ void bindBuffer(GLenum target, WebGLBuffer*);
+ void bindFramebuffer(GLenum target, WebGLFramebuffer*);
+ void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
+ void bindTexture(GLenum target, WebGLTexture*);
+ void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void blendEquation(GLenum mode);
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void blendFunc(GLenum sfactor, GLenum dfactor);
+ void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+ void bufferData(GLenum target, long long size, GLenum usage);
+ void bufferData(GLenum target, ArrayBuffer* data, GLenum usage);
+ void bufferData(GLenum target, ArrayBufferView* data, GLenum usage);
+ void bufferSubData(GLenum target, long long offset, ArrayBuffer* data);
+ void bufferSubData(GLenum target, long long offset, ArrayBufferView* data);
+
+ GLenum checkFramebufferStatus(GLenum target);
+ void clear(GLbitfield mask);
+ void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void clearDepth(GLfloat);
+ void clearStencil(GLint);
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void compileShader(WebGLShader*);
+
+ void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data);
+ void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data);
+
+ void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+ PassRefPtr<WebGLBuffer> createBuffer();
+ PassRefPtr<WebGLFramebuffer> createFramebuffer();
+ PassRefPtr<WebGLProgram> createProgram();
+ PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
+ PassRefPtr<WebGLShader> createShader(GLenum type);
+ PassRefPtr<WebGLTexture> createTexture();
+
+ void cullFace(GLenum mode);
+
+ void deleteBuffer(WebGLBuffer*);
+ void deleteFramebuffer(WebGLFramebuffer*);
+ void deleteProgram(WebGLProgram*);
+ void deleteRenderbuffer(WebGLRenderbuffer*);
+ void deleteShader(WebGLShader*);
+ void deleteTexture(WebGLTexture*);
+
+ void depthFunc(GLenum);
+ void depthMask(GLboolean);
+ void depthRange(GLfloat zNear, GLfloat zFar);
+ void detachShader(WebGLProgram*, WebGLShader*);
+ void disable(GLenum cap);
+ void disableVertexAttribArray(GLuint index);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);
+
+ void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+ void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount);
+
+ void enable(GLenum cap);
+ void enableVertexAttribArray(GLuint index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer*);
+ void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture*, GLint level);
+ void frontFace(GLenum mode);
+ void generateMipmap(GLenum target);
+
+ PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GLuint index);
+ PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GLuint index);
+ bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
+ GLint getAttribLocation(WebGLProgram*, const String& name);
+ WebGLGetInfo getBufferParameter(GLenum target, GLenum pname);
+ PassRefPtr<WebGLContextAttributes> getContextAttributes();
+ GLenum getError();
+ PassRefPtr<WebGLExtension> getExtension(const String& name);
+ WebGLGetInfo getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+ WebGLGetInfo getParameter(GLenum pname);
+ WebGLGetInfo getProgramParameter(WebGLProgram*, GLenum pname);
+ String getProgramInfoLog(WebGLProgram*);
+ WebGLGetInfo getRenderbufferParameter(GLenum target, GLenum pname);
+ WebGLGetInfo getShaderParameter(WebGLShader*, GLenum pname);
+ String getShaderInfoLog(WebGLShader*);
+ PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType);
+ String getShaderSource(WebGLShader*);
+ Vector<String> getSupportedExtensions();
+ WebGLGetInfo getTexParameter(GLenum target, GLenum pname);
+ WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
+ PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
+ WebGLGetInfo getVertexAttrib(GLuint index, GLenum pname);
+ long long getVertexAttribOffset(GLuint index, GLenum pname);
+
+ void hint(GLenum target, GLenum mode);
+ GLboolean isBuffer(WebGLBuffer*);
+ bool isContextLost() const;
+ GLboolean isEnabled(GLenum cap);
+ GLboolean isFramebuffer(WebGLFramebuffer*);
+ GLboolean isProgram(WebGLProgram*);
+ GLboolean isRenderbuffer(WebGLRenderbuffer*);
+ GLboolean isShader(WebGLShader*);
+ GLboolean isTexture(WebGLTexture*);
+
+ void lineWidth(GLfloat);
+ void linkProgram(WebGLProgram*);
+ void pixelStorei(GLenum pname, GLint param);
+ void polygonOffset(GLfloat factor, GLfloat units);
+ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels);
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void sampleCoverage(GLfloat value, GLboolean invert);
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ void shaderSource(WebGLShader*, const String&);
+ void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMask(GLuint);
+ void stencilMaskSeparate(GLenum face, GLuint mask);
+ void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
+
+ void texParameterf(GLenum target, GLenum pname, GLfloat param);
+ void texParameteri(GLenum target, GLenum pname, GLint param);
+
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
+
+ void uniform1f(const WebGLUniformLocation*, GLfloat x);
+ void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform1fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform1i(const WebGLUniformLocation*, GLint x);
+ void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform1iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
+ void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform2fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
+ void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform2iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
+ void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform3fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
+ void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform3iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniform4f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform4fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform4i(const WebGLUniformLocation*, GLint x, GLint y, GLint z, GLint w);
+ void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform4iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+ void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+ void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+ void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+ void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+ void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+
+ void useProgram(WebGLProgram*);
+ void validateProgram(WebGLProgram*);
+
+ void vertexAttrib1f(GLuint index, GLfloat x);
+ void vertexAttrib1fv(GLuint index, Float32Array* values);
+ void vertexAttrib1fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+ void vertexAttrib2fv(GLuint index, Float32Array* values);
+ void vertexAttrib2fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+ void vertexAttrib3fv(GLuint index, Float32Array* values);
+ void vertexAttrib3fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void vertexAttrib4fv(GLuint index, Float32Array* values);
+ void vertexAttrib4fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, long long offset);
+
+ void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+ // WEBKIT_lose_context support
+ enum LostContextMode {
+ // Lost context occurred at the graphics system level.
+ RealLostContext,
+
+ // Lost context provoked by WEBKIT_lose_context.
+ SyntheticLostContext,
+
+ // A synthetic lost context that should attempt to recover automatically
+ AutoRecoverSyntheticLostContext
+ };
+ void forceLostContext(LostContextMode);
+ void forceRestoreContext();
+ void loseContextImpl(LostContextMode);
+
+ blink::WebGraphicsContext3D* webContext() const { return m_drawingBuffer->context(); }
+ WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
+ virtual blink::WebLayer* platformLayer() const OVERRIDE;
+ Extensions3DUtil* extensionsUtil();
+
+ void reshape(int width, int height);
+
+ void markLayerComposited();
+ virtual void paintRenderingResultsToCanvas() OVERRIDE;
+ PassRefPtrWillBeRawPtr<ImageData> paintRenderingResultsToImageData();
+
+ void removeSharedObject(WebGLSharedObject*);
+ void removeContextObject(WebGLContextObject*);
+
+ unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
+
+ // ActiveDOMObject notifications
+ virtual bool hasPendingActivity() const OVERRIDE;
+ virtual void stop() OVERRIDE;
+
+ void setSavingImage(bool isSaving) { m_savingImage = isSaving; }
+protected:
+ friend class WebGLDrawBuffers;
+ friend class WebGLFramebuffer;
+ friend class WebGLObject;
+ friend class OESVertexArrayObject;
+ friend class WebGLDebugShaders;
+ friend class WebGLCompressedTextureATC;
+ friend class WebGLCompressedTextureETC1;
+ friend class WebGLCompressedTexturePVRTC;
+ friend class WebGLCompressedTextureS3TC;
+ friend class WebGLRenderingContextErrorMessageCallback;
+ friend class WebGLVertexArrayObjectOES;
+ friend class ScopedTexture2DRestorer;
+
+ WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
+ PassRefPtr<DrawingBuffer> createDrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D>);
+ void initializeNewContext();
+ void setupFlags();
+
+ void addSharedObject(WebGLSharedObject*);
+ void addContextObject(WebGLContextObject*);
+ void detachAndRemoveAllObjects();
+
+ void destroyContext();
+ void markContextChanged(ContentChangeType);
+
+ // Query if the GL implementation is NPOT strict.
+ bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
+ // Query if depth_stencil buffer is supported.
+ bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
+
+ // Helper to return the size in bytes of OpenGL data types
+ // like GL_FLOAT, GL_INT, etc.
+ unsigned sizeInBytes(GLenum type);
+
+ // Check if each enabled vertex attribute is bound to a buffer.
+ bool validateRenderingState(const char*);
+
+ bool validateWebGLObject(const char*, WebGLObject*);
+
+ // Adds a compressed texture format.
+ void addCompressedTextureFormat(GLenum);
+ void removeAllCompressedTextureFormats();
+
+ PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, const char* functionName);
+
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
+
+ WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*);
+
+ // Structure for rendering to a DrawingBuffer, instead of directly
+ // to the back-buffer of m_context.
+ RefPtr<DrawingBuffer> m_drawingBuffer;
+ RefPtr<WebGLContextGroup> m_contextGroup;
+
+ // Dispatches a context lost event once it is determined that one is needed.
+ // This is used both for synthetic and real context losses. For real ones, it's
+ // likely that there's no JavaScript on the stack, but that might be dependent
+ // on how exactly the platform discovers that the context was lost. For better
+ // portability we always defer the dispatch of the event.
+ Timer<WebGLRenderingContextBase> m_dispatchContextLostEventTimer;
+ bool m_restoreAllowed;
+ Timer<WebGLRenderingContextBase> m_restoreTimer;
+
+ bool m_needsUpdate;
+ bool m_markedCanvasDirty;
+ HashSet<WebGLContextObject*> m_contextObjects;
+
+ OwnPtr<WebGLRenderingContextLostCallback> m_contextLostCallbackAdapter;
+ OwnPtr<WebGLRenderingContextErrorMessageCallback> m_errorMessageCallbackAdapter;
+
+ // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
+ RefPtr<WebGLBuffer> m_boundArrayBuffer;
+
+ RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
+ RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
+ void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
+ {
+ if (arrayObject)
+ m_boundVertexArrayObject = arrayObject;
+ else
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+ }
+
+ class VertexAttribValue {
+ public:
+ VertexAttribValue()
+ {
+ initValue();
+ }
+
+ void initValue()
+ {
+ value[0] = 0.0f;
+ value[1] = 0.0f;
+ value[2] = 0.0f;
+ value[3] = 1.0f;
+ }
+
+ GLfloat value[4];
+ };
+ Vector<VertexAttribValue> m_vertexAttribValue;
+ unsigned m_maxVertexAttribs;
+ RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
+ long m_vertexAttrib0BufferSize;
+ GLfloat m_vertexAttrib0BufferValue[4];
+ bool m_forceAttrib0BufferRefill;
+ bool m_vertexAttrib0UsedBefore;
+
+ 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;
+
+ Vector<GLenum> m_compressedTextureFormats;
+
+ // Fixed-size cache of reusable image buffers for video texImage2D calls.
+ class LRUImageBufferCache {
+ public:
+ LRUImageBufferCache(int capacity);
+ // The pointer returned is owned by the image buffer map.
+ ImageBuffer* imageBuffer(const IntSize& size);
+ private:
+ void bubbleToFront(int idx);
+ OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_generatedImageCache;
+
+ GLint m_maxTextureSize;
+ GLint m_maxCubeMapTextureSize;
+ GLint m_maxRenderbufferSize;
+ GLint m_maxViewportDims[2];
+ GLint m_maxTextureLevel;
+ GLint m_maxCubeMapTextureLevel;
+
+ GLint m_maxDrawBuffers;
+ GLint m_maxColorAttachments;
+ GLenum m_backDrawBuffer;
+ bool m_drawBuffersWebGLRequirementsChecked;
+ bool m_drawBuffersSupported;
+
+ GLint m_packAlignment;
+ GLint m_unpackAlignment;
+ bool m_unpackFlipY;
+ bool m_unpackPremultiplyAlpha;
+ GLenum m_unpackColorspaceConversion;
+ bool m_contextLost;
+ LostContextMode m_contextLostMode;
+ RefPtr<WebGLContextAttributes> m_requestedAttributes;
+
+ bool m_layerCleared;
+ GLfloat m_clearColor[4];
+ bool m_scissorEnabled;
+ GLfloat m_clearDepth;
+ GLint m_clearStencil;
+ GLboolean m_colorMask[4];
+ GLboolean m_depthMask;
+
+ bool m_stencilEnabled;
+ GLuint m_stencilMask, m_stencilMaskBack;
+ GLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
+ GLuint m_stencilFuncMask, m_stencilFuncMaskBack;
+
+ bool m_isGLES2NPOTStrict;
+ bool m_isDepthStencilSupported;
+
+ bool m_synthesizedErrorsToConsole;
+ int m_numGLErrorsToConsoleAllowed;
+
+ bool m_multisamplingAllowed;
+ bool m_multisamplingObserverRegistered;
+
+ GLuint m_onePlusMaxEnabledAttribIndex;
+ unsigned long m_onePlusMaxNonDefaultTextureUnit;
+
+ OwnPtr<Extensions3DUtil> m_extensionsUtil;
+
+ bool m_savingImage;
+
+ enum ExtensionFlags {
+ ApprovedExtension = 0x00,
+ // Extension that is behind the draft extensions runtime flag:
+ DraftExtension = 0x01,
+ // Extension that is still in draft state, but has been selectively enabled by default under a prefix. Do not use
+ // this for enabling new draft extensions; use the DraftExtension flag instead, and do not use vendor prefixes:
+ EnabledDraftExtension = 0x04,
+ };
+
+ class ExtensionTracker {
+ public:
+ ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
+ : m_draft(flags & DraftExtension)
+ , m_prefixes(prefixes)
+ {
+ }
+
+ virtual ~ExtensionTracker()
+ {
+ }
+
+ bool draft() const
+ {
+ return m_draft;
+ }
+
+ const char* const* prefixes() const;
+ bool matchesNameWithPrefixes(const String&) const;
+
+ virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContextBase*) = 0;
+ virtual bool supported(WebGLRenderingContextBase*) const = 0;
+ virtual const char* extensionName() const = 0;
+ virtual void loseExtension() = 0;
+
+ private:
+ bool m_draft;
+ const char* const* m_prefixes;
+ };
+
+ template <typename T>
+ class TypedExtensionTracker FINAL : public ExtensionTracker {
+ public:
+ TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
+ : ExtensionTracker(flags, prefixes)
+ , m_extensionField(extensionField)
+ , m_extension(nullptr)
+ {
+ }
+
+ virtual ~TypedExtensionTracker()
+ {
+ if (m_extension) {
+ m_extension->lose(true);
+ m_extension = nullptr;
+ }
+ }
+
+ virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContextBase* context) OVERRIDE
+ {
+ if (!m_extension) {
+ m_extension = T::create(context);
+ m_extensionField = m_extension;
+ }
+
+ return m_extension;
+ }
+
+ virtual bool supported(WebGLRenderingContextBase* context) const OVERRIDE
+ {
+ return T::supported(context);
+ }
+
+ virtual const char* extensionName() const OVERRIDE
+ {
+ return T::extensionName();
+ }
+
+ virtual void loseExtension() OVERRIDE
+ {
+ if (m_extension) {
+ m_extension->lose(false);
+ if (m_extension->isLost())
+ m_extension = nullptr;
+ }
+ }
+
+ private:
+ RefPtr<T>& m_extensionField;
+ // ExtensionTracker holds it's own reference to the extension to ensure
+ // that it is not deleted before this object's destructor is called
+ RefPtr<T> m_extension;
+ };
+
+ bool m_extensionEnabled[WebGLExtensionNameCount];
+ Vector<ExtensionTracker*> m_extensions;
+
+ template <typename T>
+ void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
+ {
+ m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes));
+ }
+
+ bool extensionSupportedAndAllowed(const ExtensionTracker*);
+
+ inline bool extensionEnabled(WebGLExtensionName name)
+ {
+ return m_extensionEnabled[name];
+ }
+
+ // Errors raised by synthesizeGLError() while the context is lost.
+ Vector<GLenum> m_lostContextErrors;
+
+ // Helpers for getParameter and others
+ WebGLGetInfo getBooleanParameter(GLenum);
+ WebGLGetInfo getBooleanArrayParameter(GLenum);
+ WebGLGetInfo getFloatParameter(GLenum);
+ WebGLGetInfo getIntParameter(GLenum);
+ WebGLGetInfo getUnsignedIntParameter(GLenum);
+ WebGLGetInfo getWebGLFloatArrayParameter(GLenum);
+ WebGLGetInfo getWebGLIntArrayParameter(GLenum);
+
+ // Clear the backbuffer if it was composited since the last operation.
+ // clearMask is set to the bitfield of any clear that would happen anyway at this time
+ // and the function returns true if that clear is now unnecessary.
+ bool clearIfComposited(GLbitfield clearMask = 0);
+
+ // Helper to restore state that clearing the framebuffer may destroy.
+ void restoreStateAfterClear();
+
+ // Convert texture internal format.
+ GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);
+
+ void texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState&);
+ void texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
+ void texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState&);
+ void texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
+
+ void handleTextureCompleteness(const char*, bool);
+ void createFallbackBlackTextures1x1();
+
+ // Helper function for copyTex{Sub}Image, check whether the internalformat
+ // and the color buffer format of the current bound framebuffer combination
+ // is valid.
+ bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat);
+
+ // Helper function to get the bound framebuffer's color buffer format.
+ GLenum boundFramebufferColorFormat();
+
+ // Helper function to verify limits on the length of uniform and attribute locations.
+ bool validateLocationLength(const char* functionName, const String&);
+
+ // Helper function to check if size is non-negative.
+ // Generate GL error and return false for negative inputs; otherwise, return true.
+ bool validateSize(const char* functionName, GLint x, GLint y);
+
+ // Helper function to check if all characters in the string belong to the
+ // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
+ bool validateString(const char* functionName, const String&);
+
+ // Helper function to check target and texture bound to the target.
+ // Generate GL errors and return 0 if target is invalid or texture bound is
+ // null. Otherwise, return the texture bound to the target.
+ WebGLTexture* validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap);
+
+ // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level);
+
+ // Helper function to check input level for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if level is invalid.
+ bool validateTexFuncLevel(const char* functionName, GLenum target, GLint level);
+
+ // Helper function to check if a 64-bit value is non-negative and can fit into a 32-bit integer.
+ // Generates GL error and returns false if not.
+ bool validateValueFitNonNegInt32(const char* functionName, const char* paramName, long long value);
+
+ enum TexFuncValidationFunctionType {
+ NotTexSubImage2D,
+ TexSubImage2D,
+ };
+
+ enum TexFuncValidationSourceType {
+ SourceArrayBufferView,
+ SourceImageData,
+ SourceHTMLImageElement,
+ SourceHTMLCanvasElement,
+ SourceHTMLVideoElement,
+ };
+
+ // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
+ // Otherwise, it would return quickly without doing other work.
+ bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset);
+
+ // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
+ // Generates GL error and returns false if width or height is invalid.
+ bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height);
+
+ // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
+
+ enum NullDisposition {
+ NullAllowed,
+ NullNotAllowed
+ };
+
+ // Helper function to validate that the given ArrayBufferView
+ // is of the correct type and contains enough data for the texImage call.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition);
+
+ // Helper function to validate a given texture format is settable as in
+ // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
+ // copyTexSubImage2D.
+ // Generates GL error and returns false if the format is not settable.
+ bool validateSettableTexFormat(const char* functionName, GLenum format);
+
+ // Helper function to validate compressed texture data is correct size
+ // for the given format and dimensions.
+ bool validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels);
+
+ // Helper function for validating compressed texture formats.
+ bool validateCompressedTexFormat(GLenum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture*);
+
+ // Helper function to validate mode for draw{Arrays/Elements}.
+ bool validateDrawMode(const char* functionName, GLenum);
+
+ // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+ bool validateStencilSettings(const char* functionName);
+
+ // Helper function to validate stencil or depth func.
+ bool validateStencilOrDepthFunc(const char* functionName, GLenum);
+
+ // Helper function for texParameterf and texParameteri.
+ void texParameter(GLenum target, GLenum pname, GLfloat parami, GLint paramf, bool isFloat);
+
+ // Helper function to print GL errors to console.
+ void printGLErrorToConsole(const String&);
+
+ // Helper function to print warnings to console. Currently
+ // used only to warn about use of obsolete functions.
+ void printWarningToConsole(const String&);
+
+ // Helper function to validate input parameters for framebuffer functions.
+ // Generate GL error if parameters are illegal.
+ bool validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment);
+
+ // Helper function to validate blend equation mode.
+ bool validateBlendEquation(const char* functionName, GLenum);
+
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst);
+
+ // Helper function to validate a GL capability.
+ bool validateCapability(const char* functionName, GLenum);
+
+ // Helper function to validate input parameters for uniform functions.
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GLsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GLsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GLsizei, GLsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, Float32Array*, GLsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, void*, GLsizei, GLsizei mod);
+
+ // Helper function to validate the target for bufferData.
+ // Return the current bound buffer to target, or 0 if the target is invalid.
+ WebGLBuffer* validateBufferDataTarget(const char* functionName, GLenum target);
+
+ // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
+ bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
+
+ // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
+ bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
+
+ // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
+ bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
+
+ // Helper function to validate drawArrays(Instanced) calls
+ bool validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count);
+
+ // Helper function to validate drawElements(Instanced) calls
+ bool validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset);
+
+ // Helper function to validate draw*Instanced calls
+ bool validateDrawInstanced(const char* functionName, GLsizei primcount);
+
+ // Helper functions for vertexAttribNf{v}.
+ void vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat, GLfloat, GLfloat, GLfloat);
+ void vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array*, GLsizei expectedSize);
+ void vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat*, GLsizei, GLsizei expectedSize);
+
+ // Helper functions to bufferData() and bufferSubData().
+ void bufferDataImpl(GLenum target, long long size, const void* data, GLenum usage);
+ void bufferSubDataImpl(GLenum target, long long offset, GLsizeiptr size, const void* data);
+
+ // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
+ // Return false if caller should return without further processing.
+ bool deleteObject(WebGLObject*);
+
+ // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
+ // If the object has already been deleted, set deleted to true upon return.
+ // Return false if caller should return without further processing.
+ bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
+
+ void dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*);
+ // Helper for restoration after context lost.
+ void maybeRestoreContext(Timer<WebGLRenderingContextBase>*);
+
+ enum ConsoleDisplayPreference {
+ DisplayInConsole,
+ DontDisplayInConsole
+ };
+
+ // Wrapper for WebGraphicsContext3D::synthesizeGLError that sends a message
+ // to the JavaScript console.
+ void synthesizeGLError(GLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
+ void emitGLWarning(const char* function, const char* reason);
+
+ String ensureNotNull(const String&) const;
+
+ // Enable or disable stencil test based on user setting and
+ // whether the current FBO has a stencil buffer.
+ void applyStencilTest();
+
+ // Helper for enabling or disabling a capability.
+ void enableOrDisable(GLenum capability, bool enable);
+
+ // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
+ IntSize clampedCanvasSize();
+
+ // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
+ // Later, return the cached value.
+ GLint maxDrawBuffers();
+ GLint maxColorAttachments();
+
+ void setBackDrawBuffer(GLenum);
+
+ void restoreCurrentFramebuffer();
+ void restoreCurrentTexture2D();
+
+ virtual void multisamplingChanged(bool) OVERRIDE;
+
+ void findNewMaxEnabledAttribIndex();
+ void findNewMaxNonDefaultTextureUnit();
+
+ friend class WebGLStateRestorer;
+ friend class WebGLRenderingContextEvictionManager;
+
+ static Vector<WebGLRenderingContextBase*>& activeContexts();
+ static Vector<WebGLRenderingContextBase*>& forciblyEvictedContexts();
+
+ static void activateContext(WebGLRenderingContextBase*);
+ static void deactivateContext(WebGLRenderingContextBase*, bool addToInactiveList);
+ static void willDestroyContext(WebGLRenderingContextBase*);
+ static void forciblyLoseOldestContext(const String& reason);
+ // Return the least recently used context's position in the active context vector.
+ // If the vector is empty, return the maximum allowed active context number.
+ static size_t oldestContextIndex();
+ static IntSize oldestContextSize();
+};
+
+DEFINE_TYPE_CASTS(WebGLRenderingContextBase, CanvasRenderingContext, context, context->is3d(), context.is3d());
+
+} // namespace WebCore
+
+#endif // WebGLRenderingContextBase_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl
new file mode 100644
index 00000000000..4f0de43de88
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl
@@ -0,0 +1,689 @@
+/*
+ * 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.
+ */
+
+// http://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContextBase
+
+typedef unsigned long GLenum;
+typedef boolean GLboolean;
+typedef unsigned long GLbitfield;
+typedef byte GLbyte; // 'byte' should be a signed 8 bit type.
+typedef short GLshort;
+typedef long GLint;
+typedef long GLsizei;
+typedef long long GLintptr;
+typedef long long GLsizeiptr;
+typedef octet GLubyte; // 'octet' should be an unsigned 8 bit type.
+typedef unsigned short GLushort;
+typedef unsigned long GLuint;
+typedef unrestricted float GLfloat;
+typedef unrestricted float GLclampf;
+
+[
+ // FIXME: [DoNotCheckConstants] and [TypeChecking=Interface|Nullable] should be applied
+ // to members and not need to be put on implementing interface
+ // DoNotCheckConstants, // need to put on implementing interface
+ NoInterfaceObject, // Always used on target of 'implements'
+ // TypeChecking=Interface|Nullable|Unrestricted, // need to put on implementing interface
+] interface WebGLRenderingContextBase {
+
+ readonly attribute HTMLCanvasElement canvas;
+
+ /* ClearBufferMask */
+ const GLenum DEPTH_BUFFER_BIT = 0x00000100;
+ const GLenum STENCIL_BUFFER_BIT = 0x00000400;
+ const GLenum COLOR_BUFFER_BIT = 0x00004000;
+
+ /* BeginMode */
+ const GLenum POINTS = 0x0000;
+ const GLenum LINES = 0x0001;
+ const GLenum LINE_LOOP = 0x0002;
+ const GLenum LINE_STRIP = 0x0003;
+ const GLenum TRIANGLES = 0x0004;
+ const GLenum TRIANGLE_STRIP = 0x0005;
+ const GLenum TRIANGLE_FAN = 0x0006;
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ const GLenum ZERO = 0;
+ const GLenum ONE = 1;
+ const GLenum SRC_COLOR = 0x0300;
+ const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
+ const GLenum SRC_ALPHA = 0x0302;
+ const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
+ const GLenum DST_ALPHA = 0x0304;
+ const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ const GLenum DST_COLOR = 0x0306;
+ const GLenum ONE_MINUS_DST_COLOR = 0x0307;
+ const GLenum SRC_ALPHA_SATURATE = 0x0308;
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ const GLenum FUNC_ADD = 0x8006;
+ const GLenum BLEND_EQUATION = 0x8009;
+ const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ const GLenum BLEND_EQUATION_ALPHA = 0x883D;
+
+ /* BlendSubtract */
+ const GLenum FUNC_SUBTRACT = 0x800A;
+ const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
+
+ /* Separate Blend Functions */
+ const GLenum BLEND_DST_RGB = 0x80C8;
+ const GLenum BLEND_SRC_RGB = 0x80C9;
+ const GLenum BLEND_DST_ALPHA = 0x80CA;
+ const GLenum BLEND_SRC_ALPHA = 0x80CB;
+ const GLenum CONSTANT_COLOR = 0x8001;
+ const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ const GLenum CONSTANT_ALPHA = 0x8003;
+ const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ const GLenum BLEND_COLOR = 0x8005;
+
+ /* Buffer Objects */
+ const GLenum ARRAY_BUFFER = 0x8892;
+ const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
+ const GLenum ARRAY_BUFFER_BINDING = 0x8894;
+ const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+ const GLenum STREAM_DRAW = 0x88E0;
+ const GLenum STATIC_DRAW = 0x88E4;
+ const GLenum DYNAMIC_DRAW = 0x88E8;
+
+ const GLenum BUFFER_SIZE = 0x8764;
+ const GLenum BUFFER_USAGE = 0x8765;
+
+ const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
+
+ /* CullFaceMode */
+ const GLenum FRONT = 0x0404;
+ const GLenum BACK = 0x0405;
+ const GLenum FRONT_AND_BACK = 0x0408;
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ const GLenum TEXTURE_2D = 0x0DE1;
+ const GLenum CULL_FACE = 0x0B44;
+ const GLenum BLEND = 0x0BE2;
+ const GLenum DITHER = 0x0BD0;
+ const GLenum STENCIL_TEST = 0x0B90;
+ const GLenum DEPTH_TEST = 0x0B71;
+ const GLenum SCISSOR_TEST = 0x0C11;
+ const GLenum POLYGON_OFFSET_FILL = 0x8037;
+ const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ const GLenum SAMPLE_COVERAGE = 0x80A0;
+
+ /* ErrorCode */
+ const GLenum NO_ERROR = 0;
+ const GLenum INVALID_ENUM = 0x0500;
+ const GLenum INVALID_VALUE = 0x0501;
+ const GLenum INVALID_OPERATION = 0x0502;
+ const GLenum OUT_OF_MEMORY = 0x0505;
+
+ /* FrontFaceDirection */
+ const GLenum CW = 0x0900;
+ const GLenum CCW = 0x0901;
+
+ /* GetPName */
+ const GLenum LINE_WIDTH = 0x0B21;
+ const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
+ const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ const GLenum CULL_FACE_MODE = 0x0B45;
+ const GLenum FRONT_FACE = 0x0B46;
+ const GLenum DEPTH_RANGE = 0x0B70;
+ const GLenum DEPTH_WRITEMASK = 0x0B72;
+ const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
+ const GLenum DEPTH_FUNC = 0x0B74;
+ const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
+ const GLenum STENCIL_FUNC = 0x0B92;
+ const GLenum STENCIL_FAIL = 0x0B94;
+ const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ const GLenum STENCIL_REF = 0x0B97;
+ const GLenum STENCIL_VALUE_MASK = 0x0B93;
+ const GLenum STENCIL_WRITEMASK = 0x0B98;
+ const GLenum STENCIL_BACK_FUNC = 0x8800;
+ const GLenum STENCIL_BACK_FAIL = 0x8801;
+ const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ const GLenum STENCIL_BACK_REF = 0x8CA3;
+ const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
+ const GLenum VIEWPORT = 0x0BA2;
+ const GLenum SCISSOR_BOX = 0x0C10;
+ /* SCISSOR_TEST */
+ const GLenum COLOR_CLEAR_VALUE = 0x0C22;
+ const GLenum COLOR_WRITEMASK = 0x0C23;
+ const GLenum UNPACK_ALIGNMENT = 0x0CF5;
+ const GLenum PACK_ALIGNMENT = 0x0D05;
+ const GLenum MAX_TEXTURE_SIZE = 0x0D33;
+ const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
+ const GLenum SUBPIXEL_BITS = 0x0D50;
+ const GLenum RED_BITS = 0x0D52;
+ const GLenum GREEN_BITS = 0x0D53;
+ const GLenum BLUE_BITS = 0x0D54;
+ const GLenum ALPHA_BITS = 0x0D55;
+ const GLenum DEPTH_BITS = 0x0D56;
+ const GLenum STENCIL_BITS = 0x0D57;
+ const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
+ /* POLYGON_OFFSET_FILL */
+ const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
+ const GLenum TEXTURE_BINDING_2D = 0x8069;
+ const GLenum SAMPLE_BUFFERS = 0x80A8;
+ const GLenum SAMPLES = 0x80A9;
+ const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
+ const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+ /* HintMode */
+ const GLenum DONT_CARE = 0x1100;
+ const GLenum FASTEST = 0x1101;
+ const GLenum NICEST = 0x1102;
+
+ /* HintTarget */
+ const GLenum GENERATE_MIPMAP_HINT = 0x8192;
+
+ /* DataType */
+ const GLenum BYTE = 0x1400;
+ const GLenum UNSIGNED_BYTE = 0x1401;
+ const GLenum SHORT = 0x1402;
+ const GLenum UNSIGNED_SHORT = 0x1403;
+ const GLenum INT = 0x1404;
+ const GLenum UNSIGNED_INT = 0x1405;
+ const GLenum FLOAT = 0x1406;
+
+ /* PixelFormat */
+ const GLenum DEPTH_COMPONENT = 0x1902;
+ const GLenum ALPHA = 0x1906;
+ const GLenum RGB = 0x1907;
+ const GLenum RGBA = 0x1908;
+ const GLenum LUMINANCE = 0x1909;
+ const GLenum LUMINANCE_ALPHA = 0x190A;
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+ /* Shaders */
+ const GLenum FRAGMENT_SHADER = 0x8B30;
+ const GLenum VERTEX_SHADER = 0x8B31;
+ const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
+ const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ const GLenum MAX_VARYING_VECTORS = 0x8DFC;
+ const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ const GLenum SHADER_TYPE = 0x8B4F;
+ const GLenum DELETE_STATUS = 0x8B80;
+ const GLenum LINK_STATUS = 0x8B82;
+ const GLenum VALIDATE_STATUS = 0x8B83;
+ const GLenum ATTACHED_SHADERS = 0x8B85;
+ const GLenum ACTIVE_UNIFORMS = 0x8B86;
+ const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
+ const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
+ const GLenum CURRENT_PROGRAM = 0x8B8D;
+
+ /* StencilFunction */
+ const GLenum NEVER = 0x0200;
+ const GLenum LESS = 0x0201;
+ const GLenum EQUAL = 0x0202;
+ const GLenum LEQUAL = 0x0203;
+ const GLenum GREATER = 0x0204;
+ const GLenum NOTEQUAL = 0x0205;
+ const GLenum GEQUAL = 0x0206;
+ const GLenum ALWAYS = 0x0207;
+
+ /* StencilOp */
+ /* ZERO */
+ const GLenum KEEP = 0x1E00;
+ const GLenum REPLACE = 0x1E01;
+ const GLenum INCR = 0x1E02;
+ const GLenum DECR = 0x1E03;
+ const GLenum INVERT = 0x150A;
+ const GLenum INCR_WRAP = 0x8507;
+ const GLenum DECR_WRAP = 0x8508;
+
+ /* StringName */
+ const GLenum VENDOR = 0x1F00;
+ const GLenum RENDERER = 0x1F01;
+ const GLenum VERSION = 0x1F02;
+
+ /* TextureMagFilter */
+ const GLenum NEAREST = 0x2600;
+ const GLenum LINEAR = 0x2601;
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
+ const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
+ const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
+ const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
+
+ /* TextureParameterName */
+ const GLenum TEXTURE_MAG_FILTER = 0x2800;
+ const GLenum TEXTURE_MIN_FILTER = 0x2801;
+ const GLenum TEXTURE_WRAP_S = 0x2802;
+ const GLenum TEXTURE_WRAP_T = 0x2803;
+
+ /* TextureTarget */
+ /* TEXTURE_2D */
+ const GLenum TEXTURE = 0x1702;
+
+ const GLenum TEXTURE_CUBE_MAP = 0x8513;
+ const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+ /* TextureUnit */
+ const GLenum TEXTURE0 = 0x84C0;
+ const GLenum TEXTURE1 = 0x84C1;
+ const GLenum TEXTURE2 = 0x84C2;
+ const GLenum TEXTURE3 = 0x84C3;
+ const GLenum TEXTURE4 = 0x84C4;
+ const GLenum TEXTURE5 = 0x84C5;
+ const GLenum TEXTURE6 = 0x84C6;
+ const GLenum TEXTURE7 = 0x84C7;
+ const GLenum TEXTURE8 = 0x84C8;
+ const GLenum TEXTURE9 = 0x84C9;
+ const GLenum TEXTURE10 = 0x84CA;
+ const GLenum TEXTURE11 = 0x84CB;
+ const GLenum TEXTURE12 = 0x84CC;
+ const GLenum TEXTURE13 = 0x84CD;
+ const GLenum TEXTURE14 = 0x84CE;
+ const GLenum TEXTURE15 = 0x84CF;
+ const GLenum TEXTURE16 = 0x84D0;
+ const GLenum TEXTURE17 = 0x84D1;
+ const GLenum TEXTURE18 = 0x84D2;
+ const GLenum TEXTURE19 = 0x84D3;
+ const GLenum TEXTURE20 = 0x84D4;
+ const GLenum TEXTURE21 = 0x84D5;
+ const GLenum TEXTURE22 = 0x84D6;
+ const GLenum TEXTURE23 = 0x84D7;
+ const GLenum TEXTURE24 = 0x84D8;
+ const GLenum TEXTURE25 = 0x84D9;
+ const GLenum TEXTURE26 = 0x84DA;
+ const GLenum TEXTURE27 = 0x84DB;
+ const GLenum TEXTURE28 = 0x84DC;
+ const GLenum TEXTURE29 = 0x84DD;
+ const GLenum TEXTURE30 = 0x84DE;
+ const GLenum TEXTURE31 = 0x84DF;
+ const GLenum ACTIVE_TEXTURE = 0x84E0;
+
+ /* TextureWrapMode */
+ const GLenum REPEAT = 0x2901;
+ const GLenum CLAMP_TO_EDGE = 0x812F;
+ const GLenum MIRRORED_REPEAT = 0x8370;
+
+ /* Uniform Types */
+ const GLenum FLOAT_VEC2 = 0x8B50;
+ const GLenum FLOAT_VEC3 = 0x8B51;
+ const GLenum FLOAT_VEC4 = 0x8B52;
+ const GLenum INT_VEC2 = 0x8B53;
+ const GLenum INT_VEC3 = 0x8B54;
+ const GLenum INT_VEC4 = 0x8B55;
+ const GLenum BOOL = 0x8B56;
+ const GLenum BOOL_VEC2 = 0x8B57;
+ const GLenum BOOL_VEC3 = 0x8B58;
+ const GLenum BOOL_VEC4 = 0x8B59;
+ const GLenum FLOAT_MAT2 = 0x8B5A;
+ const GLenum FLOAT_MAT3 = 0x8B5B;
+ const GLenum FLOAT_MAT4 = 0x8B5C;
+ const GLenum SAMPLER_2D = 0x8B5E;
+ const GLenum SAMPLER_CUBE = 0x8B60;
+
+ /* Vertex Arrays */
+ const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+ /* Read Format */
+ const GLenum IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+ const GLenum IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+
+ /* Shader Source */
+ const GLenum COMPILE_STATUS = 0x8B81;
+
+ /* Shader Precision-Specified Types */
+ const GLenum LOW_FLOAT = 0x8DF0;
+ const GLenum MEDIUM_FLOAT = 0x8DF1;
+ const GLenum HIGH_FLOAT = 0x8DF2;
+ const GLenum LOW_INT = 0x8DF3;
+ const GLenum MEDIUM_INT = 0x8DF4;
+ const GLenum HIGH_INT = 0x8DF5;
+
+ /* Framebuffer Object. */
+ const GLenum FRAMEBUFFER = 0x8D40;
+ const GLenum RENDERBUFFER = 0x8D41;
+
+ const GLenum RGBA4 = 0x8056;
+ const GLenum RGB5_A1 = 0x8057;
+ const GLenum RGB565 = 0x8D62;
+ const GLenum DEPTH_COMPONENT16 = 0x81A5;
+ const GLenum STENCIL_INDEX = 0x1901;
+ const GLenum STENCIL_INDEX8 = 0x8D48;
+ const GLenum DEPTH_STENCIL = 0x84F9;
+
+ const GLenum RENDERBUFFER_WIDTH = 0x8D42;
+ const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
+ const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
+ const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+ const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
+ const GLenum DEPTH_ATTACHMENT = 0x8D00;
+ const GLenum STENCIL_ATTACHMENT = 0x8D20;
+ const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+ const GLenum NONE = 0;
+
+ const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
+ const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+ const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
+ const GLenum RENDERBUFFER_BINDING = 0x8CA7;
+ const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+ const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ /* WebGL-specific enums */
+ const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
+ const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const GLenum CONTEXT_LOST_WEBGL = 0x9242;
+ const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+ const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
+
+ readonly attribute GLsizei drawingBufferWidth;
+ readonly attribute GLsizei drawingBufferHeight;
+
+ void activeTexture(GLenum texture);
+ void attachShader(WebGLProgram? program, WebGLShader? shader);
+ void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
+ void bindBuffer(GLenum target, WebGLBuffer? buffer);
+ void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
+ void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
+ void bindTexture(GLenum target, WebGLTexture? texture);
+ void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void blendEquation(GLenum mode);
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void blendFunc(GLenum sfactor, GLenum dfactor);
+ void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ // FIXME: should be union type
+ // https://www.khronos.org/bugzilla/show_bug.cgi?id=1172
+ void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+ void bufferData(GLenum target, ArrayBufferView data, GLenum usage);
+ void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
+ void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView data);
+ void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
+
+ GLenum checkFramebufferStatus(GLenum target);
+ void clear(GLbitfield mask);
+ void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void clearDepth(GLclampf depth);
+ void clearStencil(GLint s);
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void compileShader(WebGLShader? shader);
+
+ void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border, ArrayBufferView? data);
+ void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, ArrayBufferView? data);
+
+ void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+ WebGLBuffer createBuffer();
+ WebGLFramebuffer createFramebuffer();
+ WebGLProgram createProgram();
+ WebGLRenderbuffer createRenderbuffer();
+ WebGLShader createShader(GLenum type);
+ WebGLTexture createTexture();
+
+ void cullFace(GLenum mode);
+
+ void deleteBuffer(WebGLBuffer? buffer);
+ void deleteFramebuffer(WebGLFramebuffer? framebuffer);
+ void deleteProgram(WebGLProgram? program);
+ void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
+ void deleteShader(WebGLShader? shader);
+ void deleteTexture(WebGLTexture? texture);
+
+ void depthFunc(GLenum func);
+ void depthMask(GLboolean flag);
+ void depthRange(GLclampf zNear, GLclampf zFar);
+ void detachShader(WebGLProgram? program, WebGLShader? shader);
+ void disable(GLenum cap);
+ void disableVertexAttribArray(GLuint index);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
+
+ void enable(GLenum cap);
+ void enableVertexAttribArray(GLuint index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer? renderbuffer);
+ void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture? texture, GLint level);
+ void frontFace(GLenum mode);
+ void generateMipmap(GLenum target);
+
+ WebGLActiveInfo getActiveAttrib(WebGLProgram? program, GLuint index);
+ WebGLActiveInfo getActiveUniform(WebGLProgram? program, GLuint index);
+
+ [Custom] void getAttachedShaders(WebGLProgram? program);
+
+ GLint getAttribLocation(WebGLProgram? program, DOMString name);
+
+ [Custom] any getBufferParameter(GLenum target, GLenum pname);
+
+ WebGLContextAttributes getContextAttributes();
+
+ GLenum getError();
+
+ // object getExtension(DOMString name);
+ [Custom] any getExtension(DOMString name);
+
+ [Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+ [Custom] any getParameter(GLenum pname);
+ [Custom] any getProgramParameter(WebGLProgram? program, GLenum pname);
+ [TreatReturnedNullStringAs=Null] DOMString getProgramInfoLog(WebGLProgram? program);
+ [Custom] any getRenderbufferParameter(GLenum target, GLenum pname);
+ [Custom] any getShaderParameter(WebGLShader? shader, GLenum pname);
+
+ [TreatReturnedNullStringAs=Null] DOMString getShaderInfoLog(WebGLShader? shader);
+
+ WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
+
+ [TreatReturnedNullStringAs=Null] DOMString getShaderSource(WebGLShader? shader);
+
+ [Custom] sequence<DOMString> getSupportedExtensions();
+
+ [Custom] any getTexParameter(GLenum target, GLenum pname);
+
+ [Custom] any getUniform(WebGLProgram? program, WebGLUniformLocation location);
+
+ WebGLUniformLocation getUniformLocation(WebGLProgram? program, DOMString name);
+
+ [Custom] any getVertexAttrib(GLuint index, GLenum pname);
+
+ GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
+
+ void hint(GLenum target, GLenum mode);
+ GLboolean isBuffer(WebGLBuffer? buffer);
+ GLboolean isContextLost();
+ GLboolean isEnabled(GLenum cap);
+ GLboolean isFramebuffer(WebGLFramebuffer? framebuffer);
+ GLboolean isProgram(WebGLProgram? program);
+ GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
+ GLboolean isShader(WebGLShader? shader);
+ GLboolean isTexture(WebGLTexture? texture);
+ void lineWidth(GLfloat width);
+ void linkProgram(WebGLProgram? program);
+ void pixelStorei(GLenum pname, GLint param);
+ void polygonOffset(GLfloat factor, GLfloat units);
+
+ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels);
+
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void sampleCoverage(GLclampf value, GLboolean invert);
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ void shaderSource(WebGLShader? shader, DOMString string);
+ void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMask(GLuint mask);
+ void stencilMaskSeparate(GLenum face, GLuint mask);
+ void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+ void texParameterf(GLenum target, GLenum pname, GLfloat param);
+ void texParameteri(GLenum target, GLenum pname, GLint param);
+
+ // Supported forms:
+ // FIXME: should be union type
+ // https://www.khronos.org/bugzilla/show_bug.cgi?id=1172
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, ArrayBufferView? pixels);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData? pixels);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement image);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement video);
+
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView? pixels);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData? pixels);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement image);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement video);
+
+ void uniform1f(WebGLUniformLocation? location, GLfloat x);
+ [Custom] void uniform1fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform1i(WebGLUniformLocation? location, GLint x);
+ [Custom] void uniform1iv(WebGLUniformLocation? location, Int32Array v);
+ void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
+ [Custom] void uniform2fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
+ [Custom] void uniform2iv(WebGLUniformLocation? location, Int32Array v);
+ void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
+ [Custom] void uniform3fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
+ [Custom] void uniform3iv(WebGLUniformLocation? location, Int32Array v);
+ void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ [Custom] void uniform4fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
+ [Custom] void uniform4iv(WebGLUniformLocation? location, Int32Array v);
+
+ [Custom] void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+ [Custom] void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+ [Custom] void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+
+ void useProgram(WebGLProgram? program);
+ void validateProgram(WebGLProgram? program);
+
+ void vertexAttrib1f(GLuint indx, GLfloat x);
+ [Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
+ void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+ [Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
+ void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ [Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
+ void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ [Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
+ void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, GLintptr offset);
+
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp
index 0920fc9043e..203041e85cf 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp
@@ -27,22 +27,22 @@
#include "core/html/canvas/WebGLShader.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum type)
+PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContextBase* ctx, GLenum type)
{
return adoptRef(new WebGLShader(ctx, type));
}
-WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type)
+WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GLenum type)
: WebGLSharedObject(ctx)
, m_type(type)
, m_source("")
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createShader(type));
+ setObject(ctx->webContext()->createShader(type));
}
WebGLShader::~WebGLShader()
@@ -50,7 +50,7 @@ WebGLShader::~WebGLShader()
deleteObject(0);
}
-void WebGLShader::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLShader::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteShader(object);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h
index 6c776afc281..2d2fc23be20 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h
@@ -29,28 +29,29 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/WebGLSharedObject.h"
#include "wtf/PassRefPtr.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
-class WebGLShader : public WebGLSharedObject, public ScriptWrappable {
+class WebGLShader FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLShader();
- static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum);
+ static PassRefPtr<WebGLShader> create(WebGLRenderingContextBase*, GLenum);
- GC3Denum type() const { return m_type; }
+ GLenum type() const { return m_type; }
const String& source() const { return m_source; }
void setSource(const String& source) { m_source = source; }
private:
- WebGLShader(WebGLRenderingContext*, GC3Denum);
+ WebGLShader(WebGLRenderingContextBase*, GLenum);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
- virtual bool isShader() const { return true; }
+ virtual bool isShader() const OVERRIDE { return true; }
- GC3Denum m_type;
+ GLenum m_type;
String m_source;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp
index 288468f37ce..8fb4bb1c9af 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp
@@ -31,27 +31,27 @@
namespace WebCore {
// static
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GLint rangeMin, GLint rangeMax, GLint precision)
{
return adoptRef(new WebGLShaderPrecisionFormat(rangeMin, rangeMax, precision));
}
-GC3Dint WebGLShaderPrecisionFormat::rangeMin() const
+GLint WebGLShaderPrecisionFormat::rangeMin() const
{
return m_rangeMin;
}
-GC3Dint WebGLShaderPrecisionFormat::rangeMax() const
+GLint WebGLShaderPrecisionFormat::rangeMax() const
{
return m_rangeMax;
}
-GC3Dint WebGLShaderPrecisionFormat::precision() const
+GLint WebGLShaderPrecisionFormat::precision() const
{
return m_precision;
}
-WebGLShaderPrecisionFormat::WebGLShaderPrecisionFormat(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
+WebGLShaderPrecisionFormat::WebGLShaderPrecisionFormat(GLint rangeMin, GLint rangeMax, GLint precision)
: m_rangeMin(rangeMin)
, m_rangeMax(rangeMax)
, m_precision(precision)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h
index b59acc052a5..bd363bb232b 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h
@@ -28,7 +28,7 @@
#define WebGLShaderPrecisionFormat_h
#include "bindings/v8/ScriptWrappable.h"
-#include "platform/graphics/GraphicsContext3D.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -36,18 +36,18 @@ namespace WebCore {
class WebGLShaderPrecisionFormat : public RefCounted<WebGLShaderPrecisionFormat>, public ScriptWrappable {
public:
- static PassRefPtr<WebGLShaderPrecisionFormat> create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
+ static PassRefPtr<WebGLShaderPrecisionFormat> create(GLint rangeMin, GLint rangeMax, GLint precision);
- GC3Dint rangeMin() const;
- GC3Dint rangeMax() const;
- GC3Dint precision() const;
+ GLint rangeMin() const;
+ GLint rangeMax() const;
+ GLint precision() const;
private:
- WebGLShaderPrecisionFormat(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
+ WebGLShaderPrecisionFormat(GLint rangeMin, GLint rangeMax, GLint precision);
- GC3Dint m_rangeMin;
- GC3Dint m_rangeMax;
- GC3Dint m_precision;
+ GLint m_rangeMin;
+ GLint m_rangeMax;
+ GLint m_precision;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp
index f5d63651ff5..94f1db80baf 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp
@@ -28,11 +28,11 @@
#include "core/html/canvas/WebGLSharedObject.h"
#include "core/html/canvas/WebGLContextGroup.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
+WebGLSharedObject::WebGLSharedObject(WebGLRenderingContextBase* context)
: WebGLObject(context),
m_contextGroup(context->contextGroup())
{
@@ -54,9 +54,9 @@ void WebGLSharedObject::detachContextGroup()
}
}
-GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const
+blink::WebGraphicsContext3D* WebGLSharedObject::getAWebGraphicsContext3D() const
{
- return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0;
+ return m_contextGroup ? m_contextGroup->getAWebGraphicsContext3D() : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h
index 6c33471ba7f..990c8ae1565 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h
@@ -30,9 +30,8 @@
namespace WebCore {
-class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
// WebGLSharedObject the base class for objects that can be shared by multiple
// WebGLRenderingContexts.
@@ -43,13 +42,12 @@ public:
WebGLContextGroup* contextGroup() const { return m_contextGroup; }
virtual bool isBuffer() const { return false; }
- virtual bool isFramebuffer() const { return false; }
virtual bool isProgram() const { return false; }
virtual bool isRenderbuffer() const { return false; }
virtual bool isShader() const { return false; }
virtual bool isTexture() const { return false; }
- virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContext*) const
+ virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContextBase*) const OVERRIDE FINAL
{
return contextGroup == m_contextGroup;
}
@@ -57,14 +55,14 @@ public:
void detachContextGroup();
protected:
- WebGLSharedObject(WebGLRenderingContext*);
+ WebGLSharedObject(WebGLRenderingContextBase*);
- virtual bool hasGroupOrContext() const
+ virtual bool hasGroupOrContext() const OVERRIDE FINAL
{
return m_contextGroup;
}
- virtual GraphicsContext3D* getAGraphicsContext3D() const;
+ virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const OVERRIDE FINAL;
private:
WebGLContextGroup* m_contextGroup;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp
index 804547e1b0e..292974230ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp
@@ -27,16 +27,16 @@
#include "core/html/canvas/WebGLTexture.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLTexture(ctx));
}
-WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
+WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_target(0)
, m_minFilter(GL_NEAREST_MIPMAP_LINEAR)
@@ -51,7 +51,7 @@ WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
, m_isHalfFloatType(false)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createTexture());
+ setObject(ctx->webContext()->createTexture());
}
WebGLTexture::~WebGLTexture()
@@ -59,7 +59,7 @@ WebGLTexture::~WebGLTexture()
deleteObject(0);
}
-void WebGLTexture::setTarget(GC3Denum target, GC3Dint maxLevel)
+void WebGLTexture::setTarget(GLenum target, GLint maxLevel)
{
if (!object())
return;
@@ -81,7 +81,7 @@ void WebGLTexture::setTarget(GC3Denum target, GC3Dint maxLevel)
}
}
-void WebGLTexture::setParameteri(GC3Denum pname, GC3Dint param)
+void WebGLTexture::setParameteri(GLenum pname, GLint param)
{
if (!object() || !m_target)
return;
@@ -130,15 +130,15 @@ void WebGLTexture::setParameteri(GC3Denum pname, GC3Dint param)
update();
}
-void WebGLTexture::setParameterf(GC3Denum pname, GC3Dfloat param)
+void WebGLTexture::setParameterf(GLenum pname, GLfloat param)
{
if (!object() || !m_target)
return;
- GC3Dint iparam = static_cast<GC3Dint>(param);
+ GLint iparam = static_cast<GLint>(param);
setParameteri(pname, iparam);
}
-void WebGLTexture::setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type)
+void WebGLTexture::setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type)
{
if (!object() || !m_target)
return;
@@ -160,10 +160,10 @@ void WebGLTexture::generateMipmapLevelInfo()
if (!m_isComplete) {
for (size_t ii = 0; ii < m_info.size(); ++ii) {
const LevelInfo& info0 = m_info[ii][0];
- GC3Dsizei width = info0.width;
- GC3Dsizei height = info0.height;
- GC3Dint levelCount = computeLevelCount(width, height);
- for (GC3Dint level = 1; level < levelCount; ++level) {
+ GLsizei width = info0.width;
+ GLsizei height = info0.height;
+ GLint levelCount = computeLevelCount(width, height);
+ for (GLint level = 1; level < levelCount; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
LevelInfo& info = m_info[ii][level];
@@ -175,7 +175,7 @@ void WebGLTexture::generateMipmapLevelInfo()
m_needToUseBlackTexture = false;
}
-GC3Denum WebGLTexture::getInternalFormat(GC3Denum target, GC3Dint level) const
+GLenum WebGLTexture::getInternalFormat(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -183,7 +183,7 @@ GC3Denum WebGLTexture::getInternalFormat(GC3Denum target, GC3Dint level) const
return info->internalFormat;
}
-GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
+GLenum WebGLTexture::getType(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -191,7 +191,7 @@ GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
return info->type;
}
-GC3Dsizei WebGLTexture::getWidth(GC3Denum target, GC3Dint level) const
+GLsizei WebGLTexture::getWidth(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -199,7 +199,7 @@ GC3Dsizei WebGLTexture::getWidth(GC3Denum target, GC3Dint level) const
return info->width;
}
-GC3Dsizei WebGLTexture::getHeight(GC3Denum target, GC3Dint level) const
+GLsizei WebGLTexture::getHeight(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -207,7 +207,7 @@ GC3Dsizei WebGLTexture::getHeight(GC3Denum target, GC3Dint level) const
return info->height;
}
-bool WebGLTexture::isValid(GC3Denum target, GC3Dint level) const
+bool WebGLTexture::isValid(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -215,7 +215,7 @@ bool WebGLTexture::isValid(GC3Denum target, GC3Dint level) const
return info->valid;
}
-bool WebGLTexture::isNPOT(GC3Dsizei width, GC3Dsizei height)
+bool WebGLTexture::isNPOT(GLsizei width, GLsizei height)
{
ASSERT(width >= 0 && height >= 0);
if (!width || !height)
@@ -245,12 +245,12 @@ bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag flag) const
return false;
}
-void WebGLTexture::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLTexture::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteTexture(object);
}
-int WebGLTexture::mapTargetToIndex(GC3Denum target) const
+int WebGLTexture::mapTargetToIndex(GLenum target) const
{
if (m_target == GL_TEXTURE_2D) {
if (target == GL_TEXTURE_2D)
@@ -290,17 +290,17 @@ bool WebGLTexture::canGenerateMipmaps()
return true;
}
-GC3Dint WebGLTexture::computeLevelCount(GC3Dsizei width, GC3Dsizei height)
+GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height)
{
// return 1 + log2Floor(std::max(width, height));
- GC3Dsizei n = std::max(width, height);
+ GLsizei n = std::max(width, height);
if (n <= 0)
return 0;
- GC3Dint log = 0;
- GC3Dsizei value = n;
+ GLint log = 0;
+ GLsizei value = n;
for (int ii = 4; ii >= 0; --ii) {
int shift = (1 << ii);
- GC3Dsizei x = (value >> shift);
+ GLsizei x = (value >> shift);
if (x) {
value = x;
log += shift;
@@ -322,7 +322,7 @@ void WebGLTexture::update()
m_isComplete = true;
m_isCubeComplete = true;
const LevelInfo& first = m_info[0][0];
- GC3Dint levelCount = computeLevelCount(first.width, first.height);
+ GLint levelCount = computeLevelCount(first.width, first.height);
if (levelCount < 1)
m_isComplete = false;
else {
@@ -337,9 +337,9 @@ void WebGLTexture::update()
m_isComplete = false;
break;
}
- GC3Dsizei width = info0.width;
- GC3Dsizei height = info0.height;
- for (GC3Dint level = 1; level < levelCount; ++level) {
+ GLsizei width = info0.width;
+ GLsizei height = info0.height;
+ for (GLint level = 1; level < levelCount; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
const LevelInfo& info = m_info[ii][level];
@@ -369,14 +369,14 @@ void WebGLTexture::update()
m_needToUseBlackTexture = true;
}
-const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GC3Denum target, GC3Dint level) const
+const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GLenum target, GLint 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<GC3Dint>(m_info[targetIndex].size()))
+ if (level < 0 || level >= static_cast<GLint>(m_info[targetIndex].size()))
return 0;
return &(m_info[targetIndex][level]);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h
index 67f1fdce86c..bb086c08a10 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class WebGLTexture : public WebGLSharedObject, public ScriptWrappable {
+class WebGLTexture FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
enum TextureExtensionFlag {
NoTextureExtensionEnabled = 0,
@@ -42,30 +42,30 @@ public:
};
virtual ~WebGLTexture();
- static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLTexture> create(WebGLRenderingContextBase*);
- void setTarget(GC3Denum target, GC3Dint maxLevel);
- void setParameteri(GC3Denum pname, GC3Dint param);
- void setParameterf(GC3Denum pname, GC3Dfloat param);
+ void setTarget(GLenum target, GLint maxLevel);
+ void setParameteri(GLenum pname, GLint param);
+ void setParameterf(GLenum pname, GLfloat param);
- GC3Denum getTarget() const { return m_target; }
+ GLenum getTarget() const { return m_target; }
int getMinFilter() const { return m_minFilter; }
- void setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type);
+ void setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
bool canGenerateMipmaps();
// Generate all level information.
void generateMipmapLevelInfo();
- GC3Denum getInternalFormat(GC3Denum target, GC3Dint level) const;
- GC3Denum getType(GC3Denum target, GC3Dint level) const;
- GC3Dsizei getWidth(GC3Denum target, GC3Dint level) const;
- GC3Dsizei getHeight(GC3Denum target, GC3Dint level) const;
- bool isValid(GC3Denum target, GC3Dint level) const;
+ GLenum getInternalFormat(GLenum target, GLint level) const;
+ GLenum getType(GLenum target, GLint level) const;
+ GLsizei getWidth(GLenum target, GLint level) const;
+ GLsizei getHeight(GLenum target, GLint level) const;
+ bool isValid(GLenum target, GLint level) const;
// Whether width/height is NotPowerOfTwo.
- static bool isNPOT(GC3Dsizei, GC3Dsizei);
+ static bool isNPOT(GLsizei, GLsizei);
bool isNPOT() const;
// Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2).
@@ -73,12 +73,12 @@ public:
bool hasEverBeenBound() const { return object() && m_target; }
- static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
+ static GLint computeLevelCount(GLsizei width, GLsizei height);
protected:
- WebGLTexture(WebGLRenderingContext*);
+ WebGLTexture(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
class LevelInfo {
@@ -92,7 +92,7 @@ private:
{
}
- void setInfo(GC3Denum internalFmt, GC3Dsizei w, GC3Dsizei h, GC3Denum tp)
+ void setInfo(GLenum internalFmt, GLsizei w, GLsizei h, GLenum tp)
{
valid = true;
internalFormat = internalFmt;
@@ -102,26 +102,26 @@ private:
}
bool valid;
- GC3Denum internalFormat;
- GC3Dsizei width;
- GC3Dsizei height;
- GC3Denum type;
+ GLenum internalFormat;
+ GLsizei width;
+ GLsizei height;
+ GLenum type;
};
- virtual bool isTexture() const { return true; }
+ virtual bool isTexture() const OVERRIDE { return true; }
void update();
- int mapTargetToIndex(GC3Denum) const;
+ int mapTargetToIndex(GLenum) const;
- const LevelInfo* getLevelInfo(GC3Denum target, GC3Dint level) const;
+ const LevelInfo* getLevelInfo(GLenum target, GLint level) const;
- GC3Denum m_target;
+ GLenum m_target;
- GC3Denum m_minFilter;
- GC3Denum m_magFilter;
- GC3Denum m_wrapS;
- GC3Denum m_wrapT;
+ GLenum m_minFilter;
+ GLenum m_magFilter;
+ GLenum m_wrapS;
+ GLenum m_wrapT;
Vector<Vector<LevelInfo> > m_info;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp
index 2790c7eb70c..cd1eb95593a 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp
@@ -30,12 +30,12 @@
namespace WebCore {
-PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location)
+PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GLint location)
{
return adoptRef(new WebGLUniformLocation(program, location));
}
-WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GC3Dint location)
+WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GLint location)
: m_program(program)
, m_location(location)
{
@@ -53,7 +53,7 @@ WebGLProgram* WebGLUniformLocation::program() const
return m_program.get();
}
-GC3Dint WebGLUniformLocation::location() const
+GLint WebGLUniformLocation::location() const
{
// If the program has been linked again, then this UniformLocation is no
// longer valid.
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h
index 34e0480c126..76e98b3e359 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h
@@ -36,18 +36,18 @@ namespace WebCore {
class WebGLUniformLocation FINAL : public RefCounted<WebGLUniformLocation>, public ScriptWrappable {
public:
- static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location);
+ static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GLint location);
WebGLProgram* program() const;
- GC3Dint location() const;
+ GLint location() const;
protected:
- WebGLUniformLocation(WebGLProgram*, GC3Dint location);
+ WebGLUniformLocation(WebGLProgram*, GLint location);
private:
RefPtr<WebGLProgram> m_program;
- GC3Dint m_location;
+ GLint m_location;
unsigned m_linkCount;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
index 1d54886af8a..6c12bccb704 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -27,31 +27,29 @@
#include "core/html/canvas/WebGLVertexArrayObjectOES.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContext* ctx, VaoType type)
+PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContextBase* ctx, VaoType type)
{
return adoptRef(new WebGLVertexArrayObjectOES(ctx, type));
}
-WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
+WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase* ctx, VaoType type)
: WebGLContextObject(ctx)
, m_type(type)
, m_hasEverBeenBound(false)
- , m_boundElementArrayBuffer(0)
+ , m_boundElementArrayBuffer(nullptr)
{
ScriptWrappable::init(this);
m_vertexAttribState.resize(ctx->maxVertexAttribs());
- Extensions3D* extensions = context()->graphicsContext3D()->extensions();
switch (m_type) {
case VaoTypeDefault:
break;
default:
- setObject(extensions->createVertexArrayOES());
+ setObject(context()->webContext()->createVertexArrayOES());
break;
}
}
@@ -61,14 +59,13 @@ WebGLVertexArrayObjectOES::~WebGLVertexArrayObjectOES()
deleteObject(0);
}
-void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLVertexArrayObjectOES::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
- Extensions3D* extensions = context3d->extensions();
switch (m_type) {
case VaoTypeDefault:
break;
default:
- extensions->deleteVertexArrayOES(object);
+ context()->webContext()->deleteVertexArrayOES(object);
break;
}
@@ -87,22 +84,22 @@ void WebGLVertexArrayObjectOES::setElementArrayBuffer(PassRefPtr<WebGLBuffer> bu
if (buffer)
buffer->onAttached();
if (m_boundElementArrayBuffer)
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
+ m_boundElementArrayBuffer->onDetached(context()->webContext());
m_boundElementArrayBuffer = buffer;
}
void WebGLVertexArrayObjectOES::setVertexAttribState(
- GC3Duint index, GC3Dsizei bytesPerElement, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, PassRefPtr<WebGLBuffer> buffer)
+ GLuint index, GLsizei bytesPerElement, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset, PassRefPtr<WebGLBuffer> buffer)
{
- GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
+ GLsizei validatedStride = stride ? stride : bytesPerElement;
VertexAttribState& state = m_vertexAttribState[index];
if (buffer)
buffer->onAttached();
if (state.bufferBinding)
- state.bufferBinding->onDetached(context()->graphicsContext3D());
+ state.bufferBinding->onDetached(context()->webContext());
state.bufferBinding = buffer;
state.bytesPerElement = bytesPerElement;
@@ -117,20 +114,20 @@ void WebGLVertexArrayObjectOES::setVertexAttribState(
void WebGLVertexArrayObjectOES::unbindBuffer(PassRefPtr<WebGLBuffer> buffer)
{
if (m_boundElementArrayBuffer == buffer) {
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
- m_boundElementArrayBuffer = 0;
+ m_boundElementArrayBuffer->onDetached(context()->webContext());
+ m_boundElementArrayBuffer = nullptr;
}
for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
VertexAttribState& state = m_vertexAttribState[i];
if (state.bufferBinding == buffer) {
- buffer->onDetached(context()->graphicsContext3D());
- state.bufferBinding = 0;
+ buffer->onDetached(context()->webContext());
+ state.bufferBinding = nullptr;
}
}
}
-void WebGLVertexArrayObjectOES::setVertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+void WebGLVertexArrayObjectOES::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
VertexAttribState& state = m_vertexAttribState[index];
state.divisor = divisor;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
index 8b1fd6ee063..e54ef0a36a9 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class WebGLVertexArrayObjectOES : public WebGLContextObject, public ScriptWrappable {
+class WebGLVertexArrayObjectOES FINAL : public WebGLContextObject, public ScriptWrappable {
public:
enum VaoType {
VaoTypeDefault,
@@ -42,7 +42,7 @@ public:
virtual ~WebGLVertexArrayObjectOES();
- static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContext*, VaoType);
+ static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContextBase*, VaoType);
// Cached values for vertex attrib range checks
struct VertexAttribState {
@@ -61,14 +61,14 @@ public:
bool enabled;
RefPtr<WebGLBuffer> bufferBinding;
- GC3Dsizei bytesPerElement;
- GC3Dint size;
- GC3Denum type;
+ GLsizei bytesPerElement;
+ GLint size;
+ GLenum type;
bool normalized;
- GC3Dsizei stride;
- GC3Dsizei originalStride;
- GC3Dintptr offset;
- GC3Duint divisor;
+ GLsizei stride;
+ GLsizei originalStride;
+ GLintptr offset;
+ GLuint divisor;
};
bool isDefaultObject() const { return m_type == VaoTypeDefault; }
@@ -80,16 +80,14 @@ public:
void setElementArrayBuffer(PassRefPtr<WebGLBuffer>);
VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
- void setVertexAttribState(GC3Duint, GC3Dsizei, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr, PassRefPtr<WebGLBuffer>);
+ void setVertexAttribState(GLuint, GLsizei, GLint, GLenum, GLboolean, GLsizei, GLintptr, PassRefPtr<WebGLBuffer>);
void unbindBuffer(PassRefPtr<WebGLBuffer>);
- void setVertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+ void setVertexAttribDivisor(GLuint index, GLuint divisor);
private:
- WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
+ WebGLVertexArrayObjectOES(WebGLRenderingContextBase*, VaoType);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
-
- virtual bool isVertexArray() const { return true; }
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
VaoType m_type;
bool m_hasEverBeenBound;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp
index a41645c2428..63fed8c3512 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/BaseButtonInputType.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLInputElement.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp
index 7ffe40b29da..d40d965acb2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/BaseCheckableInputType.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
@@ -111,4 +111,9 @@ bool BaseCheckableInputType::isCheckable()
return true;
}
+bool BaseCheckableInputType::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
+{
+ return oldValue != newValue;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h
index fdb2fa006ec..aeb6ee2e462 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h
@@ -42,16 +42,17 @@ protected:
virtual void handleKeydownEvent(KeyboardEvent*);
private:
- virtual FormControlState saveFormControlState() const OVERRIDE;
- virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
- virtual bool appendFormData(FormDataList&, bool) const OVERRIDE;
- virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE;
- virtual bool canSetStringValue() const OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
- virtual String fallbackValue() const OVERRIDE;
- virtual bool storesValueSeparateFromAttribute() OVERRIDE;
- virtual void setValue(const String&, bool, TextFieldEventBehavior) OVERRIDE;
- virtual bool isCheckable() OVERRIDE;
+ virtual FormControlState saveFormControlState() const OVERRIDE FINAL;
+ virtual void restoreFormControlState(const FormControlState&) OVERRIDE FINAL;
+ virtual bool appendFormData(FormDataList&, bool) const OVERRIDE FINAL;
+ virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE FINAL;
+ virtual bool canSetStringValue() const OVERRIDE FINAL;
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE FINAL;
+ virtual String fallbackValue() const OVERRIDE FINAL;
+ virtual bool storesValueSeparateFromAttribute() OVERRIDE FINAL;
+ virtual void setValue(const String&, bool, TextFieldEventBehavior) OVERRIDE FINAL;
+ virtual bool isCheckable() OVERRIDE FINAL;
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
index 3967a8ac871..76f32aba3de 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
@@ -29,17 +29,16 @@
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/FrameHost.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/page/Chrome.h"
-#include "core/page/Page.h"
#include "platform/UserGestureIndicator.h"
namespace WebCore {
BaseChooserOnlyDateAndTimeInputType::~BaseChooserOnlyDateAndTimeInputType()
{
- closeDateTimeChooser();
}
void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
@@ -54,25 +53,29 @@ void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
DateTimeChooserParameters parameters;
if (!element().setupDateTimeChooserParameters(parameters))
return;
- m_dateTimeChooser = element().document().page()->chrome().openDateTimeChooser(this, parameters);
+ m_dateTimeChooser = element().document().frameHost()->chrome().openDateTimeChooser(this, parameters);
}
void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree()
{
DEFINE_STATIC_LOCAL(AtomicString, valueContainerPseudo, ("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral));
- RefPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
- valueContainer->setPseudo(valueContainerPseudo);
+ RefPtrWillBeRawPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
+ valueContainer->setShadowPseudoId(valueContainerPseudo);
element().userAgentShadowRoot()->appendChild(valueContainer.get());
- updateAppearance();
+ updateView();
}
-void BaseChooserOnlyDateAndTimeInputType::updateAppearance()
+void BaseChooserOnlyDateAndTimeInputType::updateView()
{
Node* node = element().userAgentShadowRoot()->firstChild();
if (!node || !node->isHTMLElement())
return;
- String displayValue = visibleValue();
+ String displayValue;
+ if (!element().suggestedValue().isNull())
+ displayValue = element().suggestedValue();
+ else
+ displayValue = visibleValue();
if (displayValue.isEmpty()) {
// Need to put something to keep text baseline.
displayValue = " ";
@@ -84,7 +87,7 @@ void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool val
{
BaseDateAndTimeInputType::setValue(value, valueChanged, eventBehavior);
if (valueChanged)
- updateAppearance();
+ updateView();
}
void BaseChooserOnlyDateAndTimeInputType::closePopupView()
@@ -138,5 +141,12 @@ void BaseChooserOnlyDateAndTimeInputType::accessKeyAction(bool sendMouseEvents)
BaseClickableWithKeyInputType::accessKeyAction(element(), sendMouseEvents);
}
+void BaseChooserOnlyDateAndTimeInputType::trace(Visitor* visitor)
+{
+ visitor->trace(m_dateTimeChooser);
+ BaseDateAndTimeInputType::trace(visitor);
+ DateTimeChooserClient::trace(visitor);
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
index 4ba1f878ce5..92e1764fb80 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
@@ -35,12 +35,14 @@
namespace WebCore {
class BaseChooserOnlyDateAndTimeInputType : public BaseDateAndTimeInputType, public DateTimeChooserClient {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BaseChooserOnlyDateAndTimeInputType);
protected:
- BaseChooserOnlyDateAndTimeInputType(HTMLInputElement& element) : BaseDateAndTimeInputType(element) { }
+ explicit BaseChooserOnlyDateAndTimeInputType(HTMLInputElement& element) : BaseDateAndTimeInputType(element) { }
virtual ~BaseChooserOnlyDateAndTimeInputType();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- void updateAppearance();
void closeDateTimeChooser();
// InputType functions:
@@ -52,13 +54,14 @@ private:
virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE;
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
+ virtual void updateView() OVERRIDE;
// DateTimeChooserClient functions:
virtual void didChooseValue(const String&) OVERRIDE;
virtual void didChooseValue(double) OVERRIDE;
virtual void didEndChooser() OVERRIDE;
- RefPtr<DateTimeChooser> m_dateTimeChooser;
+ RefPtrWillBeMember<DateTimeChooser> m_dateTimeChooser;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp
index bf87e948cc0..662f4e6a4cd 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp
@@ -43,7 +43,6 @@ namespace WebCore {
using blink::WebLocalizedString;
using namespace HTMLNames;
-using namespace std;
static const int msecPerMinute = 60 * 1000;
static const int msecPerSecond = 1000;
@@ -64,9 +63,9 @@ double BaseDateAndTimeInputType::valueAsDouble() const
return value.isFinite() ? value.toDouble() : DateComponents::invalidMilliseconds();
}
-void BaseDateAndTimeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState&) const
+void BaseDateAndTimeInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- element().setValue(serialize(newValue), eventBehavior);
+ setValueAsDecimal(Decimal::fromDouble(newValue), eventBehavior, exceptionState);
}
bool BaseDateAndTimeInputType::typeMismatchFor(const String& value) const
@@ -177,7 +176,7 @@ bool BaseDateAndTimeInputType::supportsReadOnly() const
bool BaseDateAndTimeInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
bool BaseDateAndTimeInputType::valueMissing(const String& value) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h
index 0bdf559b0f2..bf5c8bf895a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h
@@ -43,7 +43,11 @@ class BaseDateAndTimeInputType : public InputType {
protected:
BaseDateAndTimeInputType(HTMLInputElement& element) : InputType(element) { }
virtual Decimal parseToNumber(const String&, const Decimal&) const OVERRIDE;
- virtual bool parseToDateComponents(const String&, DateComponents*) const OVERRIDE;
+ // 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.
+ bool parseToDateComponents(const String&, DateComponents*) const;
virtual String sanitizeValue(const String&) const OVERRIDE;
virtual String serialize(const Decimal&) const OVERRIDE;
String serializeWithComponents(const DateComponents&) const;
@@ -55,7 +59,7 @@ private:
virtual double valueAsDate() const OVERRIDE;
virtual void setValueAsDate(double, ExceptionState&) const OVERRIDE;
virtual double valueAsDouble() const OVERRIDE;
- virtual void setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
+ virtual void setValueAsDouble(double, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
virtual bool typeMismatchFor(const String&) const OVERRIDE;
virtual bool typeMismatch() const OVERRIDE;
virtual bool valueMissing(const String&) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
index 3fbe6236e7b..4f8b9eb59ce 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
@@ -32,10 +32,10 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/CSSValueKeywords.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/KeyboardEvent.h"
+#include "core/events/ScopedEventQueue.h"
#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLOptionElement.h"
@@ -46,6 +46,7 @@
#include "core/page/Page.h"
#include "core/rendering/RenderTheme.h"
#include "platform/DateComponents.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/DateTimeFormat.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/DateMath.h"
@@ -158,9 +159,12 @@ void BaseMultipleFieldsDateAndTimeInputType::didBlurFromControl()
if (containsFocusedShadowElement())
return;
- RefPtr<HTMLInputElement> protector(element());
+ EventQueueScope scope;
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(element());
// Remove focus ring by CSS "focus" pseudo class.
element().setFocus(false);
+ if (SpinButtonElement *spinButton = spinButtonElement())
+ spinButton->releaseCapture();
}
void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
@@ -177,7 +181,7 @@ void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
{
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
String oldValue = input->value();
String newValue = sanitizeValue(dateTimeEditElement()->value());
// Even if oldValue is null and newValue is "", we should assume they are same.
@@ -185,9 +189,8 @@ void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
input->setNeedsValidityCheck();
} else {
input->setValueInternal(newValue, DispatchNoEvent);
- input->setNeedsStyleRecalc();
+ input->setNeedsStyleRecalc(SubtreeStyleChange);
input->dispatchFormControlInputEvent();
- input->dispatchFormControlChangeEvent();
}
input->notifyFormStateChanged();
input->updateClearButtonVisibility();
@@ -240,6 +243,12 @@ void BaseMultipleFieldsDateAndTimeInputType::spinButtonStepUp()
edit->stepUp();
}
+void BaseMultipleFieldsDateAndTimeInputType::spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch eventDispatch)
+{
+ if (eventDispatch == SpinButtonElement::EventDispatchAllowed)
+ element().dispatchFormControlChangeEvent();
+}
+
bool BaseMultipleFieldsDateAndTimeInputType::isPickerIndicatorOwnerDisabledOrReadOnly() const
{
return element().isDisabledOrReadOnly();
@@ -259,6 +268,7 @@ void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(const St
unsigned end;
if (date.parseDate(value, 0, end) && end == value.length())
edit->setOnlyYearMonthDay(date);
+ element().dispatchFormControlChangeEvent();
}
void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(double value)
@@ -285,6 +295,7 @@ BaseMultipleFieldsDateAndTimeInputType::BaseMultipleFieldsDateAndTimeInputType(H
BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType()
{
+#if !ENABLE(OILPAN)
if (SpinButtonElement* element = spinButtonElement())
element->removeSpinButtonOwner();
if (ClearButtonElement* element = clearButtonElement())
@@ -293,6 +304,7 @@ BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType(
element->removeEditControlOwner();
if (PickerIndicatorElement* element = pickerIndicatorElement())
element->removePickerIndicatorOwner();
+#endif
}
String BaseMultipleFieldsDateAndTimeInputType::badInputText() const
@@ -339,22 +351,15 @@ void BaseMultipleFieldsDateAndTimeInputType::createShadowSubtree()
ContainerNode* container = element().userAgentShadowRoot();
container->appendChild(DateTimeEditElement::create(document, *this));
- updateView();
+ element().updateView();
container->appendChild(ClearButtonElement::create(document, *this));
container->appendChild(SpinButtonElement::create(document, *this));
- bool shouldAddPickerIndicator = false;
- if (InputType::themeSupportsDataListUI(this))
- shouldAddPickerIndicator = true;
- if (RenderTheme::theme().supportsCalendarPicker(formControlType())) {
- shouldAddPickerIndicator = true;
+ if (RenderTheme::theme().supportsCalendarPicker(formControlType()))
m_pickerIndicatorIsAlwaysVisible = true;
- }
- if (shouldAddPickerIndicator) {
- container->appendChild(PickerIndicatorElement::create(document, *this));
- m_pickerIndicatorIsVisible = true;
- updatePickerIndicatorVisibility();
- }
+ container->appendChild(PickerIndicatorElement::create(document, *this));
+ m_pickerIndicatorIsVisible = true;
+ updatePickerIndicatorVisibility();
}
void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
@@ -379,15 +384,15 @@ void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
m_isDestroyingShadowSubtree = false;
}
-void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusType type)
{
DateTimeEditElement* edit = dateTimeEditElement();
if (!edit || m_isDestroyingShadowSubtree)
return;
- if (direction == FocusDirectionBackward) {
+ if (type == FocusTypeBackward) {
if (element().document().page())
- element().document().page()->focusController().advanceFocus(direction);
- } else if (direction == FocusDirectionNone || direction == FocusDirectionMouse || direction == FocusDirectionPage) {
+ element().document().page()->focusController().advanceFocus(type);
+ } else if (type == FocusTypeNone || type == FocusTypeMouse || type == FocusTypePage) {
edit->focusByOwner(oldFocusedElement);
} else {
edit->focusByOwner();
@@ -443,6 +448,11 @@ AtomicString BaseMultipleFieldsDateAndTimeInputType::localeIdentifier() const
return element().computeInheritedLanguage();
}
+void BaseMultipleFieldsDateAndTimeInputType::editControlDidChangeValueByKeyboard()
+{
+ element().dispatchFormControlChangeEvent();
+}
+
void BaseMultipleFieldsDateAndTimeInputType::minOrMaxAttributeChanged()
{
updateView();
@@ -479,7 +489,7 @@ void BaseMultipleFieldsDateAndTimeInputType::setValue(const String& sanitizedVal
InputType::setValue(sanitizedValue, valueChanged, eventBehavior);
DateTimeEditElement* edit = dateTimeEditElement();
if (valueChanged || (sanitizedValue.isEmpty() && edit && edit->anyEditableFieldsHaveValues())) {
- updateView();
+ element().updateView();
element().setNeedsValidityCheck();
}
}
@@ -503,12 +513,18 @@ void BaseMultipleFieldsDateAndTimeInputType::updateView()
DateTimeEditElement::LayoutParameters layoutParameters(element().locale(), createStepRange(AnyIsDefaultStep));
DateComponents date;
- const bool hasValue = parseToDateComponents(element().value(), &date);
+ bool hasValue = false;
+ if (!element().suggestedValue().isNull())
+ hasValue = parseToDateComponents(element().suggestedValue(), &date);
+ else
+ hasValue = parseToDateComponents(element().value(), &date);
if (!hasValue)
setMillisecondToDateComponents(layoutParameters.stepRange.minimum().toDouble(), &date);
setupLayoutParameters(layoutParameters, date);
+ DEFINE_STATIC_LOCAL(AtomicString, datetimeformatAttr, ("datetimeformat", AtomicString::ConstructFromLiteral));
+ edit->setAttribute(datetimeformatAttr, AtomicString(layoutParameters.dateTimeFormat), ASSERT_NO_EXCEPTION);
const AtomicString pattern = edit->fastGetAttribute(HTMLNames::patternAttr);
if (!pattern.isEmpty())
layoutParameters.dateTimeFormat = pattern;
@@ -540,12 +556,10 @@ void BaseMultipleFieldsDateAndTimeInputType::updatePickerIndicatorVisibility()
showPickerIndicator();
return;
}
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- if (element().hasValidDataListOptions())
- showPickerIndicator();
- else
- hidePickerIndicator();
- }
+ if (element().hasValidDataListOptions())
+ showPickerIndicator();
+ else
+ hidePickerIndicator();
}
void BaseMultipleFieldsDateAndTimeInputType::hidePickerIndicator()
@@ -586,7 +600,7 @@ bool BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEven
void BaseMultipleFieldsDateAndTimeInputType::clearValue()
{
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
input->setValue("", DispatchInputAndChangeEvent);
input->updateClearButtonVisibility();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h
index 14a0a2c8171..4867175784d 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h
@@ -49,6 +49,8 @@ class BaseMultipleFieldsDateAndTimeInputType
, protected PickerIndicatorElement::PickerIndicatorOwner
, protected SpinButtonElement::SpinButtonOwner
, protected ClearButtonElement::ClearButtonOwner {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BaseMultipleFieldsDateAndTimeInputType);
+
public:
virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const = 0;
@@ -67,6 +69,7 @@ private:
virtual bool isEditControlOwnerDisabled() const OVERRIDE FINAL;
virtual bool isEditControlOwnerReadOnly() const OVERRIDE FINAL;
virtual AtomicString localeIdentifier() const OVERRIDE FINAL;
+ virtual void editControlDidChangeValueByKeyboard() OVERRIDE FINAL;
// SpinButtonElement::SpinButtonOwner functions.
virtual void focusAndSelectSpinButtonOwner() OVERRIDE;
@@ -74,6 +77,7 @@ private:
virtual bool shouldSpinButtonRespondToWheelEvents() OVERRIDE;
virtual void spinButtonStepDown() OVERRIDE;
virtual void spinButtonStepUp() OVERRIDE;
+ virtual void spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch) OVERRIDE;
// PickerIndicatorElement::PickerIndicatorOwner functions
virtual bool isPickerIndicatorOwnerDisabledOrReadOnly() const OVERRIDE FINAL;
@@ -94,7 +98,7 @@ private:
virtual void destroyShadowSubtree() OVERRIDE FINAL;
virtual void disabledAttributeChanged() OVERRIDE FINAL;
virtual void forwardEvent(Event*) OVERRIDE FINAL;
- virtual void handleFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
+ virtual void handleFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE;
virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE FINAL;
virtual bool hasBadInput() const OVERRIDE;
virtual bool hasCustomFocusLogic() const OVERRIDE FINAL;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp
index d00d21e98cb..cc531a12091 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "core/html/forms/BaseTextInputType.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptRegexp.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLInputElement.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h
index 8c917a0b616..c2743688571 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h
@@ -42,9 +42,9 @@ protected:
BaseTextInputType(HTMLInputElement& element) : TextFieldInputType(element) { }
private:
- virtual bool isTextType() const OVERRIDE;
- virtual bool patternMismatch(const String&) const OVERRIDE;
- virtual bool supportsPlaceholder() const OVERRIDE;
+ virtual bool isTextType() const OVERRIDE FINAL;
+ virtual bool patternMismatch(const String&) const OVERRIDE FINAL;
+ virtual bool supportsPlaceholder() const OVERRIDE FINAL;
virtual bool supportsSelectionAPI() const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp
index 39e112c03fe..7ecf1cbf1d4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp
@@ -31,14 +31,14 @@
#include "config.h"
#include "core/html/forms/ButtonInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-PassRefPtr<InputType> ButtonInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ButtonInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ButtonInputType(element));
+ return adoptRefWillBeNoop(new ButtonInputType(element));
}
const AtomicString& ButtonInputType::formControlType() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h
index aa31135602b..5b187710d3a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class ButtonInputType : public BaseButtonInputType {
+class ButtonInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
ButtonInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp
index 738f9d58b9b..9a77643e431 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/CheckboxInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/html/HTMLInputElement.h"
#include "platform/text/PlatformLocale.h"
@@ -40,9 +40,9 @@
namespace WebCore {
-PassRefPtr<InputType> CheckboxInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> CheckboxInputType::create(HTMLInputElement& element)
{
- return adoptRef(new CheckboxInputType(element));
+ return adoptRefWillBeNoop(new CheckboxInputType(element));
}
const AtomicString& CheckboxInputType::formControlType() const
@@ -68,12 +68,12 @@ void CheckboxInputType::handleKeyupEvent(KeyboardEvent* event)
dispatchSimulatedClickIfActive(event);
}
-PassOwnPtr<ClickHandlingState> CheckboxInputType::willDispatchClick()
+PassOwnPtrWillBeRawPtr<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);
+ OwnPtrWillBeRawPtr<ClickHandlingState> state = adoptPtrWillBeNoop(new ClickHandlingState);
state->checked = element().checked();
state->indeterminate = element().indeterminate();
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h
index 9299018f6b5..06e4c516750 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class CheckboxInputType : public BaseCheckableInputType {
+class CheckboxInputType FINAL : public BaseCheckableInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
CheckboxInputType(HTMLInputElement& element) : BaseCheckableInputType(element) { }
@@ -45,7 +45,7 @@ private:
virtual bool valueMissing(const String&) const OVERRIDE;
virtual String valueMissingText() const OVERRIDE;
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
- virtual PassOwnPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
+ virtual PassOwnPtrWillBeRawPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
virtual void didDispatchClick(Event*, const ClickHandlingState&) OVERRIDE;
virtual bool isCheckbox() const OVERRIDE;
virtual bool supportsIndeterminateAppearance() const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp
index 304504bdfc3..ae4bd2d7677 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp
@@ -31,11 +31,10 @@
#include "config.h"
#include "core/html/forms/ColorInputType.h"
-#include "CSSPropertyNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
+#include "core/CSSPropertyNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/MouseEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLDataListElement.h"
@@ -44,6 +43,8 @@
#include "core/html/HTMLOptionElement.h"
#include "core/page/Chrome.h"
#include "core/rendering/RenderView.h"
+#include "platform/ColorChooser.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/graphics/Color.h"
#include "wtf/PassOwnPtr.h"
@@ -68,13 +69,13 @@ static bool isValidColorString(const String& value)
// We don't accept #rgb and #aarrggbb formats.
if (value.length() != 7)
return false;
- Color color(value);
- return color.isValid() && !color.hasAlpha();
+ Color color;
+ return color.setFromString(value) && !color.hasAlpha();
}
-PassRefPtr<InputType> ColorInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ColorInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ColorInputType(element));
+ return adoptRefWillBeNoop(new ColorInputType(element));
}
ColorInputType::~ColorInputType()
@@ -117,7 +118,10 @@ String ColorInputType::sanitizeValue(const String& proposedValue) const
Color ColorInputType::valueAsColor() const
{
- return Color(element().value());
+ Color color;
+ bool success = color.setFromString(element().value());
+ ASSERT_UNUSED(success, success);
+ return color;
}
void ColorInputType::createShadowSubtree()
@@ -125,14 +129,14 @@ void ColorInputType::createShadowSubtree()
ASSERT(element().shadow());
Document& document = element().document();
- RefPtr<HTMLDivElement> wrapperElement = HTMLDivElement::create(document);
- wrapperElement->setPseudo(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral));
- RefPtr<HTMLDivElement> colorSwatch = HTMLDivElement::create(document);
- colorSwatch->setPseudo(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<HTMLDivElement> wrapperElement = HTMLDivElement::create(document);
+ wrapperElement->setShadowPseudoId(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<HTMLDivElement> colorSwatch = HTMLDivElement::create(document);
+ colorSwatch->setShadowPseudoId(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral));
wrapperElement->appendChild(colorSwatch.release());
element().userAgentShadowRoot()->appendChild(wrapperElement.release());
- updateColorSwatch();
+ element().updateView();
}
void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
@@ -142,7 +146,7 @@ void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldE
if (!valueChanged)
return;
- updateColorSwatch();
+ element().updateView();
if (m_chooser)
m_chooser->setSelectedColor(valueAsColor());
}
@@ -157,7 +161,7 @@ void ColorInputType::handleDOMActivateEvent(Event* event)
Chrome* chrome = this->chrome();
if (chrome && !m_chooser)
- m_chooser = chrome->createColorChooser(this, valueAsColor());
+ m_chooser = chrome->createColorChooser(element().document().frame(), this, valueAsColor());
event->setDefaultHandled();
}
@@ -169,7 +173,7 @@ void ColorInputType::closePopupView()
bool ColorInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
bool ColorInputType::typeMismatchFor(const String& value) const
@@ -182,7 +186,7 @@ void ColorInputType::didChooseColor(const Color& color)
if (element().isDisabledFormControl() || color == valueAsColor())
return;
element().setValueFromRenderer(color.serialized());
- updateColorSwatch();
+ element().updateView();
element().dispatchFormControlChangeEvent();
}
@@ -197,7 +201,7 @@ void ColorInputType::endColorChooser()
m_chooser->endChooser();
}
-void ColorInputType::updateColorSwatch()
+void ColorInputType::updateView()
{
HTMLElement* colorSwatch = shadowColorSwatch();
if (!colorSwatch)
@@ -224,30 +228,25 @@ Color ColorInputType::currentColor()
bool ColorInputType::shouldShowSuggestions() const
{
- if (RuntimeEnabledFeatures::dataListElementEnabled())
- return element().fastHasAttribute(listAttr);
-
- return false;
+ return element().fastHasAttribute(listAttr);
}
Vector<ColorSuggestion> ColorInputType::suggestions() const
{
Vector<ColorSuggestion> suggestions;
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- HTMLDataListElement* dataList = element().dataList();
- if (dataList) {
- RefPtr<HTMLCollection> options = dataList->options();
- for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); i++) {
- if (!element().isValidValue(option->value()))
- continue;
- Color color(option->value());
- if (!color.isValid())
- continue;
- ColorSuggestion suggestion(color, option->label().left(maxSuggestionLabelLength));
- suggestions.append(suggestion);
- if (suggestions.size() >= maxSuggestions)
- break;
- }
+ HTMLDataListElement* dataList = element().dataList();
+ if (dataList) {
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); i++) {
+ if (!element().isValidValue(option->value()))
+ continue;
+ Color color;
+ if (!color.setFromString(option->value()))
+ continue;
+ ColorSuggestion suggestion(color, option->label().left(maxSuggestionLabelLength));
+ suggestions.append(suggestion);
+ if (suggestions.size() >= maxSuggestions)
+ break;
}
}
return suggestions;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h
index b0f7ba3d02b..366451bddd2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h
@@ -36,9 +36,11 @@
namespace WebCore {
-class ColorInputType : public BaseClickableWithKeyInputType, public ColorChooserClient {
+class ColorChooser;
+
+class ColorInputType FINAL : public BaseClickableWithKeyInputType, public ColorChooserClient {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
virtual ~ColorInputType();
// ColorChooserClient implementation.
@@ -63,10 +65,10 @@ private:
virtual void closePopupView() OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual bool typeMismatchFor(const String&) const OVERRIDE;
+ virtual void updateView() OVERRIDE;
Color valueAsColor() const;
void endColorChooser();
- void updateColorSwatch();
HTMLElement* shadowColorSwatch() const;
OwnPtr<ColorChooser> m_chooser;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp
index a820bc8f97b..6f3cbef7a8e 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/DateInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -53,9 +53,9 @@ inline DateInputType::DateInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> DateInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> DateInputType::create(HTMLInputElement& element)
{
- return adoptRef(new DateInputType(element));
+ return adoptRefWillBeNoop(new DateInputType(element));
}
void DateInputType::countUsage()
@@ -72,7 +72,7 @@ StepRange DateInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateDefaultStep, dateDefaultStepBase, dateStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
- return InputType::createStepRange(anyStepHandling, 0, Decimal::fromDouble(DateComponents::minimumDate()), Decimal::fromDouble(DateComponents::maximumDate()), stepDescription);
+ return InputType::createStepRange(anyStepHandling, dateDefaultStepBase, Decimal::fromDouble(DateComponents::minimumDate()), Decimal::fromDouble(DateComponents::maximumDate()), stepDescription);
}
bool DateInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h
index 2688adf1d93..1583a2b46c5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h
@@ -44,9 +44,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseDateInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseDateInputType;
#endif
-class DateInputType : public BaseDateInputType {
+class DateInputType FINAL : public BaseDateInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
DateInputType(HTMLInputElement&);
@@ -61,7 +61,7 @@ private:
// BaseMultipleFieldsDateAndTimeInputType functions
virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp
index 60c162dc247..76c733f43c2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/html/forms/DateTimeLocalInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -50,9 +50,9 @@ static const int dateTimeLocalDefaultStep = 60;
static const int dateTimeLocalDefaultStepBase = 0;
static const int dateTimeLocalStepScaleFactor = 1000;
-PassRefPtr<InputType> DateTimeLocalInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> DateTimeLocalInputType::create(HTMLInputElement& element)
{
- return adoptRef(new DateTimeLocalInputType(element));
+ return adoptRefWillBeNoop(new DateTimeLocalInputType(element));
}
void DateTimeLocalInputType::countUsage()
@@ -81,7 +81,7 @@ StepRange DateTimeLocalInputType::createStepRange(AnyStepHandling anyStepHandlin
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeLocalDefaultStep, dateTimeLocalDefaultStepBase, dateTimeLocalStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
- return InputType::createStepRange(anyStepHandling, 0, Decimal::fromDouble(DateComponents::minimumDateTime()), Decimal::fromDouble(DateComponents::maximumDateTime()), stepDescription);
+ return InputType::createStepRange(anyStepHandling, dateTimeLocalDefaultStepBase, Decimal::fromDouble(DateComponents::minimumDateTime()), Decimal::fromDouble(DateComponents::maximumDateTime()), stepDescription);
}
bool DateTimeLocalInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
index ade5ac0f8e4..8fb2f5e637b 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
@@ -44,9 +44,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseDateTimeLocalInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseDateTimeLocalInputType;
#endif
-class DateTimeLocalInputType : public BaseDateTimeLocalInputType {
+class DateTimeLocalInputType FINAL : public BaseDateTimeLocalInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
DateTimeLocalInputType(HTMLInputElement& element) : BaseDateTimeLocalInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp
index 20db60bf5f2..727bdb478e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "core/html/forms/EmailInputType.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ScriptRegexp.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/page/Chrome.h"
@@ -34,7 +34,8 @@
#include "public/platform/Platform.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringBuilder.h"
-#include <unicode/uidna.h>
+#include <unicode/idna.h>
+#include <unicode/unistr.h>
namespace WebCore {
@@ -45,11 +46,13 @@ static const char localPartCharacters[] = "abcdefghijklmnopqrstuvwxyz0123456789!
static const char emailPattern[] =
"[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part
"@"
- "[a-z0-9-]+(\\.[a-z0-9-]+)*"; // domain part
+ "[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?" // domain part
+ "(?:\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*";
// RFC5321 says the maximum total length of a domain name is 255 octets.
-static const size_t maximumDomainNameLength = 255;
-static const int32_t idnaConversionOption = UIDNA_ALLOW_UNASSIGNED;
+static const int32_t maximumDomainNameLength = 255;
+// Use the same option as in url/url_canon_icu.cc
+static const int32_t idnaConversionOption = UIDNA_CHECK_BIDI;
static String convertEmailAddressToASCII(const String& address)
{
@@ -60,15 +63,24 @@ static String convertEmailAddressToASCII(const String& address)
if (atPosition == kNotFound)
return address;
- UErrorCode error = U_ZERO_ERROR;
- UChar domainNameBuffer[maximumDomainNameLength];
- int32_t domainNameLength = uidna_IDNToASCII(address.charactersWithNullTermination().data() + atPosition + 1, address.length() - atPosition - 1, domainNameBuffer, WTF_ARRAY_LENGTH(domainNameBuffer), idnaConversionOption, 0, &error);
- if (error != U_ZERO_ERROR || domainNameLength <= 0)
+ // UnicodeString ctor for copy-on-write does not work reliably (in debug
+ // build.) TODO(jshin): In an unlikely case this is a perf-issue, treat
+ // 8bit and non-8bit strings separately.
+ icu::UnicodeString idnDomainName(address.charactersWithNullTermination().data() + atPosition + 1, address.length() - atPosition - 1);
+ icu::UnicodeString domainName;
+
+ // Leak |idna| at the end.
+ UErrorCode errorCode = U_ZERO_ERROR;
+ static icu::IDNA *idna = icu::IDNA::createUTS46Instance(idnaConversionOption, errorCode);
+ ASSERT(idna);
+ icu::IDNAInfo idnaInfo;
+ idna->nameToASCII(idnDomainName, domainName, idnaInfo, errorCode);
+ if (U_FAILURE(errorCode) || idnaInfo.hasErrors() || domainName.length() > maximumDomainNameLength)
return address;
StringBuilder builder;
builder.append(address, 0, atPosition + 1);
- builder.append(domainNameBuffer, domainNameLength);
+ builder.append(domainName.getBuffer(), domainName.length());
return builder.toString();
}
@@ -133,9 +145,9 @@ static bool isValidEmailAddress(const String& address)
return !matchOffset && matchLength == addressLength;
}
-PassRefPtr<InputType> EmailInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> EmailInputType::create(HTMLInputElement& element)
{
- return adoptRef(new EmailInputType(element));
+ return adoptRefWillBeNoop(new EmailInputType(element));
}
void EmailInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h
index 82bd153a780..230586f9d47 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class EmailInputType : public BaseTextInputType {
+class EmailInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
EmailInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
index 64338a6849d..f63368f318d 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
@@ -22,10 +22,9 @@
#include "config.h"
#include "core/html/forms/FileInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
#include "core/fileapi/File.h"
@@ -37,6 +36,7 @@
#include "core/page/DragData.h"
#include "core/rendering/RenderFileUploadControl.h"
#include "platform/FileMetadata.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/PassOwnPtr.h"
@@ -54,9 +54,15 @@ inline FileInputType::FileInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> FileInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> FileInputType::create(HTMLInputElement& element)
{
- return adoptRef(new FileInputType(element));
+ return adoptRefWillBeNoop(new FileInputType(element));
+}
+
+void FileInputType::trace(Visitor* visitor)
+{
+ visitor->trace(m_fileList);
+ BaseClickableWithKeyInputType::trace(visitor);
}
Vector<FileChooserFileInfo> FileInputType::filesFromFormControlState(const FormControlState& state)
@@ -146,13 +152,13 @@ void FileInputType::handleDOMActivateEvent(Event* event)
if (Chrome* chrome = this->chrome()) {
FileChooserSettings settings;
HTMLInputElement& input = element();
- settings.allowsDirectoryUpload = RuntimeEnabledFeatures::directoryUploadEnabled() && input.fastHasAttribute(webkitdirectoryAttr);
+ settings.allowsDirectoryUpload = input.fastHasAttribute(webkitdirectoryAttr);
settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input.fastHasAttribute(multipleAttr);
settings.acceptMIMETypes = input.acceptMIMETypes();
settings.acceptFileExtensions = input.acceptFileExtensions();
settings.selectedFiles = m_fileList->paths();
#if ENABLE(MEDIA_CAPTURE)
- settings.useMediaCapture = input.capture();
+ settings.useMediaCapture = input.isFileUpload() && input.fastHasAttribute(captureAttr);
#endif
chrome->runOpenPanel(input.document().frame(), newFileChooser(settings));
}
@@ -200,21 +206,25 @@ bool FileInputType::getTypeSpecificValue(String& value)
return true;
}
-void FileInputType::setValue(const String&, bool, TextFieldEventBehavior)
+void FileInputType::setValue(const String&, bool valueChanged, TextFieldEventBehavior)
{
+ if (!valueChanged)
+ return;
+
m_fileList->clear();
- element().setNeedsStyleRecalc();
+ element().setNeedsStyleRecalc(SubtreeStyleChange);
+ element().setNeedsValidityCheck();
}
-PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
+PassRefPtrWillBeRawPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
{
- RefPtr<FileList> fileList(FileList::create());
+ RefPtrWillBeRawPtr<FileList> fileList(FileList::create());
size_t size = files.size();
// 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) && RuntimeEnabledFeatures::directoryUploadEnabled()) {
+ if (size && element().fastHasAttribute(webkitdirectoryAttr)) {
// Find the common root path.
String rootPath = directoryName(files[0].path);
for (size_t i = 1; i < size; i++) {
@@ -247,10 +257,10 @@ bool FileInputType::isFileUpload() const
void FileInputType::createShadowSubtree()
{
ASSERT(element().shadow());
- RefPtr<HTMLInputElement> button = HTMLInputElement::create(element().document(), 0, false);
+ RefPtrWillBeRawPtr<HTMLInputElement> button = HTMLInputElement::create(element().document(), 0, false);
button->setType(InputTypeNames::button);
- button->setAttribute(valueAttr, locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel));
- button->setPseudo(AtomicString("-webkit-file-upload-button", AtomicString::ConstructFromLiteral));
+ button->setAttribute(valueAttr, AtomicString(locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel)));
+ button->setShadowPseudoId(AtomicString("-webkit-file-upload-button", AtomicString::ConstructFromLiteral));
element().userAgentShadowRoot()->appendChild(button.release());
}
@@ -265,15 +275,15 @@ void FileInputType::multipleAttributeChanged()
{
ASSERT(element().shadow());
if (Element* button = toElement(element().userAgentShadowRoot()->firstChild()))
- button->setAttribute(valueAttr, locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel));
+ button->setAttribute(valueAttr, AtomicString(locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel)));
}
-void FileInputType::setFiles(PassRefPtr<FileList> files)
+void FileInputType::setFiles(PassRefPtrWillBeRawPtr<FileList> files)
{
if (!files)
return;
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
bool pathsChanged = false;
if (files->length() != m_fileList->length()) {
@@ -289,21 +299,16 @@ void FileInputType::setFiles(PassRefPtr<FileList> files)
m_fileList = files;
- input->setFormControlValueMatchesRenderer(true);
input->notifyFormStateChanged();
input->setNeedsValidityCheck();
- Vector<String> paths;
- for (unsigned i = 0; i < m_fileList->length(); ++i)
- paths.append(m_fileList->item(i)->path());
-
if (input->renderer())
- input->renderer()->repaint();
+ input->renderer()->paintInvalidationForWholeRenderer();
if (pathsChanged) {
// This call may cause destruction of this instance.
// input instance is safe since it is ref-counted.
- input->HTMLElement::dispatchChangeEvent();
+ input->dispatchChangeEvent();
}
input->setChangedSinceLastFormControlChangeEvent(false);
}
@@ -335,7 +340,7 @@ bool FileInputType::receiveDroppedFiles(const DragData* dragData)
return false;
HTMLInputElement& input = element();
- if (input.fastHasAttribute(webkitdirectoryAttr) && RuntimeEnabledFeatures::directoryUploadEnabled()) {
+ if (input.fastHasAttribute(webkitdirectoryAttr)) {
receiveDropForDirectoryUpload(paths);
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h
index a91ba75e2be..68fc3342045 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h
@@ -34,6 +34,7 @@
#include "core/html/forms/BaseClickableWithKeyInputType.h"
#include "platform/FileChooser.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
@@ -41,9 +42,10 @@ namespace WebCore {
class DragData;
class FileList;
-class FileInputType : public BaseClickableWithKeyInputType, private FileChooserClient {
+class FileInputType FINAL : public BaseClickableWithKeyInputType, private FileChooserClient {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
+ virtual void trace(Visitor*) OVERRIDE;
static Vector<FileChooserFileInfo> filesFromFormControlState(const FormControlState&);
private:
@@ -58,7 +60,7 @@ private:
virtual RenderObject* createRenderer(RenderStyle*) const OVERRIDE;
virtual bool canSetStringValue() const OVERRIDE;
virtual FileList* files() OVERRIDE;
- virtual void setFiles(PassRefPtr<FileList>) OVERRIDE;
+ virtual void setFiles(PassRefPtrWillBeRawPtr<FileList>) OVERRIDE;
virtual bool canSetValue(const String&) OVERRIDE;
virtual bool getTypeSpecificValue(String&) OVERRIDE; // Checked first, before internal storage or the value attribute.
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE;
@@ -73,10 +75,10 @@ private:
// FileChooserClient implementation.
virtual void filesChosen(const Vector<FileChooserFileInfo>&) OVERRIDE;
- PassRefPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
+ PassRefPtrWillBeRawPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
void receiveDropForDirectoryUpload(const Vector<String>&);
- RefPtr<FileList> m_fileList;
+ RefPtrWillBeMember<FileList> m_fileList;
String m_droppedFileSystemId;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp b/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp
index a3cd9b02100..e4125bb7ed5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp
@@ -221,7 +221,7 @@ PassOwnPtr<SavedFormState> SavedFormState::deserialize(const Vector<String>& sta
FormControlState state = FormControlState::deserialize(stateVector, index);
if (type.isEmpty() || type.find(isNotFormControlTypeCharacter) != kNotFound || state.isFailure())
return nullptr;
- savedFormState->appendControlState(name, type, state);
+ savedFormState->appendControlState(AtomicString(name), AtomicString(type), state);
}
return savedFormState.release();
}
@@ -288,19 +288,20 @@ Vector<String> SavedFormState::getReferencedFilePaths() const
// ----------------------------------------------------------------------------
-class FormKeyGenerator {
+class FormKeyGenerator FINAL : public NoBaseWillBeGarbageCollectedFinalized<FormKeyGenerator> {
WTF_MAKE_NONCOPYABLE(FormKeyGenerator);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<FormKeyGenerator> create() { return adoptPtr(new FormKeyGenerator); }
+ static PassOwnPtrWillBeRawPtr<FormKeyGenerator> create() { return adoptPtrWillBeNoop(new FormKeyGenerator); }
+ void trace(Visitor* visitor) { visitor->trace(m_formToKeyMap); }
const AtomicString& formKey(const HTMLFormControlElementWithState&);
void willDeleteForm(HTMLFormElement*);
private:
FormKeyGenerator() { }
- typedef HashMap<HTMLFormElement*, AtomicString> FormToKeyMap;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<HTMLFormElement>, AtomicString> FormToKeyMap;
typedef HashMap<String, unsigned> FormSignatureToNextIndexMap;
FormToKeyMap m_formToKeyMap;
FormSignatureToNextIndexMap m_formSignatureToNextIndexMap;
@@ -310,7 +311,7 @@ static inline void recordFormStructure(const HTMLFormElement& form, StringBuilde
{
// 2 is enough to distinguish forms in webkit.org/b/91209#c0
const size_t namedControlsToBeRecorded = 2;
- const Vector<FormAssociatedElement*>& controls = form.associatedElements();
+ const FormAssociatedElement::List& controls = form.associatedElements();
builder.append(" [");
for (size_t i = 0, namedControls = 0; i < controls.size() && namedControls < namedControlsToBeRecorded; ++i) {
if (!controls[i]->isFormControlElementWithState())
@@ -333,7 +334,9 @@ static inline String formSignature(const HTMLFormElement& form)
KURL actionURL = form.getURLAttribute(actionAttr);
// Remove the query part because it might contain volatile parameters such
// as a session key.
- actionURL.setQuery(String());
+ if (!actionURL.isEmpty())
+ actionURL.setQuery(String());
+
StringBuilder builder;
if (!actionURL.isEmpty())
builder.append(actionURL.string());
@@ -356,14 +359,14 @@ const AtomicString& FormKeyGenerator::formKey(const HTMLFormControlElementWithSt
String signature = formSignature(*form);
ASSERT(!signature.isNull());
FormSignatureToNextIndexMap::AddResult result = m_formSignatureToNextIndexMap.add(signature, 0);
- unsigned nextIndex = result.iterator->value++;
+ unsigned nextIndex = result.storedValue->value++;
StringBuilder formKeyBuilder;
formKeyBuilder.append(signature);
formKeyBuilder.appendLiteral(" #");
formKeyBuilder.appendNumber(nextIndex);
FormToKeyMap::AddResult addFormKeyresult = m_formToKeyMap.add(form, formKeyBuilder.toAtomicString());
- return addFormKeyresult.iterator->value;
+ return addFormKeyresult.storedValue->value;
}
void FormKeyGenerator::willDeleteForm(HTMLFormElement* form)
@@ -374,12 +377,28 @@ void FormKeyGenerator::willDeleteForm(HTMLFormElement* form)
// ----------------------------------------------------------------------------
-FormController::FormController()
+PassRefPtrWillBeRawPtr<DocumentState> DocumentState::create()
{
+ return adoptRefWillBeNoop(new DocumentState);
}
-FormController::~FormController()
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentState)
+
+void DocumentState::trace(Visitor* visitor)
{
+ visitor->trace(m_formControls);
+}
+
+void DocumentState::addControl(HTMLFormControlElementWithState* control)
+{
+ ASSERT(!m_formControls.contains(control));
+ m_formControls.add(control);
+}
+
+void DocumentState::removeControl(HTMLFormControlElementWithState* control)
+{
+ RELEASE_ASSERT(m_formControls.contains(control));
+ m_formControls.remove(control);
}
static String formStateSignature()
@@ -391,28 +410,23 @@ static String formStateSignature()
return signature;
}
-PassOwnPtr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const FormElementListHashSet& controlList)
+Vector<String> DocumentState::toStateVector()
{
- OwnPtr<FormKeyGenerator> keyGenerator = FormKeyGenerator::create();
+ OwnPtrWillBeRawPtr<FormKeyGenerator> keyGenerator = FormKeyGenerator::create();
OwnPtr<SavedFormStateMap> stateMap = adoptPtr(new SavedFormStateMap);
- for (FormElementListHashSet::const_iterator it = controlList.begin(); it != controlList.end(); ++it) {
- HTMLFormControlElementWithState* control = (*it).get();
+ for (FormElementListHashSet::const_iterator it = m_formControls.begin(); it != m_formControls.end(); ++it) {
+ HTMLFormControlElementWithState* control = it->get();
ASSERT(control->inDocument());
if (!control->shouldSaveAndRestoreFormControlState())
continue;
SavedFormStateMap::AddResult result = stateMap->add(keyGenerator->formKey(*control), nullptr);
if (result.isNewEntry)
- result.iterator->value = SavedFormState::create();
- result.iterator->value->appendControlState(control->name(), control->type(), control->saveFormControlState());
+ result.storedValue->value = SavedFormState::create();
+ result.storedValue->value->appendControlState(control->name(), control->type(), control->saveFormControlState());
}
- return stateMap.release();
-}
-Vector<String> FormController::formElementsState() const
-{
- OwnPtr<SavedFormStateMap> stateMap = createSavedFormStateMap(m_formElementsWithState);
Vector<String> stateVector;
- stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 4);
+ stateVector.reserveInitialCapacity(m_formControls.size() * 4);
stateVector.append(formStateSignature());
for (SavedFormStateMap::const_iterator it = stateMap->begin(); it != stateMap->end(); ++it) {
stateVector.append(it->key);
@@ -424,6 +438,29 @@ Vector<String> FormController::formElementsState() const
return stateVector;
}
+// ----------------------------------------------------------------------------
+
+FormController::FormController()
+ : m_documentState(DocumentState::create())
+{
+}
+
+FormController::~FormController()
+{
+}
+
+void FormController::trace(Visitor* visitor)
+{
+ visitor->trace(m_radioButtonGroupScope);
+ visitor->trace(m_documentState);
+ visitor->trace(m_formKeyGenerator);
+}
+
+DocumentState* FormController::formElementsState() const
+{
+ return m_documentState.get();
+}
+
void FormController::setStateForNewFormElements(const Vector<String>& stateVector)
{
formStatesFromStateVector(stateVector, m_savedFormStateMap);
@@ -453,7 +490,7 @@ void FormController::formStatesFromStateVector(const Vector<String>& stateVector
return;
while (i + 1 < stateVector.size()) {
- AtomicString formKey = stateVector[i++];
+ AtomicString formKey = AtomicString(stateVector[i++]);
OwnPtr<SavedFormState> state = SavedFormState::deserialize(stateVector, i);
if (!state) {
i = 0;
@@ -487,7 +524,7 @@ void FormController::restoreControlStateFor(HTMLFormControlElementWithState& con
void FormController::restoreControlStateIn(HTMLFormElement& form)
{
- const Vector<FormAssociatedElement*>& elements = form.associatedElements();
+ const FormAssociatedElement::List& elements = form.associatedElements();
for (size_t i = 0; i < elements.size(); ++i) {
if (!elements[i]->isFormControlElementWithState())
continue;
@@ -508,20 +545,18 @@ Vector<String> FormController::getReferencedFilePaths(const Vector<String>& stat
SavedFormStateMap map;
formStatesFromStateVector(stateVector, map);
for (SavedFormStateMap::const_iterator it = map.begin(); it != map.end(); ++it)
- toReturn.append(it->value->getReferencedFilePaths());
+ toReturn.appendVector(it->value->getReferencedFilePaths());
return toReturn;
}
-void FormController::registerFormElementWithState(HTMLFormControlElementWithState* control)
+void FormController::registerStatefulFormControl(HTMLFormControlElementWithState& control)
{
- ASSERT(!m_formElementsWithState.contains(control));
- m_formElementsWithState.add(control);
+ m_documentState->addControl(&control);
}
-void FormController::unregisterFormElementWithState(HTMLFormControlElementWithState* control)
+void FormController::unregisterStatefulFormControl(HTMLFormControlElementWithState& control)
{
- RELEASE_ASSERT(m_formElementsWithState.contains(control));
- m_formElementsWithState.remove(control);
+ m_documentState->removeControl(&control);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FormController.h b/chromium/third_party/WebKit/Source/core/html/forms/FormController.h
index 40799358d55..0671fe8a2b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FormController.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FormController.h
@@ -22,7 +22,8 @@
#ifndef FormController_h
#define FormController_h
-#include "core/html/forms/CheckedRadioButtons.h"
+#include "core/html/forms/RadioButtonGroupScope.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/ListHashSet.h"
#include "wtf/Vector.h"
@@ -71,21 +72,39 @@ inline void FormControlState::append(const String& value)
m_values.append(value);
}
-class FormController {
- WTF_MAKE_FAST_ALLOCATED;
+typedef HashMap<AtomicString, OwnPtr<SavedFormState> > SavedFormStateMap;
+
+class DocumentState FINAL : public RefCountedWillBeGarbageCollected<DocumentState> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentState);
+public:
+ static PassRefPtrWillBeRawPtr<DocumentState> create();
+ void trace(Visitor*);
+
+ void addControl(HTMLFormControlElementWithState*);
+ void removeControl(HTMLFormControlElementWithState*);
+ Vector<String> toStateVector();
+
+private:
+ typedef WillBeHeapListHashSet<RefPtrWillBeMember<HTMLFormControlElementWithState>, 64> FormElementListHashSet;
+ FormElementListHashSet m_formControls;
+};
+
+class FormController FINAL : public NoBaseWillBeGarbageCollectedFinalized<FormController> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<FormController> create()
+ static PassOwnPtrWillBeRawPtr<FormController> create()
{
- return adoptPtr(new FormController);
+ return adoptPtrWillBeNoop(new FormController);
}
~FormController();
+ void trace(Visitor*);
- CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+ RadioButtonGroupScope& radioButtonGroupScope() { return m_radioButtonGroupScope; }
- void registerFormElementWithState(HTMLFormControlElementWithState*);
- void unregisterFormElementWithState(HTMLFormControlElementWithState*);
+ void registerStatefulFormControl(HTMLFormControlElementWithState&);
+ void unregisterStatefulFormControl(HTMLFormControlElementWithState&);
// This should be callled only by Document::formElementsState().
- Vector<String> formElementsState() const;
+ DocumentState* formElementsState() const;
// This should be callled only by Document::setStateForNewFormElements().
void setStateForNewFormElements(const Vector<String>&);
void willDeleteForm(HTMLFormElement*);
@@ -95,18 +114,14 @@ public:
static Vector<String> getReferencedFilePaths(const Vector<String>& stateVector);
private:
- typedef ListHashSet<RefPtr<HTMLFormControlElementWithState>, 64> FormElementListHashSet;
- typedef HashMap<AtomicString, OwnPtr<SavedFormState> > SavedFormStateMap;
-
FormController();
- static PassOwnPtr<SavedFormStateMap> createSavedFormStateMap(const FormElementListHashSet&);
FormControlState takeStateForFormElement(const HTMLFormControlElementWithState&);
static void formStatesFromStateVector(const Vector<String>&, SavedFormStateMap&);
- CheckedRadioButtons m_checkedRadioButtons;
- FormElementListHashSet m_formElementsWithState;
+ RadioButtonGroupScope m_radioButtonGroupScope;
+ RefPtrWillBeMember<DocumentState> m_documentState;
SavedFormStateMap m_savedFormStateMap;
- OwnPtr<FormKeyGenerator> m_formKeyGenerator;
+ OwnPtrWillBeMember<FormKeyGenerator> m_formKeyGenerator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp
index 7609742da68..abfbb551ab6 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp
@@ -32,8 +32,8 @@
#include "config.h"
#include "core/html/forms/HiddenInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/FormController.h"
@@ -43,9 +43,9 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<InputType> HiddenInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> HiddenInputType::create(HTMLInputElement& element)
{
- return adoptRef(new HiddenInputType(element));
+ return adoptRefWillBeNoop(new HiddenInputType(element));
}
const AtomicString& HiddenInputType::formControlType() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h
index a93b5c34fa7..70eeeb84e74 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class HiddenInputType : public InputType {
+class HiddenInputType FINAL : public InputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
HiddenInputType(HTMLInputElement& element) : InputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
index a8a8d5143ca..e10beef9621 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
@@ -23,8 +23,8 @@
#include "config.h"
#include "core/html/forms/ImageInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/MouseEvent.h"
#include "core/fetch/ImageResource.h"
#include "core/html/FormDataList.h"
@@ -45,9 +45,9 @@ inline ImageInputType::ImageInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> ImageInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ImageInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ImageInputType(element));
+ return adoptRefWillBeNoop(new ImageInputType(element));
}
const AtomicString& ImageInputType::formControlType() const
@@ -107,7 +107,7 @@ static IntPoint extractClickLocation(Event* event)
void ImageInputType::handleDOMActivateEvent(Event* event)
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (element->isDisabledFormControl() || !element->form())
return;
element->setActivatedSubmit(true);
@@ -150,9 +150,6 @@ void ImageInputType::startResourceLoading()
if (!renderer)
return;
- if (imageLoader->hasPendingBeforeLoadEvent())
- return;
-
RenderImageResource* imageResource = renderer->imageResource();
imageResource->setImageResource(imageLoader->image());
@@ -189,7 +186,7 @@ bool ImageInputType::shouldRespectHeightAndWidthAttributes()
unsigned ImageInputType::height() const
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (!element->renderer()) {
// Check the attribute first for an explicit pixel value.
@@ -213,7 +210,7 @@ unsigned ImageInputType::height() const
unsigned ImageInputType::width() const
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (!element->renderer()) {
// Check the attribute first for an explicit pixel value.
@@ -235,4 +232,14 @@ unsigned ImageInputType::width() const
return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0;
}
+bool ImageInputType::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || BaseButtonInputType::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& ImageInputType::subResourceAttributeName() const
+{
+ return srcAttr;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h
index d033e2a61c2..a81356d09f4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h
@@ -38,9 +38,9 @@
namespace WebCore {
-class ImageInputType : public BaseButtonInputType {
+class ImageInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
ImageInputType(HTMLInputElement&);
@@ -61,6 +61,8 @@ private:
virtual bool shouldRespectHeightAndWidthAttributes() OVERRIDE;
virtual unsigned height() const OVERRIDE;
virtual unsigned width() const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
IntPoint m_clickLocation; // Valid only during HTMLFormElement::prepareForSubmission().
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp
index c443f6d2025..f06d4056f52 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp
@@ -28,15 +28,18 @@
#include "config.h"
#include "core/html/forms/InputType.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/InputTypeNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/ScopedEventQueue.h"
#include "core/fileapi/FileList.h"
+#include "core/frame/FrameHost.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLShadowElement.h"
#include "core/html/forms/ButtonInputType.h"
#include "core/html/forms/CheckboxInputType.h"
#include "core/html/forms/ColorInputType.h"
@@ -61,9 +64,9 @@
#include "core/html/forms/URLInputType.h"
#include "core/html/forms/WeekInputType.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/html/shadow/HTMLShadowElement.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderTheme.h"
+#include "platform/ColorChooser.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/PlatformLocale.h"
#include "platform/text/TextBreakIterator.h"
@@ -71,9 +74,8 @@ namespace WebCore {
using blink::WebLocalizedString;
using namespace HTMLNames;
-using namespace std;
-typedef PassRefPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&);
+typedef PassRefPtrWillBeRawPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&);
typedef HashMap<AtomicString, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
@@ -81,8 +83,7 @@ static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
map->add(InputTypeNames::button, ButtonInputType::create);
map->add(InputTypeNames::checkbox, CheckboxInputType::create);
- if (RuntimeEnabledFeatures::inputTypeColorEnabled())
- map->add(InputTypeNames::color, ColorInputType::create);
+ map->add(InputTypeNames::color, ColorInputType::create);
map->add(InputTypeNames::date, DateInputType::create);
map->add(InputTypeNames::datetime_local, DateTimeLocalInputType::create);
map->add(InputTypeNames::email, EmailInputType::create);
@@ -100,8 +101,7 @@ static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
map->add(InputTypeNames::tel, TelephoneInputType::create);
map->add(InputTypeNames::time, TimeInputType::create);
map->add(InputTypeNames::url, URLInputType::create);
- if (RuntimeEnabledFeatures::inputTypeWeekEnabled())
- map->add(InputTypeNames::week, WeekInputType::create);
+ map->add(InputTypeNames::week, WeekInputType::create);
// No need to register "text" because it is the default type.
return map.release();
}
@@ -112,7 +112,7 @@ static const InputTypeFactoryMap* factoryMap()
return factoryMap;
}
-PassRefPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName)
+PassRefPtrWillBeRawPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName)
{
InputTypeFactoryFunction factory = typeName.isEmpty() ? 0 : factoryMap()->get(typeName);
if (!factory)
@@ -120,7 +120,7 @@ PassRefPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicS
return factory(element);
}
-PassRefPtr<InputType> InputType::createText(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> InputType::createText(HTMLInputElement& element)
{
return TextInputType::create(element);
}
@@ -133,25 +133,10 @@ const AtomicString& InputType::normalizeTypeName(const AtomicString& typeName)
return it == factoryMap()->end() ? InputTypeNames::text : it->key;
}
-bool InputType::canChangeFromAnotherType(const AtomicString& normalizedTypeName)
-{
- // 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 Blink, but this rule
- // still may be important for compatibility.
- return normalizedTypeName != InputTypeNames::file;
-}
-
InputType::~InputType()
{
}
-bool InputType::themeSupportsDataListUI(InputType* type)
-{
- return RenderTheme::theme().supportsDataListUI(type->formControlType());
-}
-
bool InputType::isTextField() const
{
return false;
@@ -210,22 +195,22 @@ double InputType::valueAsDate() const
void InputType::setValueAsDate(double, ExceptionState& exceptionState) const
{
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "This input element does not support Date values.");
}
double InputType::valueAsDouble() const
{
- return numeric_limits<double>::quiet_NaN();
+ return std::numeric_limits<double>::quiet_NaN();
}
void InputType::setValueAsDouble(double doubleValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- setValueAsDecimal(Decimal::fromDouble(doubleValue), eventBehavior, exceptionState);
+ exceptionState.throwDOMException(InvalidStateError, "This input element does not support Number values.");
}
-void InputType::setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionState& exceptionState) const
+void InputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState&) const
{
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ element().setValue(serialize(newValue), eventBehavior);
}
bool InputType::supportsValidation() const
@@ -437,12 +422,6 @@ Decimal InputType::parseToNumberOrNaN(const String& string) const
return parseToNumber(string, Decimal::nan());
}
-bool InputType::parseToDateComponents(const String&, DateComponents*) const
-{
- ASSERT_NOT_REACHED();
- return false;
-}
-
String InputType::serialize(const Decimal&) const
{
ASSERT_NOT_REACHED();
@@ -458,8 +437,8 @@ void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
Chrome* InputType::chrome() const
{
- if (Page* page = element().document().page())
- return &page->chrome();
+ if (FrameHost* host = element().document().frameHost())
+ return &host->chrome();
return 0;
}
@@ -534,7 +513,7 @@ FileList* InputType::files()
return 0;
}
-void InputType::setFiles(PassRefPtr<FileList>)
+void InputType::setFiles(PassRefPtrWillBeRawPtr<FileList>)
{
}
@@ -568,10 +547,15 @@ bool InputType::storesValueSeparateFromAttribute()
return true;
}
+bool InputType::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
+{
+ return !equalIgnoringNullity(oldValue, newValue);
+}
+
void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
{
element().setValueInternal(sanitizedValue, eventBehavior);
- element().setNeedsStyleRecalc();
+ element().setNeedsStyleRecalc(SubtreeStyleChange);
if (!valueChanged)
return;
switch (eventBehavior) {
@@ -619,11 +603,6 @@ String InputType::droppedFileSystemId()
return String();
}
-bool InputType::shouldResetOnDocumentActivation()
-{
- return false;
-}
-
bool InputType::shouldRespectListAttribute()
{
return false;
@@ -689,11 +668,6 @@ bool InputType::isNumberField() const
return false;
}
-bool InputType::isSubmitButton() const
-{
- return false;
-}
-
bool InputType::isTelephoneField() const
{
return false;
@@ -764,10 +738,6 @@ bool InputType::supportsReadOnly() const
return false;
}
-void InputType::updatePlaceholderText()
-{
-}
-
String InputType::defaultToolTip() const
{
return String();
@@ -783,6 +753,16 @@ void InputType::handleDOMActivateEvent(Event*)
{
}
+bool InputType::hasLegalLinkAttribute(const QualifiedName&) const
+{
+ return false;
+}
+
+const QualifiedName& InputType::subResourceAttributeName() const
+{
+ return QualifiedName::null();
+}
+
bool InputType::supportsIndeterminateAppearance() const
{
return false;
@@ -808,46 +788,64 @@ unsigned InputType::width() const
return 0;
}
-void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState)
+void InputType::applyStep(const Decimal& current, int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState)
{
StepRange stepRange(createStepRange(anyStepHandling));
if (!stepRange.hasStep()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "This form element does not have an allowed value step.");
return;
}
- const Decimal current = parseToNumberOrNaN(element().value());
- if (!current.isFinite()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
- Decimal newValue = current + stepRange.step() * count;
- if (!newValue.isFinite()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- const Decimal acceptableErrorValue = stepRange.acceptableError();
- if (newValue - stepRange.minimum() < -acceptableErrorValue) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
- if (newValue < stepRange.minimum())
- newValue = stepRange.minimum();
+ EventQueueScope scope;
+ const Decimal step = stepRange.step();
const AtomicString& stepString = element().fastGetAttribute(stepAttr);
- if (!equalIgnoringCase(stepString, "any"))
- newValue = stepRange.alignValueForStep(current, newValue);
+ if (!equalIgnoringCase(stepString, "any") && stepRange.stepMismatch(current)) {
+ // Snap-to-step / clamping steps
+ // If the current value is not matched to step value:
+ // - The value should be the larger matched value nearest to 0 if count > 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 5
+ // - The value should be the smaller matched value nearest to 0 if count < 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 2
+ //
+
+ ASSERT(!step.isZero());
+ Decimal newValue;
+ const Decimal base = stepRange.stepBase();
+ if (count < 0)
+ newValue = base + ((current - base) / step).floor() * step;
+ else if (count > 0)
+ newValue = base + ((current - base) / step).ceiling() * step;
+ else
+ newValue = current;
+
+ if (newValue < stepRange.minimum())
+ newValue = stepRange.minimum();
+ if (newValue > stepRange.maximum())
+ newValue = stepRange.maximum();
+
+ setValueAsDecimal(newValue, count == 1 || count == -1 ? DispatchChangeEvent : DispatchNoEvent, IGNORE_EXCEPTION);
+ if (count > 1) {
+ applyStep(newValue, count - 1, AnyIsDefaultStep, DispatchChangeEvent, IGNORE_EXCEPTION);
+ return;
+ }
+ if (count < -1) {
+ applyStep(newValue, count + 1, AnyIsDefaultStep, DispatchChangeEvent, IGNORE_EXCEPTION);
+ return;
+ }
+ } else {
+ Decimal newValue = current + stepRange.step() * count;
- if (newValue - stepRange.maximum() > acceptableErrorValue) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
- if (newValue > stepRange.maximum())
- newValue = stepRange.maximum();
+ if (!equalIgnoringCase(stepString, "any"))
+ newValue = stepRange.alignValueForStep(current, newValue);
- setValueAsDecimal(newValue, eventBehavior, exceptionState);
+ if (newValue > stepRange.maximum())
+ newValue = newValue - stepRange.step();
+ else if (newValue < stepRange.minimum())
+ newValue = newValue + stepRange.step();
+ setValueAsDecimal(newValue, eventBehavior, exceptionState);
+ }
if (AXObjectCache* cache = element().document().existingAXObjectCache())
cache->postNotification(&element(), AXObjectCache::AXValueChanged, true);
}
@@ -868,17 +866,18 @@ StepRange InputType::createStepRange(AnyStepHandling) const
void InputType::stepUp(int n, ExceptionState& exceptionState)
{
if (!isSteppable()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "This form element is not steppable.");
return;
}
- applyStep(n, RejectAny, DispatchNoEvent, exceptionState);
+ const Decimal current = parseToNumber(element().value(), 0);
+ applyStep(current, n, RejectAny, DispatchNoEvent, exceptionState);
}
void InputType::stepUpFromRenderer(int n)
{
- // The differences from stepUp()/stepDown():
+ // The only difference from stepUp()/stepDown() is the extra treatment
+ // of the current value before applying the step:
//
- // 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
@@ -902,13 +901,6 @@ void InputType::stepUpFromRenderer(int n)
// - 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(isSteppable());
@@ -936,8 +928,7 @@ void InputType::stepUpFromRenderer(int n)
else
sign = 0;
- String currentStringValue = element().value();
- Decimal current = parseToNumberOrNaN(currentStringValue);
+ Decimal current = parseToNumberOrNaN(element().value());
if (!current.isFinite()) {
current = defaultValueForStepUp();
const Decimal nextDiff = step * n;
@@ -948,33 +939,10 @@ void InputType::stepUpFromRenderer(int n)
setValueAsDecimal(current, DispatchNoEvent, IGNORE_EXCEPTION);
}
if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum())) {
- setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- } else {
- if (stepMismatch(element().value())) {
- ASSERT(!step.isZero());
- const Decimal base = stepRange.stepBase();
- Decimal newValue;
- if (sign < 0)
- newValue = base + ((current - base) / step).floor() * step;
- else if (sign > 0)
- newValue = base + ((current - base) / step).ceiling() * step;
- else
- newValue = current;
-
- if (newValue < stepRange.minimum())
- newValue = stepRange.minimum();
- if (newValue > stepRange.maximum())
- newValue = stepRange.maximum();
-
- setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent, IGNORE_EXCEPTION);
- if (n > 1)
- applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- else if (n < -1)
- applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- } else {
- applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- }
+ setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchChangeEvent, IGNORE_EXCEPTION);
+ return;
}
+ applyStep(current, n, AnyIsDefaultStep, DispatchChangeEvent, IGNORE_EXCEPTION);
}
void InputType::countUsageIfVisible(UseCounter::Feature feature) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputType.h b/chromium/third_party/WebKit/Source/core/html/forms/InputType.h
index 207abd8f305..fe0f4d33311 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputType.h
@@ -55,17 +55,14 @@ class Node;
// FIXME: InputType should not inherit InputTypeView. It's conceptually wrong.
class InputType : public InputTypeView {
WTF_MAKE_NONCOPYABLE(InputType);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<InputType> create(HTMLInputElement&, const AtomicString&);
- static PassRefPtr<InputType> createText(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&, const AtomicString&);
+ static PassRefPtrWillBeRawPtr<InputType> createText(HTMLInputElement&);
static const AtomicString& normalizeTypeName(const AtomicString&);
virtual ~InputType();
- static bool canChangeFromAnotherType(const AtomicString& normalizedTypeName);
- static bool themeSupportsDataListUI(InputType*);
-
virtual const AtomicString& formControlType() const = 0;
// Type query functions
@@ -92,7 +89,6 @@ public:
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;
@@ -172,7 +168,7 @@ public:
virtual void sanitizeValueInResponseToMinOrMaxAttributeChange();
virtual bool shouldRespectAlignAttribute();
virtual FileList* files();
- virtual void setFiles(PassRefPtr<FileList>);
+ virtual void setFiles(PassRefPtrWillBeRawPtr<FileList>);
// Should return true if the given DragData has more than one dropped files.
virtual bool receiveDroppedFiles(const DragData*);
virtual String droppedFileSystemId();
@@ -182,7 +178,6 @@ public:
virtual bool canSetValue(const String&);
virtual bool storesValueSeparateFromAttribute();
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior);
- virtual bool shouldResetOnDocumentActivation();
virtual bool shouldRespectListAttribute();
virtual bool shouldRespectSpeechAttribute();
virtual bool isEnumeratable();
@@ -191,10 +186,11 @@ public:
virtual bool shouldRespectHeightAndWidthAttributes();
virtual bool supportsPlaceholder() const;
virtual bool supportsReadOnly() const;
- virtual void updatePlaceholderText();
virtual String defaultToolTip() const;
virtual Decimal findClosestTickMarkValue(const Decimal&);
virtual void handleDOMActivateEvent(Event*);
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const;
+ virtual const QualifiedName& subResourceAttributeName() const;
// Parses the specified string for the type, and return
// the Decimal value for the parsing result if the parsing
@@ -202,12 +198,6 @@ public:
// return NaN or Infinity only if defaultValue is NaN or Infinity.
virtual Decimal parseToNumber(const String&, const Decimal& defaultValue) 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 Decimal 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.
@@ -230,6 +220,8 @@ public:
virtual bool shouldSubmitImplicitly(Event*) OVERRIDE;
virtual bool hasCustomFocusLogic() const OVERRIDE;
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&);
+
protected:
InputType(HTMLInputElement& element) : InputTypeView(element) { }
Chrome* chrome() const;
@@ -244,7 +236,7 @@ protected:
private:
// Helper for stepUp()/stepDown(). Adds step value * count to the current value.
- void applyStep(int count, AnyStepHandling, TextFieldEventBehavior, ExceptionState&);
+ void applyStep(const Decimal&, int count, AnyStepHandling, TextFieldEventBehavior, ExceptionState&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp
index d8c49395104..8e8aee3e27f 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp
@@ -35,15 +35,20 @@
namespace WebCore {
-PassRefPtr<InputTypeView> InputTypeView::create(HTMLInputElement& input)
+PassRefPtrWillBeRawPtr<InputTypeView> InputTypeView::create(HTMLInputElement& input)
{
- return adoptRef(new InputTypeView(input));
+ return adoptRefWillBeNoop(new InputTypeView(input));
}
InputTypeView::~InputTypeView()
{
}
+void InputTypeView::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+}
+
bool InputTypeView::sizeShouldIncludeDecoration(int, int& preferredSize) const
{
preferredSize = element().size();
@@ -87,7 +92,7 @@ bool InputTypeView::shouldSubmitImplicitly(Event* event)
return false;
}
-PassRefPtr<HTMLFormElement> InputTypeView::formForSubmission() const
+PassRefPtrWillBeRawPtr<HTMLFormElement> InputTypeView::formForSubmission() const
{
return element().form();
}
@@ -112,7 +117,7 @@ bool InputTypeView::hasCustomFocusLogic() const
return false;
}
-void InputTypeView::handleFocusEvent(Element*, FocusDirection)
+void InputTypeView::handleFocusEvent(Element*, FocusType)
{
}
@@ -154,7 +159,7 @@ void InputTypeView::stepAttributeChanged()
{
}
-PassOwnPtr<ClickHandlingState> InputTypeView::willDispatchClick()
+PassOwnPtrWillBeRawPtr<ClickHandlingState> InputTypeView::willDispatchClick()
{
return nullptr;
}
@@ -209,4 +214,13 @@ void InputTypeView::updateClearButtonVisibility()
{
}
+void InputTypeView::updatePlaceholderText()
+{
+}
+
+void ClickHandlingState::trace(Visitor* visitor)
+{
+ visitor->trace(checkedRadioButton);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h
index 1e4aec4f20a..808fde90803 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h
@@ -33,7 +33,8 @@
#ifndef InputTypeView_h
#define InputTypeView_h
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
@@ -53,30 +54,33 @@ class RenderObject;
class RenderStyle;
class TouchEvent;
-struct ClickHandlingState {
- WTF_MAKE_FAST_ALLOCATED;
+struct ClickHandlingState FINAL : public NoBaseWillBeGarbageCollected<ClickHandlingState> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
+ void trace(Visitor*);
+
bool checked;
bool indeterminate;
- RefPtr<HTMLInputElement> checkedRadioButton;
+ RefPtrWillBeMember<HTMLInputElement> checkedRadioButton;
};
// An InputTypeView object represents the UI-specific part of an
// HTMLInputElement. Do not expose instances of InputTypeView and classes
// derived from it to classes other than HTMLInputElement.
-class InputTypeView : public RefCounted<InputTypeView> {
+class InputTypeView : public RefCountedWillBeGarbageCollectedFinalized<InputTypeView> {
WTF_MAKE_NONCOPYABLE(InputTypeView);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<InputTypeView> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputTypeView> create(HTMLInputElement&);
virtual ~InputTypeView();
+ virtual void trace(Visitor*);
virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
virtual void handleClickEvent(MouseEvent*);
virtual void handleMouseDownEvent(MouseEvent*);
- virtual PassOwnPtr<ClickHandlingState> willDispatchClick();
+ virtual PassOwnPtrWillBeRawPtr<ClickHandlingState> willDispatchClick();
virtual void didDispatchClick(Event*, const ClickHandlingState&);
virtual void handleKeydownEvent(KeyboardEvent*);
virtual void handleKeypressEvent(KeyboardEvent*);
@@ -85,9 +89,9 @@ public:
virtual void handleTouchEvent(TouchEvent*);
virtual void forwardEvent(Event*);
virtual bool shouldSubmitImplicitly(Event*);
- virtual PassRefPtr<HTMLFormElement> formForSubmission() const;
+ virtual PassRefPtrWillBeRawPtr<HTMLFormElement> formForSubmission() const;
virtual bool hasCustomFocusLogic() const;
- virtual void handleFocusEvent(Element* oldFocusedElement, FocusDirection);
+ virtual void handleFocusEvent(Element* oldFocusedElement, FocusType);
virtual void handleBlurEvent();
virtual void subtreeHasChanged();
virtual bool hasTouchEventHandler() const;
@@ -111,15 +115,16 @@ public:
virtual void valueAttributeChanged();
virtual void listAttributeTargetChanged();
virtual void updateClearButtonVisibility();
+ virtual void updatePlaceholderText();
protected:
- InputTypeView(HTMLInputElement& element) : m_element(element) { }
- HTMLInputElement& element() const { return m_element; }
+ InputTypeView(HTMLInputElement& element) : m_element(&element) { }
+ HTMLInputElement& element() const { return *m_element; }
private:
// Not a RefPtr because the HTMLInputElement object owns this InputTypeView
// object.
- HTMLInputElement& m_element;
+ RawPtrWillBeMember<HTMLInputElement> m_element;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp
index 647ac351770..27800a016ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/MonthInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -51,9 +51,9 @@ static const int monthDefaultStep = 1;
static const int monthDefaultStepBase = 0;
static const int monthStepScaleFactor = 1;
-PassRefPtr<InputType> MonthInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> MonthInputType::create(HTMLInputElement& element)
{
- return adoptRef(new MonthInputType(element));
+ return adoptRefWillBeNoop(new MonthInputType(element));
}
void MonthInputType::countUsage()
@@ -134,6 +134,11 @@ bool MonthInputType::isMonthField() const
return true;
}
+bool MonthInputType::canSetSuggestedValue()
+{
+ return true;
+}
+
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
String MonthInputType::formatDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState) const
{
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h
index ee2bbf2bf24..34fd57227a7 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h
@@ -42,9 +42,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseMonthInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseMonthInputType;
#endif
-class MonthInputType : public BaseMonthInputType {
+class MonthInputType FINAL : public BaseMonthInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
MonthInputType(HTMLInputElement& element) : BaseMonthInputType(element) { }
@@ -58,12 +58,13 @@ private:
virtual bool parseToDateComponentsInternal(const String&, DateComponents*) const OVERRIDE;
virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
virtual bool isMonthField() const OVERRIDE;
+ virtual bool canSetSuggestedValue() OVERRIDE;
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
// BaseMultipleFieldsDateAndTimeInputType functions
- virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
- virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE FINAL;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
+ virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp
index e2d90015378..a1a3eed20a9 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp
@@ -32,9 +32,9 @@
#include "config.h"
#include "core/html/forms/NumberInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/events/KeyboardEvent.h"
#include "core/html/HTMLInputElement.h"
@@ -49,7 +49,6 @@ namespace WebCore {
using blink::WebLocalizedString;
using namespace HTMLNames;
-using namespace std;
static const int numberDefaultStep = 1;
static const int numberDefaultStepBase = 0;
@@ -94,9 +93,9 @@ static RealNumberRenderSize calculateRenderSize(const Decimal& value)
return RealNumberRenderSize(sizeOfSign + sizeOfZero , numberOfZeroAfterDecimalPoint + sizeOfDigits);
}
-PassRefPtr<InputType> NumberInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> NumberInputType::create(HTMLInputElement& element)
{
- return adoptRef(new NumberInputType(element));
+ return adoptRefWillBeNoop(new NumberInputType(element));
}
void NumberInputType::countUsage()
@@ -111,8 +110,8 @@ const AtomicString& NumberInputType::formControlType() const
void NumberInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
{
- if (!valueChanged && sanitizedValue.isEmpty() && !element().innerTextValue().isEmpty())
- updateView();
+ if (!valueChanged && sanitizedValue.isEmpty() && !element().innerEditorValue().isEmpty())
+ element().updateView();
TextFieldInputType::setValue(sanitizedValue, valueChanged, eventBehavior);
}
@@ -123,23 +122,11 @@ double NumberInputType::valueAsDouble() const
void NumberInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const double floatMax = numeric_limits<float>::max();
- if (newValue < -floatMax || newValue > floatMax) {
- exceptionState.throwDOMException(InvalidStateError, "The value provided (" + String::number(newValue) + ") is outside the range (" + String::number(-floatMax) + ", " + String::number(floatMax) + ").");
- return;
- }
element().setValue(serializeForNumberType(newValue), eventBehavior);
}
void NumberInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const Decimal floatMax = Decimal::fromDouble(numeric_limits<float>::max());
- if (newValue < -floatMax || newValue > floatMax) {
- exceptionState.throwDOMException(InvalidStateError, "The value provided (" + newValue.toString() + ") is outside the range (-" + floatMax.toString() + ", " + floatMax.toString() + ").");
- return;
- }
element().setValue(serializeForNumberType(newValue), eventBehavior);
}
@@ -157,10 +144,8 @@ bool NumberInputType::typeMismatch() const
StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor));
-
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const Decimal floatMax = Decimal::fromDouble(numeric_limits<float>::max());
- return InputType::createStepRange(anyStepHandling, numberDefaultStepBase, -floatMax, floatMax, stepDescription);
+ const Decimal doubleMax = Decimal::fromDouble(std::numeric_limits<double>::max());
+ return InputType::createStepRange(anyStepHandling, numberDefaultStepBase, -doubleMax, doubleMax, stepDescription);
}
bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
@@ -252,7 +237,7 @@ String NumberInputType::sanitizeValue(const String& proposedValue) const
bool NumberInputType::hasBadInput() const
{
- String standardValue = convertFromVisibleValue(element().innerTextValue());
+ String standardValue = convertFromVisibleValue(element().innerEditorValue());
return !standardValue.isEmpty() && !std::isfinite(parseToDoubleForNumberType(standardValue));
}
@@ -291,7 +276,7 @@ void NumberInputType::minOrMaxAttributeChanged()
InputType::minOrMaxAttributeChanged();
if (element().renderer())
- element().renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ element().renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void NumberInputType::stepAttributeChanged()
@@ -299,7 +284,7 @@ void NumberInputType::stepAttributeChanged()
InputType::stepAttributeChanged();
if (element().renderer())
- element().renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ element().renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
bool NumberInputType::supportsSelectionAPI() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h
index 35711e3f9f6..be04ad8b53f 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h
@@ -37,9 +37,9 @@ namespace WebCore {
class ExceptionState;
-class NumberInputType : public TextFieldInputType {
+class NumberInputType FINAL : public TextFieldInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
NumberInputType(HTMLInputElement& element) : TextFieldInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp
index 6da205be0cc..4c974f03c21 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp
@@ -32,24 +32,18 @@
#include "config.h"
#include "core/html/forms/PasswordInputType.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "InputTypeNames.h"
-#include "core/dom/shadow/ShadowRoot.h"
+#include "core/InputTypeNames.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/FormController.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "wtf/Assertions.h"
-#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
namespace WebCore {
-PassRefPtr<InputType> PasswordInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> PasswordInputType::create(HTMLInputElement& element)
{
- return adoptRef(new PasswordInputType(element));
+ return adoptRefWillBeNoop(new PasswordInputType(element));
}
void PasswordInputType::countUsage()
@@ -59,38 +53,6 @@ void PasswordInputType::countUsage()
countUsageIfVisible(UseCounter::InputTypePasswordMaxLength);
}
-bool PasswordInputType::isPasswordGenerationEnabled() const
-{
- if (isPasswordGenerationDecorationEnabled())
- return true;
- if (Page* page = element().document().page())
- return page->chrome().client().isPasswordGenerationEnabled();
- return false;
-}
-
-bool PasswordInputType::isPasswordGenerationDecorationEnabled() const
-{
- if (Page* page = element().document().page())
- return page->settings().passwordGenerationDecorationEnabled();
- return false;
-}
-
-bool PasswordInputType::needsContainer() const
-{
- return BaseTextInputType::needsContainer() || isPasswordGenerationEnabled();
-}
-
-void PasswordInputType::createShadowSubtree()
-{
- BaseTextInputType::createShadowSubtree();
- if (!isPasswordGenerationEnabled())
- return;
- RefPtr<PasswordGeneratorButtonElement> generatorButton = PasswordGeneratorButtonElement::create(element().document());
- if (!isPasswordGenerationDecorationEnabled())
- generatorButton->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
- containerElement()->appendChild(generatorButton.release());
-}
-
const AtomicString& PasswordInputType::formControlType() const
{
return InputTypeNames::password;
@@ -121,11 +83,6 @@ bool PasswordInputType::shouldUseInputMethod() const
return false;
}
-bool PasswordInputType::shouldResetOnDocumentActivation()
-{
- return true;
-}
-
bool PasswordInputType::shouldRespectListAttribute()
{
return false;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h
index 50f36691e0d..441cd99a171 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h
@@ -32,34 +32,26 @@
#define PasswordInputType_h
#include "core/html/forms/BaseTextInputType.h"
-#include "core/html/shadow/PasswordGeneratorButtonElement.h"
namespace WebCore {
class PasswordInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
PasswordInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
- virtual bool needsContainer() const OVERRIDE;
- virtual void createShadowSubtree() OVERRIDE;
virtual void countUsage() OVERRIDE;
virtual const AtomicString& formControlType() const OVERRIDE;
virtual bool shouldSaveAndRestoreFormControlState() const OVERRIDE;
virtual FormControlState saveFormControlState() const OVERRIDE;
virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
virtual bool shouldUseInputMethod() const OVERRIDE;
- virtual bool shouldResetOnDocumentActivation() OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual bool shouldRespectSpeechAttribute() OVERRIDE;
virtual bool isPasswordField() const OVERRIDE;
virtual void enableSecureTextInput() OVERRIDE;
virtual void disableSecureTextInput() OVERRIDE;
-
- bool isPasswordGenerationEnabled() const;
- // For testing.
- bool isPasswordGenerationDecorationEnabled() const;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
index 58850fb8e11..92909e3a87a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
@@ -19,17 +19,17 @@
*/
#include "config.h"
-#include "core/html/forms/CheckedRadioButtons.h"
+#include "core/html/forms/RadioButtonGroupScope.h"
#include "core/html/HTMLInputElement.h"
#include "wtf/HashSet.h"
namespace WebCore {
-class RadioButtonGroup {
- WTF_MAKE_FAST_ALLOCATED;
+class RadioButtonGroup : public NoBaseWillBeGarbageCollected<RadioButtonGroup> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<RadioButtonGroup> create();
+ static PassOwnPtrWillBeRawPtr<RadioButtonGroup> create();
bool isEmpty() const { return m_members.isEmpty(); }
bool isRequired() const { return m_requiredCount; }
HTMLInputElement* checkedButton() const { return m_checkedButton; }
@@ -39,26 +39,28 @@ public:
void remove(HTMLInputElement*);
bool contains(HTMLInputElement*) const;
+ void trace(Visitor*);
+
private:
RadioButtonGroup();
void setNeedsValidityCheckForAllButtons();
bool isValid() const;
void setCheckedButton(HTMLInputElement*);
- HashSet<HTMLInputElement*> m_members;
- HTMLInputElement* m_checkedButton;
+ WillBeHeapHashSet<RawPtrWillBeMember<HTMLInputElement> > m_members;
+ RawPtrWillBeMember<HTMLInputElement> m_checkedButton;
size_t m_requiredCount;
};
RadioButtonGroup::RadioButtonGroup()
- : m_checkedButton(0)
+ : m_checkedButton(nullptr)
, m_requiredCount(0)
{
}
-PassOwnPtr<RadioButtonGroup> RadioButtonGroup::create()
+PassOwnPtrWillBeRawPtr<RadioButtonGroup> RadioButtonGroup::create()
{
- return adoptPtr(new RadioButtonGroup);
+ return adoptPtrWillBeNoop(new RadioButtonGroup);
}
inline bool RadioButtonGroup::isValid() const
@@ -106,7 +108,7 @@ void RadioButtonGroup::updateCheckedState(HTMLInputElement* button)
setCheckedButton(button);
} else {
if (m_checkedButton == button)
- m_checkedButton = 0;
+ m_checkedButton = nullptr;
}
if (wasValid != isValid())
setNeedsValidityCheckForAllButtons();
@@ -130,7 +132,7 @@ void RadioButtonGroup::requiredAttributeChanged(HTMLInputElement* button)
void RadioButtonGroup::remove(HTMLInputElement* button)
{
ASSERT(button->isRadioButton());
- HashSet<HTMLInputElement*>::iterator it = m_members.find(button);
+ WillBeHeapHashSet<RawPtrWillBeMember<HTMLInputElement> >::iterator it = m_members.find(button);
if (it == m_members.end())
return;
bool wasValid = isValid();
@@ -140,7 +142,7 @@ void RadioButtonGroup::remove(HTMLInputElement* button)
--m_requiredCount;
}
if (m_checkedButton == button)
- m_checkedButton = 0;
+ m_checkedButton = nullptr;
if (m_members.isEmpty()) {
ASSERT(!m_requiredCount);
@@ -157,7 +159,7 @@ void RadioButtonGroup::remove(HTMLInputElement* button)
void RadioButtonGroup::setNeedsValidityCheckForAllButtons()
{
- typedef HashSet<HTMLInputElement*>::const_iterator Iterator;
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<HTMLInputElement> >::const_iterator Iterator;
Iterator end = m_members.end();
for (Iterator it = m_members.begin(); it != end; ++it) {
HTMLInputElement* button = *it;
@@ -171,35 +173,41 @@ bool RadioButtonGroup::contains(HTMLInputElement* button) const
return m_members.contains(button);
}
+void RadioButtonGroup::trace(Visitor* visitor)
+{
+ visitor->trace(m_members);
+ visitor->trace(m_checkedButton);
+}
+
// ----------------------------------------------------------------
// Explicity define empty constructor and destructor in order to prevent the
// compiler from generating them as inlines. So we don't need to to define
// RadioButtonGroup in the header.
-CheckedRadioButtons::CheckedRadioButtons()
+RadioButtonGroupScope::RadioButtonGroupScope()
{
}
-CheckedRadioButtons::~CheckedRadioButtons()
+RadioButtonGroupScope::~RadioButtonGroupScope()
{
}
-void CheckedRadioButtons::addButton(HTMLInputElement* element)
+void RadioButtonGroupScope::addButton(HTMLInputElement* element)
{
ASSERT(element->isRadioButton());
if (element->name().isEmpty())
return;
if (!m_nameToGroupMap)
- m_nameToGroupMap = adoptPtr(new NameToGroupMap);
+ m_nameToGroupMap = adoptPtrWillBeNoop(new NameToGroupMap);
- OwnPtr<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name().impl(), PassOwnPtr<RadioButtonGroup>()).iterator->value;
+ OwnPtrWillBeMember<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name(), nullptr).storedValue->value;
if (!group)
group = RadioButtonGroup::create();
group->add(element);
}
-void CheckedRadioButtons::updateCheckedState(HTMLInputElement* element)
+void RadioButtonGroupScope::updateCheckedState(HTMLInputElement* element)
{
ASSERT(element->isRadioButton());
if (element->name().isEmpty())
@@ -207,12 +215,12 @@ void CheckedRadioButtons::updateCheckedState(HTMLInputElement* element)
ASSERT(m_nameToGroupMap);
if (!m_nameToGroupMap)
return;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
ASSERT(group);
group->updateCheckedState(element);
}
-void CheckedRadioButtons::requiredAttributeChanged(HTMLInputElement* element)
+void RadioButtonGroupScope::requiredAttributeChanged(HTMLInputElement* element)
{
ASSERT(element->isRadioButton());
if (element->name().isEmpty())
@@ -220,31 +228,31 @@ void CheckedRadioButtons::requiredAttributeChanged(HTMLInputElement* element)
ASSERT(m_nameToGroupMap);
if (!m_nameToGroupMap)
return;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
ASSERT(group);
group->requiredAttributeChanged(element);
}
-HTMLInputElement* CheckedRadioButtons::checkedButtonForGroup(const AtomicString& name) const
+HTMLInputElement* RadioButtonGroupScope::checkedButtonForGroup(const AtomicString& name) const
{
if (!m_nameToGroupMap)
return 0;
- RadioButtonGroup* group = m_nameToGroupMap->get(name.impl());
+ RadioButtonGroup* group = m_nameToGroupMap->get(name);
return group ? group->checkedButton() : 0;
}
-bool CheckedRadioButtons::isInRequiredGroup(HTMLInputElement* element) const
+bool RadioButtonGroupScope::isInRequiredGroup(HTMLInputElement* element) const
{
ASSERT(element->isRadioButton());
if (element->name().isEmpty())
return false;
if (!m_nameToGroupMap)
return false;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
return group && group->isRequired() && group->contains(element);
}
-void CheckedRadioButtons::removeButton(HTMLInputElement* element)
+void RadioButtonGroupScope::removeButton(HTMLInputElement* element)
{
ASSERT(element->isRadioButton());
if (element->name().isEmpty())
@@ -252,18 +260,23 @@ void CheckedRadioButtons::removeButton(HTMLInputElement* element)
if (!m_nameToGroupMap)
return;
- NameToGroupMap::iterator it = m_nameToGroupMap->find(element->name().impl());
- if (it == m_nameToGroupMap->end())
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ if (!group)
return;
- it->value->remove(element);
- if (it->value->isEmpty()) {
- // FIXME: We may skip deallocating the empty RadioButtonGroup for
- // performance improvement. If we do so, we need to change the key type
- // of m_nameToGroupMap from StringImpl* to AtomicString.
- m_nameToGroupMap->remove(it);
- if (m_nameToGroupMap->isEmpty())
- m_nameToGroupMap.clear();
+ group->remove(element);
+ if (group->isEmpty()) {
+ // We don't remove an empty RadioButtonGroup from m_nameToGroupMap for
+ // better performance.
+ ASSERT(!group->isRequired());
+ ASSERT_WITH_SECURITY_IMPLICATION(!group->checkedButton());
}
}
+void RadioButtonGroupScope::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_nameToGroupMap);
+#endif
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h
index 6a1585bd5aa..41f9bbc7696 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h
@@ -18,9 +18,10 @@
*
*/
-#ifndef CheckedRadioButtons_h
-#define CheckedRadioButtons_h
+#ifndef RadioButtonGroupScope_h
+#define RadioButtonGroupScope_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/OwnPtr.h"
@@ -31,12 +32,12 @@ namespace WebCore {
class HTMLInputElement;
class RadioButtonGroup;
-// FIXME: Rename the class. The class was a simple map from a name to a checked
-// radio button. It manages RadioButtonGroup objects now.
-class CheckedRadioButtons {
+class RadioButtonGroupScope {
+ DISALLOW_ALLOCATION();
public:
- CheckedRadioButtons();
- ~CheckedRadioButtons();
+ RadioButtonGroupScope();
+ ~RadioButtonGroupScope();
+ void trace(Visitor*);
void addButton(HTMLInputElement*);
void updateCheckedState(HTMLInputElement*);
void requiredAttributeChanged(HTMLInputElement*);
@@ -45,10 +46,10 @@ public:
bool isInRequiredGroup(HTMLInputElement*) const;
private:
- typedef HashMap<StringImpl*, OwnPtr<RadioButtonGroup> > NameToGroupMap;
- OwnPtr<NameToGroupMap> m_nameToGroupMap;
+ typedef WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<RadioButtonGroup>, CaseFoldingHash> NameToGroupMap;
+ OwnPtrWillBeMember<NameToGroupMap> m_nameToGroupMap;
};
} // namespace WebCore
-#endif // CheckedRadioButtons_h
+#endif // RadioButtonGroupScope_h
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
index fc6da4939fa..9a495ce2446 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
@@ -22,9 +22,10 @@
#include "config.h"
#include "core/html/forms/RadioInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
+#include "core/dom/Document.h"
+#include "core/dom/ElementTraversal.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
#include "core/html/HTMLInputElement.h"
@@ -36,9 +37,9 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<InputType> RadioInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> RadioInputType::create(HTMLInputElement& element)
{
- return adoptRef(new RadioInputType(element));
+ return adoptRefWillBeNoop(new RadioInputType(element));
}
const AtomicString& RadioInputType::formControlType() const
@@ -83,19 +84,19 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
// We can only stay within the form's children if the form hasn't been demoted to a leaf because
// of malformed HTML.
- Node* node = &element();
- while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) {
+ HTMLElement* htmlElement = &element();
+ while ((htmlElement = (forward ? Traversal<HTMLElement>::next(*htmlElement) : Traversal<HTMLElement>::previous(*htmlElement)))) {
// Once we encounter a form element, we know we're through.
- if (node->hasTagName(formTag))
+ if (isHTMLFormElement(*htmlElement))
break;
// Look for more radio buttons.
- if (!node->hasTagName(inputTag))
+ if (!isHTMLInputElement(*htmlElement))
continue;
- HTMLInputElement* inputElement = toHTMLInputElement(node);
+ HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
if (inputElement->form() != element().form())
break;
if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) {
- RefPtr<HTMLInputElement> protector(inputElement);
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(inputElement);
document.setFocusedElement(inputElement);
inputElement->dispatchSimulatedClick(event, SendNoEvents);
event->setDefaultHandled();
@@ -128,9 +129,9 @@ bool RadioInputType::isKeyboardFocusable() const
// Never allow keyboard tabbing to leave you in the same radio group. Always
// skip any other elements in the group.
Element* currentFocusedElement = element().document().focusedElement();
- if (currentFocusedElement && currentFocusedElement->hasTagName(inputTag)) {
- HTMLInputElement* focusedInput = toHTMLInputElement(currentFocusedElement);
- if (focusedInput->isRadioButton() && focusedInput->form() == element().form() && focusedInput->name() == element().name())
+ if (isHTMLInputElement(currentFocusedElement)) {
+ HTMLInputElement& focusedInput = toHTMLInputElement(*currentFocusedElement);
+ if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name())
return false;
}
@@ -145,7 +146,7 @@ bool RadioInputType::shouldSendChangeEventAfterCheckedChanged()
return element().checked();
}
-PassOwnPtr<ClickHandlingState> RadioInputType::willDispatchClick()
+PassOwnPtrWillBeRawPtr<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.
@@ -154,7 +155,7 @@ PassOwnPtr<ClickHandlingState> RadioInputType::willDispatchClick()
// 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);
+ OwnPtrWillBeRawPtr<ClickHandlingState> state = adoptPtrWillBeNoop(new ClickHandlingState);
state->checked = element().checked();
state->checkedRadioButton = element().checkedRadioButtonForGroup();
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h
index 09788e2033a..2f965eeef20 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class RadioInputType : public BaseCheckableInputType {
+class RadioInputType FINAL : public BaseCheckableInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
RadioInputType(HTMLInputElement& element) : BaseCheckableInputType(element) { }
@@ -49,7 +49,7 @@ private:
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
virtual bool shouldSendChangeEventAfterCheckedChanged() OVERRIDE;
- virtual PassOwnPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
+ virtual PassOwnPtrWillBeRawPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
virtual void didDispatchClick(Event*, const ClickHandlingState&) OVERRIDE;
virtual bool isRadioButton() const OVERRIDE;
virtual bool supportsIndeterminateAppearance() const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
index 561a6504777..a6c0d34b3b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
@@ -32,9 +32,9 @@
#include "config.h"
#include "core/html/forms/RangeInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
@@ -61,7 +61,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
static const int rangeDefaultMinimum = 0;
static const int rangeDefaultMaximum = 100;
@@ -74,9 +73,9 @@ static Decimal ensureMaximum(const Decimal& proposedValue, const Decimal& minimu
return proposedValue >= minimum ? proposedValue : std::max(minimum, fallbackValue);
}
-PassRefPtr<InputType> RangeInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> RangeInputType::create(HTMLInputElement& element)
{
- return adoptRef(new RangeInputType(element));
+ return adoptRefWillBeNoop(new RangeInputType(element));
}
RangeInputType::RangeInputType(HTMLInputElement& element)
@@ -105,9 +104,9 @@ double RangeInputType::valueAsDouble() const
return parseToDoubleForNumberType(element().value());
}
-void RangeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState&) const
+void RangeInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- element().setValue(serialize(newValue), eventBehavior);
+ setValueAsDecimal(Decimal::fromDouble(newValue), eventBehavior, exceptionState);
}
bool RangeInputType::typeMismatchFor(const String& value) const
@@ -124,17 +123,12 @@ StepRange RangeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor));
+ const Decimal stepBase = findStepBase(rangeDefaultStepBase);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), rangeDefaultMinimum);
const Decimal maximum = ensureMaximum(parseToNumber(element().fastGetAttribute(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum);
- const AtomicString& precisionValue = element().fastGetAttribute(precisionAttr);
- if (!precisionValue.isNull()) {
- const Decimal step = equalIgnoringCase(precisionValue, "float") ? Decimal::nan() : 1;
- return StepRange(minimum, minimum, maximum, step, stepDescription);
- }
-
const Decimal step = StepRange::parseStep(anyStepHandling, stepDescription, element().fastGetAttribute(stepAttr));
- return StepRange(minimum, minimum, maximum, step, stepDescription);
+ return StepRange(stepBase, minimum, maximum, step, stepDescription);
}
bool RangeInputType::isSteppable() const
@@ -165,6 +159,7 @@ void RangeInputType::handleTouchEvent(TouchEvent* event)
return;
if (event->type() == EventTypeNames::touchend) {
+ element().dispatchFormControlChangeEvent();
event->setDefaultHandled();
return;
}
@@ -197,12 +192,12 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
// 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?
const Decimal step = equalIgnoringCase(element().fastGetAttribute(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step();
- const Decimal bigStep = max((stepRange.maximum() - stepRange.minimum()) / 10, step);
+ const Decimal bigStep = std::max((stepRange.maximum() - stepRange.minimum()) / 10, step);
bool isVertical = false;
if (element().renderer()) {
ControlPart part = element().renderer()->style()->appearance();
- isVertical = part == SliderVerticalPart || part == MediaVolumeSliderPart;
+ isVertical = part == SliderVerticalPart;
}
Decimal newValue;
@@ -229,12 +224,11 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
if (newValue != current) {
EventQueueScope scope;
- TextFieldEventBehavior eventBehavior = DispatchChangeEvent;
+ TextFieldEventBehavior eventBehavior = DispatchInputAndChangeEvent;
setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION);
if (AXObjectCache* cache = element().document().existingAXObjectCache())
cache->postNotification(&element(), AXObjectCache::AXValueChanged, true);
- element().dispatchFormControlChangeEvent();
}
event->setDefaultHandled();
@@ -245,11 +239,11 @@ void RangeInputType::createShadowSubtree()
ASSERT(element().shadow());
Document& document = element().document();
- RefPtr<HTMLDivElement> track = HTMLDivElement::create(document);
- track->setPseudo(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<HTMLDivElement> track = HTMLDivElement::create(document);
+ track->setShadowPseudoId(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral));
track->setAttribute(idAttr, ShadowElementNames::sliderTrack());
track->appendChild(SliderThumbElement::create(document));
- RefPtr<HTMLElement> container = SliderContainerElement::create(document);
+ RefPtrWillBeRawPtr<HTMLElement> container = SliderContainerElement::create(document);
container->appendChild(track.release());
element().userAgentShadowRoot()->appendChild(container.release());
}
@@ -317,7 +311,7 @@ void RangeInputType::disabledAttributeChanged()
bool RangeInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
inline SliderThumbElement* RangeInputType::sliderThumbElement() const
@@ -335,7 +329,7 @@ void RangeInputType::listAttributeTargetChanged()
m_tickMarkValuesDirty = true;
Element* sliderTrackElement = this->sliderTrackElement();
if (sliderTrackElement->renderer())
- sliderTrackElement->renderer()->setNeedsLayout();
+ sliderTrackElement->renderer()->setNeedsLayoutAndFullPaintInvalidation();
}
static bool decimalCompare(const Decimal& a, const Decimal& b)
@@ -352,13 +346,13 @@ void RangeInputType::updateTickMarkValues()
HTMLDataListElement* dataList = element().dataList();
if (!dataList)
return;
- RefPtr<HTMLCollection> options = dataList->options();
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
m_tickMarkValues.reserveCapacity(options->length());
for (unsigned i = 0; i < options->length(); ++i) {
- Node* node = options->item(i);
- HTMLOptionElement* optionElement = toHTMLOptionElement(node);
+ Element* element = options->item(i);
+ HTMLOptionElement* optionElement = toHTMLOptionElement(element);
String optionValue = optionElement->value();
- if (!element().isValidValue(optionValue))
+ if (!this->element().isValidValue(optionValue))
continue;
m_tickMarkValues.append(parseToNumber(optionValue, Decimal::nan()));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h
index cb10f784e3e..2cd9f71892a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h
@@ -38,9 +38,9 @@ namespace WebCore {
class ExceptionState;
class SliderThumbElement;
-class RangeInputType : public InputType {
+class RangeInputType FINAL : public InputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
RangeInputType(HTMLInputElement&);
@@ -48,7 +48,7 @@ private:
virtual bool isRangeControl() const OVERRIDE;
virtual const AtomicString& formControlType() const OVERRIDE;
virtual double valueAsDouble() const OVERRIDE;
- virtual void setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
+ virtual void setValueAsDouble(double, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
virtual bool typeMismatchFor(const String&) const OVERRIDE;
virtual bool supportsRequired() const OVERRIDE;
virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp
index 6175a6c95e9..bb9de0774fc 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/ResetInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/Event.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
@@ -41,9 +41,9 @@
namespace WebCore {
-PassRefPtr<InputType> ResetInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ResetInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ResetInputType(element));
+ return adoptRefWillBeNoop(new ResetInputType(element));
}
const AtomicString& ResetInputType::formControlType() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h
index 8837400b86e..e30b91cd6fc 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class ResetInputType : public BaseButtonInputType {
+class ResetInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
ResetInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp
index ba6e85aab40..a5563cee2d5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/html/forms/SearchInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLInputElement.h"
@@ -52,9 +52,9 @@ inline SearchInputType::SearchInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> SearchInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> SearchInputType::create(HTMLInputElement& element)
{
- return adoptRef(new SearchInputType(element));
+ return adoptRefWillBeNoop(new SearchInputType(element));
}
void SearchInputType::countUsage()
@@ -108,7 +108,7 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent* event)
const String& key = event->keyIdentifier();
if (key == "U+001B") {
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
input->setValueForUser("");
input->onSearch();
event->setDefaultHandled();
@@ -120,7 +120,7 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent* event)
void SearchInputType::startSearchEventTimer()
{
ASSERT(element().renderer());
- unsigned length = element().innerTextValue().length();
+ unsigned length = element().innerEditorValue().length();
if (!length) {
stopSearchEventTimer();
@@ -130,7 +130,7 @@ void SearchInputType::startSearchEventTimer()
// After typing the first key, we wait 0.5 seconds.
// After the second key, 0.4 seconds, then 0.3, then 0.2 from then on.
- m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length));
+ m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length), FROM_HERE);
}
void SearchInputType::stopSearchEventTimer()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h
index d13c0f94c42..6687f6d6901 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h
@@ -39,9 +39,9 @@ namespace WebCore {
class SearchFieldCancelButtonElement;
class SearchFieldDecorationElement;
-class SearchInputType : public BaseTextInputType {
+class SearchInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
void stopSearchEventTimer();
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp
index 0e10a5f162f..32761459cd1 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp
@@ -21,14 +21,12 @@
#include "config.h"
#include "core/html/forms/StepRange.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "wtf/MathExtras.h"
#include "wtf/text/WTFString.h"
#include <float.h>
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -84,12 +82,12 @@ Decimal StepRange::alignValueForStep(const Decimal& currentValue, const Decimal&
Decimal StepRange::clampValue(const Decimal& value) const
{
- const Decimal inRangeValue = max(m_minimum, min(value, m_maximum));
+ const Decimal inRangeValue = std::max(m_minimum, std::min(value, m_maximum));
if (!m_hasStep)
return inRangeValue;
- // Rounds inRangeValue to minimum + N * step.
- const Decimal roundedValue = roundByStep(inRangeValue, m_minimum);
- const Decimal clampedValue = roundedValue > m_maximum ? roundedValue - m_step : roundedValue;
+ // Rounds inRangeValue to stepBase + N * step.
+ const Decimal roundedValue = roundByStep(inRangeValue, m_stepBase);
+ const Decimal clampedValue = roundedValue > m_maximum ? roundedValue - m_step : (roundedValue < m_minimum ? roundedValue + m_step : roundedValue);
ASSERT(clampedValue >= m_minimum);
ASSERT(clampedValue <= m_maximum);
return clampedValue;
@@ -121,13 +119,13 @@ Decimal StepRange::parseStep(AnyStepHandling anyStepHandling, const StepDescript
break;
case ParsedStepValueShouldBeInteger:
// For date, month, and week, the parsed value should be an integer for some types.
- step = max(step.round(), Decimal(1));
+ step = std::max(step.round(), Decimal(1));
step *= stepDescription.stepScaleFactor;
break;
case ScaledStepValueShouldBeInteger:
// For datetime, datetime-local, time, the result should be an integer.
step *= stepDescription.stepScaleFactor;
- step = max(step.round(), Decimal(1));
+ step = std::max(step.round(), Decimal(1));
break;
default:
ASSERT_NOT_REACHED();
@@ -161,7 +159,7 @@ bool StepRange::stepMismatch(const Decimal& valueForCheck) const
// ... 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.
const Decimal remainder = (value - m_step * (value / m_step).round()).abs();
- // Accepts erros in lower fractional part which IEEE 754 single-precision
+ // Accepts errors in lower fractional part which IEEE 754 single-precision
// can't represent.
const Decimal computedAcceptableError = acceptableError();
return computedAcceptableError < remainder && remainder < (m_step - computedAcceptableError);
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h
index a31e264c281..f2fdbb2dfde 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h
@@ -71,7 +71,6 @@ public:
StepRange();
StepRange(const StepRange&);
StepRange(const Decimal& stepBase, const Decimal& minimum, const Decimal& maximum, const Decimal& step, const StepDescription&);
- Decimal acceptableError() const;
Decimal alignValueForStep(const Decimal& currentValue, const Decimal& newValue) const;
Decimal clampValue(const Decimal& value) const;
bool hasStep() const { return m_hasStep; }
@@ -80,7 +79,6 @@ public:
static Decimal parseStep(AnyStepHandling, const StepDescription&, const String&);
Decimal step() const { return m_step; }
Decimal stepBase() const { return m_stepBase; }
- int stepScaleFactor() const { return m_stepDescription.stepScaleFactor; }
bool stepMismatch(const Decimal&) const;
// Clamp the middle value according to the step
@@ -106,6 +104,7 @@ public:
private:
StepRange& operator =(const StepRange&);
+ Decimal acceptableError() const;
Decimal roundByStep(const Decimal& value, const Decimal& base) const;
const Decimal m_maximum; // maximum must be >= minimum.
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp
index 3b25b468ec1..8ef131314a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/SubmitInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/Event.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLFormElement.h"
@@ -42,9 +42,9 @@
namespace WebCore {
-PassRefPtr<InputType> SubmitInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> SubmitInputType::create(HTMLInputElement& element)
{
- return adoptRef(new SubmitInputType(element));
+ return adoptRefWillBeNoop(new SubmitInputType(element));
}
const AtomicString& SubmitInputType::formControlType() const
@@ -67,7 +67,7 @@ bool SubmitInputType::supportsRequired() const
void SubmitInputType::handleDOMActivateEvent(Event* event)
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (element->isDisabledFormControl() || !element->form())
return;
element->setActivatedSubmit(true);
@@ -86,11 +86,6 @@ String SubmitInputType::defaultValue() const
return locale().queryString(blink::WebLocalizedString::SubmitButtonDefaultLabel);
}
-bool SubmitInputType::isSubmitButton() const
-{
- return true;
-}
-
bool SubmitInputType::isTextButton() const
{
return true;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h
index ea88704fe9e..169117c2155 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class SubmitInputType : public BaseButtonInputType {
+class SubmitInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
SubmitInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
@@ -47,7 +47,6 @@ private:
virtual void handleDOMActivateEvent(Event*) OVERRIDE;
virtual bool canBeSuccessfulSubmitButton() OVERRIDE;
virtual String defaultValue() const OVERRIDE;
- virtual bool isSubmitButton() const OVERRIDE;
virtual bool isTextButton() const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp
index 4b5e2edbd48..4d11d9e896a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp
@@ -31,14 +31,14 @@
#include "config.h"
#include "core/html/forms/TelephoneInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-PassRefPtr<InputType> TelephoneInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> TelephoneInputType::create(HTMLInputElement& element)
{
- return adoptRef(new TelephoneInputType(element));
+ return adoptRefWillBeNoop(new TelephoneInputType(element));
}
void TelephoneInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h
index d636ee2bff6..dca6c4fc39a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class TelephoneInputType : public BaseTextInputType {
+class TelephoneInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
TelephoneInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
index 0114adab3e8..2b61994d4a8 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
@@ -32,24 +32,23 @@
#include "config.h"
#include "core/html/forms/TextFieldInputType.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/events/BeforeTextInsertedEvent.h"
-#include "core/events/KeyboardEvent.h"
+#include "core/HTMLNames.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/events/TextEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
+#include "core/events/BeforeTextInsertedEvent.h"
+#include "core/events/KeyboardEvent.h"
+#include "core/events/TextEvent.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/html/shadow/TextControlInnerElements.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderDetailsMarker.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderTextControlSingleLine.h"
@@ -83,25 +82,26 @@ private:
virtual void defaultEventHandler(Event* event) OVERRIDE
{
+ ASSERT(document().isActive());
if (event->type() != EventTypeNames::click)
return;
HTMLInputElement* host = hostInput();
- if (host && !host->isDisabledOrReadOnly() && document().page()) {
- document().page()->chrome().openTextDataListChooser(*host);
+ if (host && !host->isDisabledOrReadOnly()) {
+ document().frameHost()->chrome().openTextDataListChooser(*host);
event->setDefaultHandled();
}
}
virtual bool willRespondToMouseClickEvents() OVERRIDE
{
- return hostInput() && !hostInput()->isDisabledOrReadOnly() && document().page();
+ return hostInput() && !hostInput()->isDisabledOrReadOnly() && document().isActive();
}
public:
- static PassRefPtr<DataListIndicatorElement> create(Document& document)
+ static PassRefPtrWillBeRawPtr<DataListIndicatorElement> create(Document& document)
{
- RefPtr<DataListIndicatorElement> element = adoptRef(new DataListIndicatorElement(document));
- element->setPseudo(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<DataListIndicatorElement> element = adoptRefWillBeNoop(new DataListIndicatorElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::pickerIndicator());
return element.release();
}
@@ -115,8 +115,10 @@ TextFieldInputType::TextFieldInputType(HTMLInputElement& element)
TextFieldInputType::~TextFieldInputType()
{
+#if !ENABLE(OILPAN)
if (SpinButtonElement* spinButton = spinButtonElement())
spinButton->removeSpinButtonOwner();
+#endif
}
SpinButtonElement* TextFieldInputType::spinButtonElement() const
@@ -134,18 +136,9 @@ bool TextFieldInputType::isTextField() const
return true;
}
-static inline bool shouldIgnoreRequiredAttribute(const HTMLInputElement& input)
-{
- if (!input.document().settings() || !input.document().settings()->needsSiteSpecificQuirks())
- return false;
- if (!equalIgnoringCase(input.document().url().host(), "egov.uscis.gov"))
- return false;
- return input.fastGetAttribute(requiredAttr) == "no";
-}
-
bool TextFieldInputType::valueMissing(const String& value) const
{
- return !shouldIgnoreRequiredAttribute(element()) && element().isRequired() && value.isEmpty();
+ return element().isRequired() && value.isEmpty();
}
bool TextFieldInputType::canSetSuggestedValue()
@@ -157,14 +150,14 @@ void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChange
{
// Grab this input element to keep reference even if JS event handler
// changes input type.
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
// We don't ask InputType::setValue to dispatch events because
// TextFieldInputType dispatches events different way from InputType.
InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent);
if (valueChanged)
- updateView();
+ input->updateView();
unsigned max = visibleValue().length();
if (input->focused())
@@ -217,10 +210,11 @@ void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event)
const String& key = event->keyIdentifier();
if (key == "Up")
spinButtonStepUp();
- else if (key == "Down")
+ else if (key == "Down" && !event->altKey())
spinButtonStepDown();
else
return;
+ element().dispatchFormControlChangeEvent();
event->setDefaultHandled();
}
@@ -235,12 +229,13 @@ void TextFieldInputType::forwardEvent(Event* event)
if (element().renderer() && (event->isMouseEvent() || event->isDragEvent() || event->hasInterface(EventNames::WheelEvent) || event->type() == EventTypeNames::blur || event->type() == EventTypeNames::focus)) {
RenderTextControlSingleLine* renderTextControl = toRenderTextControlSingleLine(element().renderer());
if (event->type() == EventTypeNames::blur) {
- if (RenderBox* innerTextRenderer = element().innerTextElement()->renderBox()) {
+ if (RenderBox* innerEditorRenderer = element().innerEditorElement()->renderBox()) {
// FIXME: This class has no need to know about RenderLayer!
- if (RenderLayer* innerLayer = innerTextRenderer->layer()) {
- RenderLayerScrollableArea* innerScrollableArea = innerLayer->scrollableArea();
- IntSize scrollOffset(!renderTextControl->style()->isLeftToRightDirection() ? innerScrollableArea->scrollWidth() : 0, 0);
- innerScrollableArea->scrollToOffset(scrollOffset, ScrollOffsetClamped);
+ if (RenderLayer* innerLayer = innerEditorRenderer->layer()) {
+ if (RenderLayerScrollableArea* innerScrollableArea = innerLayer->scrollableArea()) {
+ IntSize scrollOffset(!renderTextControl->style()->isLeftToRightDirection() ? innerScrollableArea->scrollWidth().toInt() : 0, 0);
+ innerScrollableArea->scrollToOffset(scrollOffset, ScrollOffsetClamped);
+ }
}
}
@@ -253,9 +248,9 @@ void TextFieldInputType::forwardEvent(Event* event)
}
}
-void TextFieldInputType::handleFocusEvent(Element* oldFocusedNode, FocusDirection focusDirection)
+void TextFieldInputType::handleFocusEvent(Element* oldFocusedNode, FocusType focusType)
{
- InputType::handleFocusEvent(oldFocusedNode, focusDirection);
+ InputType::handleFocusEvent(oldFocusedNode, focusType);
element().beginEditing();
}
@@ -263,6 +258,8 @@ void TextFieldInputType::handleBlurEvent()
{
InputType::handleBlurEvent();
element().endEditing();
+ if (SpinButtonElement *spinButton = spinButtonElement())
+ spinButton->releaseCapture();
}
bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
@@ -275,15 +272,6 @@ RenderObject* TextFieldInputType::createRenderer(RenderStyle*) const
return new RenderTextControlSingleLine(&element());
}
-bool TextFieldInputType::needsContainer() const
-{
-#if ENABLE(INPUT_SPEECH)
- return element().isSpeechEnabled();
-#else
- return false;
-#endif
-}
-
bool TextFieldInputType::shouldHaveSpinButton() const
{
return RenderTheme::theme().shouldHaveSpinButton(&element());
@@ -293,32 +281,27 @@ void TextFieldInputType::createShadowSubtree()
{
ASSERT(element().shadow());
ShadowRoot* shadowRoot = element().userAgentShadowRoot();
- ASSERT(!shadowRoot->hasChildNodes());
+ ASSERT(!shadowRoot->hasChildren());
Document& document = element().document();
bool shouldHaveSpinButton = this->shouldHaveSpinButton();
bool shouldHaveDataListIndicator = element().hasValidDataListOptions();
bool createsContainer = shouldHaveSpinButton || shouldHaveDataListIndicator || needsContainer();
- RefPtr<TextControlInnerTextElement> innerEditor = TextControlInnerTextElement::create(document);
+ RefPtrWillBeRawPtr<TextControlInnerEditorElement> innerEditor = TextControlInnerEditorElement::create(document);
if (!createsContainer) {
shadowRoot->appendChild(innerEditor.release());
return;
}
- RefPtr<TextControlInnerContainer> container = TextControlInnerContainer::create(document);
- container->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<TextControlInnerContainer> container = TextControlInnerContainer::create(document);
+ container->setShadowPseudoId(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
shadowRoot->appendChild(container);
- RefPtr<EditingViewPortElement> editingViewPort = EditingViewPortElement::create(document);
+ RefPtrWillBeRawPtr<EditingViewPortElement> editingViewPort = EditingViewPortElement::create(document);
editingViewPort->appendChild(innerEditor.release());
container->appendChild(editingViewPort.release());
-#if ENABLE(INPUT_SPEECH)
- if (element().isSpeechEnabled())
- container->appendChild(InputFieldSpeechButtonElement::create(document));
-#endif
-
if (shouldHaveDataListIndicator)
container->appendChild(DataListIndicatorElement::create(document));
// FIXME: Because of a special handling for a spin button in
@@ -357,14 +340,16 @@ void TextFieldInputType::listAttributeTargetChanged()
// FIXME: The following code is similar to createShadowSubtree(),
// but they are different. We should simplify the code by making
// containerElement mandatory.
- RefPtr<Element> rpContainer = TextControlInnerContainer::create(document);
- rpContainer->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
- RefPtr<Element> innerEditor = element().innerTextElement();
+ RefPtrWillBeRawPtr<Element> rpContainer = TextControlInnerContainer::create(document);
+ rpContainer->setShadowPseudoId(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<Element> innerEditor = element().innerEditorElement();
innerEditor->parentNode()->replaceChild(rpContainer.get(), innerEditor.get());
- RefPtr<Element> editingViewPort = EditingViewPortElement::create(document);
+ RefPtrWillBeRawPtr<Element> editingViewPort = EditingViewPortElement::create(document);
editingViewPort->appendChild(innerEditor.release());
rpContainer->appendChild(editingViewPort.release());
rpContainer->appendChild(DataListIndicatorElement::create(document));
+ if (element().document().focusedElement() == element())
+ element().updateFocusAppearance(true /* restore selection */);
}
} else {
picker->remove(ASSERT_NO_EXCEPTION);
@@ -408,15 +393,6 @@ static bool isASCIILineBreak(UChar c)
static String limitLength(const String& string, unsigned maxLength)
{
unsigned newLength = std::min(maxLength, string.length());
- // FIXME: We should not truncate the string at a control character. It's not
- // compatible with IE and Firefox.
- for (unsigned i = 0; i < newLength; ++i) {
- const UChar current = string[i];
- if (current < ' ' && current != '\t') {
- newLength = i;
- break;
- }
- }
if (newLength == string.length())
return string;
if (newLength > 0 && U16_IS_LEAD(string[newLength - 1]))
@@ -433,10 +409,10 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
{
// Make sure that the text to be inserted will not violate the maxLength.
- // We use HTMLInputElement::innerTextValue() instead of
+ // We use HTMLInputElement::innerEditorValue() instead of
// HTMLInputElement::value() because they can be mismatched by
// sanitizeValue() in HTMLInputElement::subtreeHasChanged() in some cases.
- unsigned oldLength = element().innerTextValue().length();
+ unsigned oldLength = element().innerEditorValue().length();
// selectionLength represents the selection length of this text field to be
// removed by this insertion.
@@ -466,7 +442,7 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
bool TextFieldInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
void TextFieldInputType::updatePlaceholderText()
@@ -481,12 +457,12 @@ void TextFieldInputType::updatePlaceholderText()
return;
}
if (!placeholder) {
- RefPtr<HTMLElement> newElement = HTMLDivElement::create(element().document());
+ RefPtrWillBeRawPtr<HTMLElement> newElement = HTMLDivElement::create(element().document());
placeholder = newElement.get();
- placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
+ placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
placeholder->setAttribute(idAttr, ShadowElementNames::placeholder());
Element* container = containerElement();
- Node* previous = container ? container : element().innerTextElement();
+ Node* previous = container ? container : element().innerEditorElement();
previous->parentNode()->insertBefore(placeholder, previous->nextSibling());
ASSERT_WITH_SECURITY_IMPLICATION(placeholder->parentNode() == previous->parentNode());
}
@@ -518,10 +494,10 @@ void TextFieldInputType::subtreeHasChanged()
// HTMLInputElement::handleBeforeTextInsertedEvent() has already called
// sanitizeUserInputValue().
// sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
- element().setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element().innerTextValue())));
+ element().setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element().innerEditorValue())));
element().updatePlaceholderVisibility(false);
// Recalc for :invalid change.
- element().setNeedsStyleRecalc();
+ element().setNeedsStyleRecalc(SubtreeStyleChange);
didSetValueByUserEdit(wasChanged ? ValueChangeStateChanged : ValueChangeStateNone);
}
@@ -547,19 +523,23 @@ void TextFieldInputType::spinButtonStepUp()
void TextFieldInputType::updateView()
{
if (!element().suggestedValue().isNull()) {
- element().setInnerTextValue(element().suggestedValue());
+ element().setInnerEditorValue(element().suggestedValue());
element().updatePlaceholderVisibility(false);
- } else if (!element().formControlValueMatchesRenderer()) {
- // Update the renderer value if the formControlValueMatchesRenderer() flag is false.
- // It protects an unacceptable renderer value from being overwritten with the DOM value.
- element().setInnerTextValue(visibleValue());
+ } else if (element().needsToUpdateViewValue()) {
+ // Update the view only if needsToUpdateViewValue is true. It protects
+ // an unacceptable view value from being overwritten with the DOM value.
+ //
+ // e.g. <input type=number> has a view value "abc", and input.max is
+ // updated. In this case, updateView() is called but we should not
+ // update the view value.
+ element().setInnerEditorValue(visibleValue());
element().updatePlaceholderVisibility(false);
}
}
void TextFieldInputType::focusAndSelectSpinButtonOwner()
{
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
input->focus();
input->select();
}
@@ -574,4 +554,10 @@ bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents()
return shouldSpinButtonRespondToMouseEvents() && element().focused();
}
+void TextFieldInputType::spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch eventDispatch)
+{
+ if (eventDispatch == SpinButtonElement::EventDispatchAllowed)
+ element().dispatchFormControlChangeEvent();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h
index 38d5d9ed57f..0eb1fda2d4c 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h
@@ -41,6 +41,7 @@ class FormDataList;
// The class represents types of which UI contain text fields.
// It supports not only the types for BaseTextInputType but also type=number.
class TextFieldInputType : public InputType, protected SpinButtonElement::SpinButtonOwner {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextFieldInputType);
protected:
TextFieldInputType(HTMLInputElement&);
virtual ~TextFieldInputType();
@@ -49,16 +50,16 @@ protected:
void handleKeydownEventForSpinButton(KeyboardEvent*);
protected:
- virtual bool needsContainer() const;
- virtual bool shouldHaveSpinButton() const;
+ virtual bool needsContainer() const { return false; }
+ bool shouldHaveSpinButton() const;
virtual void createShadowSubtree() OVERRIDE;
virtual void destroyShadowSubtree() OVERRIDE;
virtual void attributeChanged() OVERRIDE;
virtual void disabledAttributeChanged() OVERRIDE;
virtual void readonlyAttributeChanged() OVERRIDE;
virtual bool supportsReadOnly() const OVERRIDE;
- virtual void handleFocusEvent(Element* oldFocusedNode, FocusDirection) OVERRIDE;
- virtual void handleBlurEvent() OVERRIDE;
+ virtual void handleFocusEvent(Element* oldFocusedNode, FocusType) OVERRIDE FINAL;
+ virtual void handleBlurEvent() OVERRIDE FINAL;
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE;
virtual void updateView() OVERRIDE;
@@ -72,27 +73,28 @@ protected:
Element* containerElement() const;
private:
- virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
- virtual bool isTextField() const OVERRIDE;
+ virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE FINAL;
+ virtual bool isTextField() const OVERRIDE FINAL;
virtual bool valueMissing(const String&) const OVERRIDE;
virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) OVERRIDE;
- virtual void forwardEvent(Event*) OVERRIDE;
- virtual bool shouldSubmitImplicitly(Event*) OVERRIDE;
+ virtual void forwardEvent(Event*) OVERRIDE FINAL;
+ virtual bool shouldSubmitImplicitly(Event*) OVERRIDE FINAL;
virtual RenderObject* createRenderer(RenderStyle*) const OVERRIDE;
virtual bool shouldUseInputMethod() const OVERRIDE;
virtual String sanitizeValue(const String&) const OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual void listAttributeTargetChanged() OVERRIDE;
- virtual void updatePlaceholderText() OVERRIDE;
+ virtual void updatePlaceholderText() OVERRIDE FINAL;
virtual bool appendFormData(FormDataList&, bool multipart) const OVERRIDE;
- virtual void subtreeHasChanged() OVERRIDE;
+ virtual void subtreeHasChanged() OVERRIDE FINAL;
// SpinButtonElement::SpinButtonOwner functions.
- virtual void focusAndSelectSpinButtonOwner() OVERRIDE;
- virtual bool shouldSpinButtonRespondToMouseEvents() OVERRIDE;
- virtual bool shouldSpinButtonRespondToWheelEvents() OVERRIDE;
- virtual void spinButtonStepDown() OVERRIDE;
- virtual void spinButtonStepUp() OVERRIDE;
+ virtual void focusAndSelectSpinButtonOwner() OVERRIDE FINAL;
+ virtual bool shouldSpinButtonRespondToMouseEvents() OVERRIDE FINAL;
+ virtual bool shouldSpinButtonRespondToWheelEvents() OVERRIDE FINAL;
+ virtual void spinButtonStepDown() OVERRIDE FINAL;
+ virtual void spinButtonStepUp() OVERRIDE FINAL;
+ virtual void spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch) OVERRIDE FINAL;
SpinButtonElement* spinButtonElement() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp
index a5e9db19398..b39a4ccbcd0 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/html/forms/TextInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "wtf/PassOwnPtr.h"
@@ -39,9 +39,9 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<InputType> TextInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> TextInputType::create(HTMLInputElement& element)
{
- return adoptRef(new TextInputType(element));
+ return adoptRefWillBeNoop(new TextInputType(element));
}
void TextInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h
index 8fb1e8c2447..75608bd2ee2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class TextInputType : public BaseTextInputType {
+class TextInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
TextInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp
index 22d80ef7e1e..ae3203eabc8 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/TimeInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -56,9 +56,9 @@ TimeInputType::TimeInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> TimeInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> TimeInputType::create(HTMLInputElement& element)
{
- return adoptRef(new TimeInputType(element));
+ return adoptRefWillBeNoop(new TimeInputType(element));
}
void TimeInputType::countUsage()
@@ -90,7 +90,7 @@ StepRange TimeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (timeDefaultStep, timeDefaultStepBase, timeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
- return InputType::createStepRange(anyStepHandling, 0, Decimal::fromDouble(DateComponents::minimumTime()), Decimal::fromDouble(DateComponents::maximumTime()), stepDescription);
+ return InputType::createStepRange(anyStepHandling, timeDefaultStepBase, Decimal::fromDouble(DateComponents::minimumTime()), Decimal::fromDouble(DateComponents::maximumTime()), stepDescription);
}
bool TimeInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h
index 82a540d52f6..b8d3f111ca3 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h
@@ -42,9 +42,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseTimeInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseTimeInputType;
#endif
-class TimeInputType : public BaseTimeInputType {
+class TimeInputType FINAL : public BaseTimeInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
TimeInputType(HTMLInputElement&);
@@ -59,9 +59,9 @@ private:
virtual String localizeValue(const String&) const OVERRIDE;
// BaseMultipleFieldsDateAndTimeInputType functions
- virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
- virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE FINAL;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
+ virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp
index e9a0052edad..673b88956ce 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp
@@ -50,7 +50,7 @@ static String stripLeadingWhiteSpace(const String& string)
unsigned i;
for (i = 0; i < length; ++i) {
- if (string[i] != noBreakSpace && (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral)))
+ if (string[i] != noBreakSpace && !isSpaceOrNewline(string[i]))
break;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp
index 33017eb34c7..c39d40c5301 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp
@@ -31,16 +31,16 @@
#include "config.h"
#include "core/html/forms/URLInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-PassRefPtr<InputType> URLInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> URLInputType::create(HTMLInputElement& element)
{
- return adoptRef(new URLInputType(element));
+ return adoptRefWillBeNoop(new URLInputType(element));
}
void URLInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h
index 98f53f21b38..e11143fc6c4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class URLInputType : public BaseTextInputType {
+class URLInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
URLInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp
index 57ee0eb6b8f..df7475f4c3e 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "core/html/forms/ValidationMessage.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLFormControlElement.h"
#include "core/page/Page.h"
#include "core/page/ValidationMessageClient.h"
@@ -46,8 +47,6 @@ ALWAYS_INLINE ValidationMessage::ValidationMessage(HTMLFormControlElement* eleme
ValidationMessage::~ValidationMessage()
{
- if (ValidationMessageClient* client = validationMessageClient())
- client->hideValidationMessage(*m_element);
}
PassOwnPtr<ValidationMessage> ValidationMessage::create(HTMLFormControlElement* element)
@@ -60,9 +59,8 @@ ValidationMessageClient* ValidationMessage::validationMessageClient() const
Page* page = m_element->document().page();
if (!page)
return 0;
- // The form valdiation feature requires ValidationMessageClient.
- ASSERT(page->validationMessageClient());
- return page->validationMessageClient();
+
+ return &page->validationMessageClient();
}
void ValidationMessage::updateValidationMessage(const String& message)
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp
index 419b1603ddc..e49651ed71e 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/WeekInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -48,9 +48,9 @@ static const int weekDefaultStepBase = -259200000; // The first day of 1970-W01.
static const int weekDefaultStep = 1;
static const int weekStepScaleFactor = 604800000;
-PassRefPtr<InputType> WeekInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> WeekInputType::create(HTMLInputElement& element)
{
- return adoptRef(new WeekInputType(element));
+ return adoptRefWillBeNoop(new WeekInputType(element));
}
void WeekInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h
index 9455039c61a..f3360f27404 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h
@@ -42,9 +42,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseWeekInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseWeekInputType;
#endif
-class WeekInputType : public BaseWeekInputType {
+class WeekInputType FINAL : public BaseWeekInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
WeekInputType(HTMLInputElement& element) : BaseWeekInputType(element) { }
@@ -57,9 +57,9 @@ private:
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
// BaseMultipleFieldsDateAndTimeInputType functions
- virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
- virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE FINAL;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
+ virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp
index 74643ac6db0..e497b047ff3 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp
@@ -31,16 +31,16 @@
#include "config.h"
#include "core/html/ime/InputMethodContext.h"
+#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/editing/InputMethodController.h"
-#include "core/html/ime/Composition.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-PassOwnPtr<InputMethodContext> InputMethodContext::create(HTMLElement* element)
+PassOwnPtrWillBeRawPtr<InputMethodContext> InputMethodContext::create(HTMLElement* element)
{
- return adoptPtr(new InputMethodContext(element));
+ return adoptPtrWillBeRefCountedGarbageCollected(new InputMethodContext(element));
}
InputMethodContext::InputMethodContext(HTMLElement* element)
@@ -53,13 +53,6 @@ InputMethodContext::~InputMethodContext()
{
}
-Composition* InputMethodContext::composition()
-{
- if (!m_composition)
- m_composition = Composition::create(this);
- return m_composition.get();
-}
-
String InputMethodContext::locale() const
{
// FIXME: Implement this.
@@ -93,7 +86,7 @@ void InputMethodContext::confirmComposition()
bool InputMethodContext::hasFocus() const
{
- Frame* frame = m_element->document().frame();
+ LocalFrame* frame = m_element->document().frame();
if (!frame)
return false;
@@ -193,4 +186,10 @@ void InputMethodContext::dispatchCandidateWindowHideEvent()
dispatchEvent(Event::create(EventTypeNames::candidatewindowhide));
}
+void InputMethodContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ EventTargetWithInlineData::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h
index 16bb6ffe17a..d2b7978bc40 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h
@@ -42,20 +42,21 @@
namespace WebCore {
-class Composition;
class ExecutionContext;
class InputMethodController;
class Node;
-class InputMethodContext : public ScriptWrappable, public EventTargetWithInlineData {
+class InputMethodContext FINAL : public NoBaseWillBeRefCountedGarbageCollected<InputMethodContext>, public ScriptWrappable, public EventTargetWithInlineData {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(InputMethodContext);
public:
- static PassOwnPtr<InputMethodContext> create(HTMLElement*);
- ~InputMethodContext();
+ static PassOwnPtrWillBeRawPtr<InputMethodContext> create(HTMLElement*);
+ virtual ~InputMethodContext();
+#if !ENABLE(OILPAN)
void ref() { m_element->ref(); }
void deref() { m_element->deref(); }
+#endif
- Composition* composition();
String locale() const;
HTMLElement* target() const;
unsigned compositionStartOffset();
@@ -78,17 +79,20 @@ public:
void dispatchCandidateWindowUpdateEvent();
void dispatchCandidateWindowHideEvent();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
InputMethodContext(HTMLElement*);
bool hasFocus() const;
CompositionUnderline selectedSegment() const;
InputMethodController& inputMethodController() const;
+#if !ENABLE(OILPAN)
virtual void refEventTarget() OVERRIDE { ref(); }
virtual void derefEventTarget() OVERRIDE { deref(); }
+#endif
- HTMLElement* m_element;
- OwnPtr<Composition> m_composition;
+ RawPtrWillBeMember<HTMLElement> m_element;
Vector<unsigned> m_segments;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl
index 8ce8c4a43d6..043feed06ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl
+++ b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl
@@ -30,7 +30,6 @@
// http://www.w3.org/TR/ime-api/
interface InputMethodContext : EventTarget {
- readonly attribute Composition composition;
readonly attribute DOMString locale;
readonly attribute HTMLElement target;
readonly attribute unsigned long compositionStartOffset;
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp
new file mode 100644
index 00000000000..4726f713235
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImport.h"
+
+#include "core/dom/Document.h"
+#include "core/html/imports/HTMLImportStateResolver.h"
+
+namespace WebCore {
+
+HTMLImport* HTMLImport::root()
+{
+ HTMLImport* i = this;
+ while (i->parent())
+ i = i->parent();
+ return i;
+}
+
+bool HTMLImport::precedes(HTMLImport* import)
+{
+ for (HTMLImport* i = this; i; i = traverseNext(i)) {
+ if (i == import)
+ return true;
+ }
+
+ return false;
+}
+
+bool HTMLImport::formsCycle() const
+{
+ for (const HTMLImport* i = this->parent(); i; i = i->parent()) {
+ if (i->document() == this->document())
+ return true;
+ }
+
+ return false;
+
+}
+
+void HTMLImport::appendImport(HTMLImport* child)
+{
+ appendChild(child);
+
+ // This prevents HTML parser from going beyond the
+ // blockage line before the precise state is computed by recalcState().
+ if (child->isSync())
+ m_state = HTMLImportState::blockedState();
+
+ stateWillChange();
+}
+
+void HTMLImport::stateDidChange()
+{
+ if (!state().shouldBlockScriptExecution()) {
+ if (Document* document = this->document())
+ document->didLoadAllImports();
+ }
+}
+
+void HTMLImport::recalcTreeState(HTMLImport* root)
+{
+ HashMap<HTMLImport*, HTMLImportState> snapshot;
+ Vector<HTMLImport*> updated;
+
+ for (HTMLImport* i = root; i; i = traverseNext(i)) {
+ snapshot.add(i, i->state());
+ i->m_state = HTMLImportState::invalidState();
+ }
+
+ // The post-visit DFS order matters here because
+ // HTMLImportStateResolver in recalcState() Depends on
+ // |m_state| of its children and precedents of ancestors.
+ // Accidental cycle dependency of state computation is prevented
+ // by invalidateCachedState() and isStateCacheValid() check.
+ for (HTMLImport* i = traverseFirstPostOrder(root); i; i = traverseNextPostOrder(i)) {
+ ASSERT(!i->m_state.isValid());
+ i->m_state = HTMLImportStateResolver(i).resolve();
+
+ HTMLImportState newState = i->state();
+ HTMLImportState oldState = snapshot.get(i);
+ // Once the state reaches Ready, it shouldn't go back.
+ ASSERT(!oldState.isReady() || oldState <= newState);
+ if (newState != oldState)
+ updated.append(i);
+ }
+
+ for (size_t i = 0; i < updated.size(); ++i)
+ updated[i]->stateDidChange();
+}
+
+#if !defined(NDEBUG)
+void HTMLImport::show()
+{
+ root()->showTree(this, 0);
+}
+
+void HTMLImport::showTree(HTMLImport* highlight, unsigned depth)
+{
+ for (unsigned i = 0; i < depth*4; ++i)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, "%s", this == highlight ? "*" : " ");
+ showThis();
+ fprintf(stderr, "\n");
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ child->showTree(highlight, depth + 1);
+}
+
+void HTMLImport::showThis()
+{
+ fprintf(stderr, "%p state=%d", this, m_state.peekValueForDebug());
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h
new file mode 100644
index 00000000000..0a7e35a7392
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImport_h
+#define HTMLImport_h
+
+#include "core/html/imports/HTMLImportState.h"
+#include "platform/heap/Handle.h"
+#include "wtf/TreeNode.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class Document;
+class LocalFrame;
+class HTMLImportChild;
+class HTMLImportLoader;
+class HTMLImportsController;
+class KURL;
+
+//
+// # Basic Data Structure and Algorithms of HTML Imports implemenation.
+//
+// ## The Import Tree
+//
+// HTML Imports form a tree:
+//
+// * The root of the tree is HTMLImportTreeRoot.
+//
+// * The HTMLImportTreeRoot is owned HTMLImportsController, which is owned by the master
+// document as a DocumentSupplement.
+//
+// * The non-root nodes are HTMLImportChild. They are all owned by HTMLImporTreeRoot.
+// LinkStyle is wired into HTMLImportChild by implementing HTMLImportChildClient interface
+//
+// * Both HTMLImportTreeRoot and HTMLImportChild are derived from HTMLImport superclass
+// that models the tree data structure using WTF::TreeNode and provides a set of
+// virtual functions.
+//
+// HTMLImportsController also owns all loaders in the tree and manages their lifetime through it.
+// One assumption is that the tree is append-only and nodes are never inserted in the middle of the tree nor removed.
+//
+// Full diagram is here:
+// https://docs.google.com/drawings/d/1jFQrO0IupWrlykTNzQ3Nv2SdiBiSz4UE9-V3-vDgBb0/
+//
+// # Import Sharing and HTMLImportLoader
+//
+// The HTML Imports spec calls for de-dup mechanism to share already loaded imports.
+// To implement this, the actual loading machinery is split out from HTMLImportChild to
+// HTMLImportLoader, and each loader shares HTMLImportLoader with other loader if the URL is same.
+// Check around HTMLImportsController::findLink() for more detail.
+//
+// HTMLImportLoader can be shared by multiple imports.
+//
+// HTMLImportChild (1)-->(*) HTMLImportLoader
+//
+//
+// # Script Blocking
+//
+// - An import blocks the HTML parser of its own imported document from running <script>
+// until all of its children are loaded.
+// Note that dynamically added import won't block the parser.
+//
+// - An import under loading also blocks imported documents that follow from being created.
+// This is because an import can include another import that has same URLs of following ones.
+// In such case, the preceding import should be loaded and following ones should be de-duped.
+//
+
+// The superclass of HTMLImportTreeRoot and HTMLImportChild
+// This represents the import tree data structure.
+class HTMLImport : public NoBaseWillBeGarbageCollectedFinalized<HTMLImport>, public TreeNode<HTMLImport> {
+public:
+ enum SyncMode {
+ Sync = 0,
+ Async = 1
+ };
+
+ virtual ~HTMLImport() { }
+
+ // FIXME: Consider returning HTMLImportTreeRoot.
+ HTMLImport* root();
+ bool precedes(HTMLImport*);
+ bool isRoot() const { return !parent(); }
+ bool isSync() const { return SyncMode(m_sync) == Sync; }
+ bool formsCycle() const;
+ const HTMLImportState& state() const { return m_state; }
+
+ void appendImport(HTMLImport*);
+
+ virtual Document* document() const = 0;
+ virtual bool isDone() const = 0; // FIXME: Should be renamed to haveFinishedLoading()
+ virtual HTMLImportLoader* loader() const { return 0; }
+ virtual void stateWillChange() { }
+ virtual void stateDidChange();
+
+ virtual void trace(Visitor*) { }
+
+protected:
+ // Stating from most conservative state.
+ // It will be corrected through state update flow.
+ explicit HTMLImport(SyncMode sync)
+ : m_sync(sync)
+ { }
+
+ static void recalcTreeState(HTMLImport* root);
+
+#if !defined(NDEBUG)
+ void show();
+ void showTree(HTMLImport* highlight, unsigned depth);
+ virtual void showThis();
+#endif
+
+private:
+ HTMLImportState m_state;
+ unsigned m_sync : 1;
+};
+
+} // namespace WebCore
+
+#endif // HTMLImport_h
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp
new file mode 100644
index 00000000000..91b1b87f5ab
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportChild.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/custom/CustomElement.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "core/html/imports/HTMLImportChildClient.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+#include "core/html/imports/HTMLImportsController.h"
+
+namespace WebCore {
+
+HTMLImportChild::HTMLImportChild(const KURL& url, HTMLImportLoader* loader, SyncMode sync)
+ : HTMLImport(sync)
+ , m_url(url)
+#if !ENABLE(OILPAN)
+ , m_weakFactory(this)
+#endif
+ , m_loader(loader)
+ , m_client(nullptr)
+{
+}
+
+HTMLImportChild::~HTMLImportChild()
+{
+#if !ENABLE(OILPAN)
+ // importDestroyed() should be called before the destruction.
+ ASSERT(!m_loader);
+
+ if (m_client)
+ m_client->importChildWasDestroyed(this);
+#endif
+}
+
+void HTMLImportChild::ownerInserted()
+{
+ if (!m_loader->isDone())
+ return;
+ root()->document()->styleResolverChanged();
+}
+
+void HTMLImportChild::didShareLoader()
+{
+ createCustomElementMicrotaskStepIfNeeded();
+ stateWillChange();
+}
+
+void HTMLImportChild::didStartLoading()
+{
+ createCustomElementMicrotaskStepIfNeeded();
+}
+
+void HTMLImportChild::didFinish()
+{
+ if (m_client)
+ m_client->didFinish();
+}
+
+void HTMLImportChild::didFinishLoading()
+{
+ stateWillChange();
+ if (m_customElementMicrotaskStep)
+ CustomElementMicrotaskDispatcher::instance().importDidFinish(m_customElementMicrotaskStep.get());
+}
+
+void HTMLImportChild::didFinishUpgradingCustomElements()
+{
+ stateWillChange();
+ m_customElementMicrotaskStep.clear();
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportChild::importDestroyed()
+{
+ if (parent())
+ parent()->removeChild(this);
+
+ ASSERT(m_loader);
+ m_loader->removeImport(this);
+ m_loader = nullptr;
+}
+#endif
+
+Document* HTMLImportChild::document() const
+{
+ ASSERT(m_loader);
+ return m_loader->document();
+}
+
+void HTMLImportChild::stateWillChange()
+{
+ toHTMLImportTreeRoot(root())->scheduleRecalcState();
+}
+
+void HTMLImportChild::stateDidChange()
+{
+ HTMLImport::stateDidChange();
+
+ if (state().isReady())
+ didFinish();
+}
+
+void HTMLImportChild::createCustomElementMicrotaskStepIfNeeded()
+{
+ // HTMLImportChild::normalize(), which is called from HTMLImportLoader::addImport(),
+ // can move import children to new parents. So their microtask steps should be updated as well,
+ // to let the steps be in the new parent queues.This method handles such migration.
+ // For implementation simplicity, outdated step objects that are owned by moved children
+ // aren't removed from the (now wrong) queues. Instead, each step invalidates its content so that
+ // it is removed from the wrong queue during the next traversal. See parentWasChanged() for the detail.
+
+ if (m_customElementMicrotaskStep) {
+ m_customElementMicrotaskStep->parentWasChanged();
+ m_customElementMicrotaskStep.clear();
+ }
+
+ if (!isDone() && !formsCycle()) {
+#if ENABLE(OILPAN)
+ m_customElementMicrotaskStep = CustomElement::didCreateImport(this);
+#else
+ m_customElementMicrotaskStep = CustomElement::didCreateImport(this)->weakPtr();
+#endif
+ }
+
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ toHTMLImportChild(child)->createCustomElementMicrotaskStepIfNeeded();
+}
+
+bool HTMLImportChild::isDone() const
+{
+ ASSERT(m_loader);
+
+ return m_loader->isDone() && m_loader->microtaskQueue()->isEmpty() && !m_customElementMicrotaskStep;
+}
+
+HTMLImportLoader* HTMLImportChild::loader() const
+{
+ // This should never be called after importDestroyed.
+ ASSERT(m_loader);
+ return m_loader;
+}
+
+void HTMLImportChild::setClient(HTMLImportChildClient* client)
+{
+ ASSERT(client);
+ ASSERT(!m_client);
+ m_client = client;
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportChild::clearClient()
+{
+ // Doesn't check m_client nullity because we allow
+ // clearClient() to reenter.
+ m_client = nullptr;
+}
+#endif
+
+HTMLLinkElement* HTMLImportChild::link() const
+{
+ if (!m_client)
+ return 0;
+ return m_client->link();
+}
+
+// Ensuring following invariants against the import tree:
+// - HTMLImportChild::firstImport() is the "first import" of the DFS order of the import tree.
+// - The "first import" manages all the children that is loaded by the document.
+void HTMLImportChild::normalize()
+{
+ if (!loader()->isFirstImport(this) && this->precedes(loader()->firstImport())) {
+ HTMLImportChild* oldFirst = loader()->firstImport();
+ loader()->moveToFirst(this);
+ takeChildrenFrom(oldFirst);
+ }
+
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ toHTMLImportChild(child)->normalize();
+}
+
+#if !defined(NDEBUG)
+void HTMLImportChild::showThis()
+{
+ bool isFirst = loader() ? loader()->isFirstImport(this) : false;
+ HTMLImport::showThis();
+ fprintf(stderr, " loader=%p first=%d, step=%p sync=%s url=%s",
+ m_loader.get(),
+ isFirst,
+ m_customElementMicrotaskStep.get(),
+ isSync() ? "Y" : "N",
+ url().string().utf8().data());
+}
+#endif
+
+void HTMLImportChild::trace(Visitor* visitor)
+{
+ visitor->trace(m_customElementMicrotaskStep);
+ visitor->trace(m_loader);
+ visitor->trace(m_client);
+ HTMLImport::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h
index 72f0329c2c5..aafc6ebcec1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h
@@ -31,67 +31,82 @@
#ifndef HTMLImportChild_h
#define HTMLImportChild_h
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportLoaderClient.h"
-#include "core/html/HTMLImportResourceOwner.h"
+#include "core/html/imports/HTMLImport.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
+#include "wtf/Vector.h"
+#include "wtf/WeakPtr.h"
namespace WebCore {
+class CustomElementMicrotaskImportStep;
class HTMLImportLoader;
class HTMLImportChildClient;
+class HTMLLinkElement;
//
// An import tree node subclas to encapsulate imported document
-// lifecycle. This class is owned by LinkStyle. The actual loading
+// lifecycle. This class is owned by HTMLImportsController. The actual loading
// is done by HTMLImportLoader, which can be shared among multiple
// HTMLImportChild of same link URL.
//
-// HTMLImportChild implements ResourceClient through HTMLImportResourceOwner
-// so that it can speculatively request linked resources while it is unblocked.
-//
-class HTMLImportChild : public HTMLImport, public HTMLImportLoaderClient, public HTMLImportResourceOwner {
+class HTMLImportChild FINAL : public HTMLImport {
public:
- HTMLImportChild(const KURL&, HTMLImportChildClient*);
+ HTMLImportChild(const KURL&, HTMLImportLoader*, SyncMode);
virtual ~HTMLImportChild();
- Document* importedDocument() const;
+ HTMLLinkElement* link() const;
const KURL& url() const { return m_url; }
- void wasAlreadyLoadedAs(HTMLImportChild* found);
- void startLoading(const ResourcePtr<RawResource>&);
+ void ownerInserted();
+ void didShareLoader();
+ void didStartLoading();
+#if !ENABLE(OILPAN)
void importDestroyed();
- bool isLoaded() const;
+ WeakPtr<HTMLImportChild> weakPtr() { return m_weakFactory.createWeakPtr(); }
+#endif
// HTMLImport
- virtual HTMLImportRoot* root() OVERRIDE;
virtual Document* document() const OVERRIDE;
- virtual void wasDetachedFromDocument() OVERRIDE;
- virtual void didFinishParsing() OVERRIDE;
- virtual bool isProcessing() const OVERRIDE;
virtual bool isDone() const OVERRIDE;
- virtual void didUnblockDocument() OVERRIDE;
+ virtual HTMLImportLoader* loader() const OVERRIDE;
+ virtual void stateWillChange() OVERRIDE;
+ virtual void stateDidChange() OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
- void clearClient() { m_client = 0; }
+#if !defined(NDEBUG)
+ virtual void showThis() OVERRIDE;
+#endif
-private:
- // RawResourceOwner doing nothing.
- // HTMLImportChild owns the resource so that the contents of prefetched Resource doesn't go away.
- virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE { }
- virtual void dataReceived(Resource*, const char*, int) OVERRIDE { }
- virtual void notifyFinished(Resource*) OVERRIDE { }
+ void setClient(HTMLImportChildClient*);
+#if !ENABLE(OILPAN)
+ void clearClient();
+#endif
- // HTMLImportLoaderClient
- virtual void didFinish() OVERRIDE;
+ void didFinishLoading();
+ void didFinishUpgradingCustomElements();
+ void normalize();
- void createLoader();
- void shareLoader(HTMLImportChild*);
+private:
+ void didFinish();
+ void shareLoader();
+ void createCustomElementMicrotaskStepIfNeeded();
KURL m_url;
- HTMLImportChildClient* m_client;
- RefPtr<HTMLImportLoader> m_loader;
+ WeakPtrWillBeWeakMember<CustomElementMicrotaskImportStep> m_customElementMicrotaskStep;
+#if !ENABLE(OILPAN)
+ WeakPtrFactory<HTMLImportChild> m_weakFactory;
+#endif
+ RawPtrWillBeMember<HTMLImportLoader> m_loader;
+ RawPtrWillBeMember<HTMLImportChildClient> m_client;
};
+inline HTMLImportChild* toHTMLImportChild(HTMLImport* import)
+{
+ ASSERT(!import || !import->isRoot());
+ return static_cast<HTMLImportChild*>(import);
+}
+
} // namespace WebCore
#endif // HTMLImportChild_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h
index 62866e8c4f7..67d0b65d4d3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h
@@ -33,11 +33,19 @@
namespace WebCore {
-class HTMLImportChildClient {
+class HTMLImportChild;
+class HTMLLinkElement;
+
+class HTMLImportChildClient : public WillBeGarbageCollectedMixin {
public:
virtual ~HTMLImportChildClient() { }
virtual void didFinish() = 0;
- virtual void loaderWillBeDestroyed() = 0;
+#if !ENABLE(OILPAN)
+ virtual void importChildWasDestroyed(HTMLImportChild*) = 0;
+#endif
+ virtual bool isSync() const = 0;
+ virtual HTMLLinkElement* link() = 0;
+ virtual void trace(Visitor*) { }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
new file mode 100644
index 00000000000..3b4d138babe
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportLoader.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "core/loader/DocumentWriter.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
+
+
+namespace WebCore {
+
+HTMLImportLoader::HTMLImportLoader(HTMLImportsController* controller)
+ : m_controller(controller)
+ , m_state(StateLoading)
+ , m_microtaskQueue(CustomElementSyncMicrotaskQueue::create())
+{
+}
+
+HTMLImportLoader::~HTMLImportLoader()
+{
+#if !ENABLE(OILPAN)
+ clear();
+#endif
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportLoader::importDestroyed()
+{
+ clear();
+}
+
+void HTMLImportLoader::clear()
+{
+ m_controller = nullptr;
+ if (m_document) {
+ m_document->setImportsController(0);
+ m_document->cancelParsing();
+ m_document.clear();
+ }
+}
+#endif
+
+void HTMLImportLoader::startLoading(const ResourcePtr<RawResource>& resource)
+{
+ setResource(resource);
+}
+
+void HTMLImportLoader::responseReceived(Resource* resource, const ResourceResponse& response)
+{
+ // Resource may already have been loaded with the import loader
+ // being added as a client later & now being notified. Fail early.
+ if (resource->loadFailedOrCanceled() || response.httpStatusCode() >= 400) {
+ setState(StateError);
+ return;
+ }
+ setState(startWritingAndParsing(response));
+}
+
+void HTMLImportLoader::dataReceived(Resource*, const char* data, int length)
+{
+ RefPtrWillBeRawPtr<DocumentWriter> protectingWriter(m_writer.get());
+ m_writer->addData(data, length);
+}
+
+void HTMLImportLoader::notifyFinished(Resource* resource)
+{
+ // The writer instance indicates that a part of the document can be already loaded.
+ // We don't take such a case as an error because the partially-loaded document has been visible from script at this point.
+ if (resource->loadFailedOrCanceled() && !m_writer) {
+ setState(StateError);
+ return;
+ }
+
+ setState(finishWriting());
+}
+
+HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(const ResourceResponse& response)
+{
+ ASSERT(!m_imports.isEmpty());
+ DocumentInit init = DocumentInit(response.url(), 0, m_controller->master()->contextDocument(), m_controller)
+ .withRegistrationContext(m_controller->master()->registrationContext());
+ m_document = HTMLDocument::create(init);
+ m_writer = DocumentWriter::create(m_document.get(), response.mimeType(), "UTF-8");
+
+ return StateLoading;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishWriting()
+{
+ return StateWritten;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishParsing()
+{
+ return StateParsed;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishLoading()
+{
+ return StateLoaded;
+}
+
+void HTMLImportLoader::setState(State state)
+{
+ if (m_state == state)
+ return;
+
+ m_state = state;
+
+ if (m_state == StateParsed || m_state == StateError || m_state == StateWritten) {
+ if (RefPtrWillBeRawPtr<DocumentWriter> writer = m_writer.release())
+ writer->end();
+ }
+
+ // Since DocumentWriter::end() can let setState() reenter, we shouldn't refer to m_state here.
+ if (state == StateLoaded || state == StateError)
+ didFinishLoading();
+}
+
+void HTMLImportLoader::didFinishParsing()
+{
+ setState(finishParsing());
+ if (!hasPendingResources())
+ setState(finishLoading());
+}
+
+void HTMLImportLoader::didRemoveAllPendingStylesheet()
+{
+ if (m_state == StateParsed)
+ setState(finishLoading());
+}
+
+bool HTMLImportLoader::hasPendingResources() const
+{
+ return m_document && m_document->styleEngine()->hasPendingSheets();
+}
+
+void HTMLImportLoader::didFinishLoading()
+{
+ for (size_t i = 0; i < m_imports.size(); ++i)
+ m_imports[i]->didFinishLoading();
+
+ clearResource();
+
+ ASSERT(!m_document || !m_document->parsing());
+}
+
+void HTMLImportLoader::moveToFirst(HTMLImportChild* import)
+{
+ size_t position = m_imports.find(import);
+ ASSERT(kNotFound != position);
+ m_imports.remove(position);
+ m_imports.insert(0, import);
+}
+
+void HTMLImportLoader::addImport(HTMLImportChild* import)
+{
+ ASSERT(kNotFound == m_imports.find(import));
+
+ m_imports.append(import);
+ import->normalize();
+ if (isDone())
+ import->didFinishLoading();
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportLoader::removeImport(HTMLImportChild* client)
+{
+ ASSERT(kNotFound != m_imports.find(client));
+ m_imports.remove(m_imports.find(client));
+}
+#endif
+
+bool HTMLImportLoader::shouldBlockScriptExecution() const
+{
+ return firstImport()->state().shouldBlockScriptExecution();
+}
+
+PassRefPtrWillBeRawPtr<CustomElementSyncMicrotaskQueue> HTMLImportLoader::microtaskQueue() const
+{
+ return m_microtaskQueue;
+}
+
+void HTMLImportLoader::trace(Visitor* visitor)
+{
+ visitor->trace(m_controller);
+#if ENABLE(OILPAN)
+ visitor->trace(m_imports);
+#endif
+ visitor->trace(m_document);
+ visitor->trace(m_writer);
+ visitor->trace(m_microtaskQueue);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h
index 83ea998e310..45d05e38469 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h
@@ -31,50 +31,77 @@
#ifndef HTMLImportLoader_h
#define HTMLImportLoader_h
-#include "core/html/HTMLImportResourceOwner.h"
+#include "core/fetch/RawResource.h"
+#include "core/fetch/ResourceOwner.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
+class CustomElementSyncMicrotaskQueue;
class Document;
class DocumentWriter;
-class HTMLImport;
-class HTMLImportLoaderClient;
+class HTMLImportChild;
+class HTMLImportsController;
+
//
-// Owning imported Document lifetime. It also implements ResourceClient through HTMLImportResourceOwner
+// Owning imported Document lifetime. It also implements ResourceClient through ResourceOwner
// to feed fetched bytes to the DocumentWriter of the imported document.
-// HTMLImportLoader is owned by and shared between HTMLImportChild.
+// HTMLImportLoader is owned by HTMLImportsController.
//
//
-class HTMLImportLoader : public RefCounted<HTMLImportLoader>, public HTMLImportResourceOwner {
+class HTMLImportLoader FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLImportLoader>, public ResourceOwner<RawResource> {
public:
enum State {
StateLoading,
StateWritten,
- StateError,
- StateReady
+ StateParsed,
+ StateLoaded,
+ StateError
};
- static PassRefPtr<HTMLImportLoader> create(HTMLImport*, ResourceFetcher*);
+ static PassOwnPtrWillBeRawPtr<HTMLImportLoader> create(HTMLImportsController* controller)
+ {
+ return adoptPtrWillBeNoop(new HTMLImportLoader(controller));
+ }
virtual ~HTMLImportLoader();
- Document* document() const { return m_importedDocument.get(); }
- Document* importedDocument() const;
- void addClient(HTMLImportLoaderClient*);
- void removeClient(HTMLImportLoaderClient*);
-
- bool isDone() const { return m_state == StateReady || m_state == StateError; }
- bool isLoaded() const { return m_state == StateReady; }
- bool isProcessing() const;
-
+ Document* document() const { return m_document.get(); }
+ void addImport(HTMLImportChild*);
+#if !ENABLE(OILPAN)
+ void removeImport(HTMLImportChild*);
+#endif
+ void moveToFirst(HTMLImportChild*);
+ HTMLImportChild* firstImport() const { return m_imports[0]; }
+ bool isFirstImport(const HTMLImportChild* child) const { return m_imports.size() ? firstImport() == child : false; }
+
+ bool isDone() const { return m_state == StateLoaded || m_state == StateError; }
+ bool hasError() const { return m_state == StateError; }
+ bool shouldBlockScriptExecution() const;
+
+#if !ENABLE(OILPAN)
+ void importDestroyed();
+#endif
void startLoading(const ResourcePtr<RawResource>&);
+
+ // Tells the loader that the parser is done with this import.
+ // Called by Document::finishedParsing, after DOMContentLoaded was dispatched.
void didFinishParsing();
- bool isOwnedBy(const HTMLImport* import) const { return m_import == import; }
+ // Tells the loader that all of the import's stylesheets finished
+ // loading.
+ // Called by Document::didRemoveAllPendingStylesheet.
+ void didRemoveAllPendingStylesheet();
+
+ PassRefPtrWillBeRawPtr<CustomElementSyncMicrotaskQueue> microtaskQueue() const;
+
+ virtual void trace(Visitor*);
private:
- HTMLImportLoader(HTMLImport*, ResourceFetcher*);
+ HTMLImportLoader(HTMLImportsController*);
// RawResourceClient
virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE;
@@ -84,16 +111,21 @@ private:
State startWritingAndParsing(const ResourceResponse&);
State finishWriting();
State finishParsing();
+ State finishLoading();
void setState(State);
- void didFinish();
-
- HTMLImport* m_import;
- ResourceFetcher* m_fetcher;
- Vector<HTMLImportLoaderClient*> m_clients;
+ void didFinishLoading();
+ bool hasPendingResources() const;
+#if !ENABLE(OILPAN)
+ void clear();
+#endif
+
+ RawPtrWillBeMember<HTMLImportsController> m_controller;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImportChild> > m_imports;
State m_state;
- RefPtr<Document> m_importedDocument;
- RefPtr<DocumentWriter> m_writer;
+ RefPtrWillBeMember<Document> m_document;
+ RefPtrWillBeMember<DocumentWriter> m_writer;
+ RefPtrWillBeMember<CustomElementSyncMicrotaskQueue> m_microtaskQueue;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h
index 77741ecc588..356a40df39b 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2014 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
@@ -28,35 +28,50 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef HTMLShadowElement_h
-#define HTMLShadowElement_h
+#ifndef HTMLImportState_h
+#define HTMLImportState_h
-#include "core/dom/shadow/InsertionPoint.h"
-#include "wtf/Forward.h"
+#include "wtf/Assertions.h"
namespace WebCore {
-class HTMLShadowElement FINAL : public InsertionPoint {
+class HTMLImportState {
public:
- static PassRefPtr<HTMLShadowElement> create(Document&);
+ enum Value {
+ BlockingScriptExecution = 0,
+ Active,
+ Ready,
+ Invalid
+ };
- virtual ~HTMLShadowElement();
+ explicit HTMLImportState(Value value = BlockingScriptExecution)
+ : m_value(value)
+ { }
- ShadowRoot* olderShadowRoot();
+ bool shouldBlockScriptExecution() const { return checkedValue() <= BlockingScriptExecution; }
+ bool isReady() const { return checkedValue() == Ready; }
+ bool isValid() const { return m_value != Invalid; }
+ bool operator==(const HTMLImportState& other) const { return m_value == other.m_value; }
+ bool operator!=(const HTMLImportState& other) const { return !(*this == other); }
+ bool operator<=(const HTMLImportState& other) const { return m_value <= other.m_value; }
+#if !defined(NDEBUG)
+ Value peekValueForDebug() const { return m_value; }
+#endif
+
+ static HTMLImportState invalidState() { return HTMLImportState(Invalid); }
+ static HTMLImportState blockedState() { return HTMLImportState(BlockingScriptExecution); }
private:
- explicit HTMLShadowElement(Document&);
- virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint) OVERRIDE;
+ Value checkedValue() const;
+ Value m_value;
};
-inline bool isHTMLShadowElement(const Node* node)
+inline HTMLImportState::Value HTMLImportState::checkedValue() const
{
- ASSERT(node);
- return node->hasTagName(HTMLNames::shadowTag);
+ ASSERT(isValid());
+ return m_value;
}
-DEFINE_NODE_TYPE_CASTS(HTMLShadowElement, hasTagName(HTMLNames::shadowTag));
-
-} // namespace WebCore
+}
-#endif // HTMLShadowElement_h
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp
new file mode 100644
index 00000000000..9a1f2bfa534
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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 "core/html/imports/HTMLImportStateResolver.h"
+
+#include "core/html/imports/HTMLImport.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
+
+namespace WebCore {
+
+inline bool HTMLImportStateResolver::isBlockingFollowers(HTMLImport* import)
+{
+ if (!import->isSync())
+ return false;
+ HTMLImportChild* child = toHTMLImportChild(import);
+ if (!child->loader()->isFirstImport(child))
+ return false;
+ return !import->state().isReady();
+}
+
+inline bool HTMLImportStateResolver::shouldBlockScriptExecution() const
+{
+ // FIXME: Memoize to make this faster.
+ for (HTMLImport* ancestor = m_import; ancestor; ancestor = ancestor->parent()) {
+ for (HTMLImport* predecessor = ancestor->previous(); predecessor; predecessor = predecessor->previous()) {
+ if (isBlockingFollowers(predecessor))
+ return true;
+ }
+ }
+
+ for (HTMLImport* child = m_import->firstChild(); child; child = child->next()) {
+ if (isBlockingFollowers(child))
+ return true;
+ }
+
+ return false;
+}
+
+inline bool HTMLImportStateResolver::isActive() const
+{
+ return !m_import->isDone();
+}
+
+HTMLImportState HTMLImportStateResolver::resolve() const
+{
+ if (shouldBlockScriptExecution())
+ return HTMLImportState(HTMLImportState::BlockingScriptExecution);
+ if (isActive())
+ return HTMLImportState(HTMLImportState::Active);
+ return HTMLImportState(HTMLImportState::Ready);
+}
+
+}
+
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h
new file mode 100644
index 00000000000..0850380bf62
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 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 HTMLImportStateResolver_h
+#define HTMLImportStateResolver_h
+
+#include "core/html/imports/HTMLImportState.h"
+
+namespace WebCore {
+
+class HTMLImport;
+
+class HTMLImportStateResolver {
+public:
+ explicit HTMLImportStateResolver(HTMLImport* import)
+ : m_import(import)
+ { }
+
+ HTMLImportState resolve() const;
+
+private:
+ static bool isBlockingFollowers(HTMLImport*);
+
+ bool shouldBlockScriptExecution() const;
+ bool isActive() const;
+
+ HTMLImport* m_import;
+};
+
+}
+
+#endif // HTMLImportStateResolver_h
+
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
new file mode 100644
index 00000000000..bfe0beded33
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
@@ -0,0 +1,110 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/imports/HTMLImportChild.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<HTMLImportTreeRoot> HTMLImportTreeRoot::create(Document* document)
+{
+ return adoptPtrWillBeNoop(new HTMLImportTreeRoot(document));
+}
+
+HTMLImportTreeRoot::HTMLImportTreeRoot(Document* document)
+ : HTMLImport(HTMLImport::Sync)
+ , m_document(document)
+ , m_recalcTimer(this, &HTMLImportTreeRoot::recalcTimerFired)
+{
+ recalcTreeState(this); // This recomputes initial state.
+}
+
+HTMLImportTreeRoot::~HTMLImportTreeRoot()
+{
+#if !ENABLE(OILPAN)
+ for (size_t i = 0; i < m_imports.size(); ++i)
+ m_imports[i]->importDestroyed();
+ m_imports.clear();
+ m_document = nullptr;
+#endif
+}
+
+Document* HTMLImportTreeRoot::document() const
+{
+ return m_document;
+}
+
+bool HTMLImportTreeRoot::isDone() const
+{
+ return !m_document->parsing() && m_document->styleEngine()->haveStylesheetsLoaded();
+}
+
+void HTMLImportTreeRoot::stateWillChange()
+{
+ scheduleRecalcState();
+}
+
+void HTMLImportTreeRoot::stateDidChange()
+{
+ HTMLImport::stateDidChange();
+
+ if (!state().isReady())
+ return;
+ if (LocalFrame* frame = m_document->frame())
+ frame->loader().checkCompleted();
+}
+
+void HTMLImportTreeRoot::scheduleRecalcState()
+{
+#if ENABLE(OILPAN)
+ ASSERT(m_document);
+ if (m_recalcTimer.isActive() || !m_document->isActive())
+ return;
+#else
+ if (m_recalcTimer.isActive() || !m_document)
+ return;
+#endif
+ m_recalcTimer.startOneShot(0, FROM_HERE);
+}
+
+HTMLImportChild* HTMLImportTreeRoot::add(PassOwnPtrWillBeRawPtr<HTMLImportChild> child)
+{
+ m_imports.append(child);
+ return m_imports.last().get();
+}
+
+HTMLImportChild* HTMLImportTreeRoot::find(const KURL& url) const
+{
+ for (size_t i = 0; i < m_imports.size(); ++i) {
+ HTMLImportChild* candidate = m_imports[i].get();
+ if (equalIgnoringFragmentIdentifier(candidate->url(), url))
+ return candidate;
+ }
+
+ return 0;
+}
+
+void HTMLImportTreeRoot::recalcTimerFired(Timer<HTMLImportTreeRoot>*)
+{
+ ASSERT(m_document);
+
+ do {
+ m_recalcTimer.stop();
+ HTMLImport::recalcTreeState(this);
+ } while (m_recalcTimer.isActive());
+}
+
+void HTMLImportTreeRoot::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_imports);
+ HTMLImport::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h
new file mode 100644
index 00000000000..6cd31168fd0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h
@@ -0,0 +1,52 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLImportTreeRoot_h
+#define HTMLImportTreeRoot_h
+
+#include "core/html/imports/HTMLImport.h"
+#include "platform/Timer.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace WebCore {
+
+class HTMLImportChild;
+
+class HTMLImportTreeRoot : public HTMLImport {
+public:
+ static PassOwnPtrWillBeRawPtr<HTMLImportTreeRoot> create(Document*);
+
+ virtual ~HTMLImportTreeRoot();
+
+ // HTMLImport
+ virtual Document* document() const OVERRIDE;
+ virtual bool isDone() const OVERRIDE;
+ virtual void stateWillChange() OVERRIDE;
+ virtual void stateDidChange() OVERRIDE;
+
+ void scheduleRecalcState();
+
+ HTMLImportChild* add(PassOwnPtrWillBeRawPtr<HTMLImportChild>);
+ HTMLImportChild* find(const KURL&) const;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit HTMLImportTreeRoot(Document*);
+
+ void recalcTimerFired(Timer<HTMLImportTreeRoot>*);
+
+ RawPtrWillBeMember<Document> m_document;
+ Timer<HTMLImportTreeRoot> m_recalcTimer;
+
+ // List of import which has been loaded or being loaded.
+ typedef WillBeHeapVector<OwnPtrWillBeMember<HTMLImportChild> > ImportList;
+ ImportList m_imports;
+};
+
+DEFINE_TYPE_CASTS(HTMLImportTreeRoot, HTMLImport, import, import->isRoot(), import.isRoot());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp
new file mode 100644
index 00000000000..8afd0dd7449
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportsController.h"
+
+#include "core/dom/Document.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportChildClient.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+
+namespace WebCore {
+
+void HTMLImportsController::provideTo(Document& master)
+{
+ DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController"));
+ OwnPtrWillBeRawPtr<HTMLImportsController> controller = adoptPtrWillBeNoop(new HTMLImportsController(master));
+ master.setImportsController(controller.get());
+ DocumentSupplement::provideTo(master, name, controller.release());
+}
+
+HTMLImportsController::HTMLImportsController(Document& master)
+ : m_root(HTMLImportTreeRoot::create(&master))
+{
+ UseCounter::count(master, UseCounter::HTMLImports);
+}
+
+HTMLImportsController::~HTMLImportsController()
+{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_root);
+#endif
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportsController::clear()
+{
+ Document* master = root()->document();
+ m_root.clear();
+
+ for (size_t i = 0; i < m_loaders.size(); ++i)
+ m_loaders[i]->importDestroyed();
+ m_loaders.clear();
+
+ if (master)
+ master->setImportsController(0);
+}
+#endif
+
+static bool makesCycle(HTMLImport* parent, const KURL& url)
+{
+ for (HTMLImport* ancestor = parent; ancestor; ancestor = ancestor->parent()) {
+ if (!ancestor->isRoot() && equalIgnoringFragmentIdentifier(toHTMLImportChild(parent)->url(), url))
+ return true;
+ }
+
+ return false;
+}
+
+HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImportLoader* loader, HTMLImport* parent, HTMLImportChildClient* client)
+{
+ HTMLImport::SyncMode mode = client->isSync() && !makesCycle(parent, url) ? HTMLImport::Sync : HTMLImport::Async;
+ if (mode == HTMLImport::Async)
+ UseCounter::count(root()->document(), UseCounter::HTMLImportsAsyncAttribute);
+
+ OwnPtrWillBeRawPtr<HTMLImportChild> child = adoptPtrWillBeNoop(new HTMLImportChild(url, loader, mode));
+ child->setClient(client);
+ parent->appendImport(child.get());
+ loader->addImport(child.get());
+ return root()->add(child.release());
+}
+
+HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChildClient* client, FetchRequest request)
+{
+ ASSERT(!request.url().isEmpty() && request.url().isValid());
+ ASSERT(parent == root() || toHTMLImportChild(parent)->loader()->isFirstImport(toHTMLImportChild(parent)));
+
+ if (HTMLImportChild* childToShareWith = root()->find(request.url())) {
+ HTMLImportLoader* loader = childToShareWith->loader();
+ ASSERT(loader);
+ HTMLImportChild* child = createChild(request.url(), loader, parent, client);
+ child->didShareLoader();
+ return child;
+ }
+
+ bool sameOriginRequest = master()->securityOrigin()->canRequest(request.url());
+ request.setCrossOriginAccessControl(
+ master()->securityOrigin(), sameOriginRequest ? AllowStoredCredentials : DoNotAllowStoredCredentials,
+ ClientDidNotRequestCredentials);
+ ResourcePtr<RawResource> resource = parent->document()->fetcher()->fetchImport(request);
+ if (!resource)
+ return 0;
+
+ HTMLImportLoader* loader = createLoader();
+ HTMLImportChild* child = createChild(request.url(), loader, parent, client);
+ // We set resource after the import tree is built since
+ // Resource::addClient() immediately calls back to feed the bytes when the resource is cached.
+ loader->startLoading(resource);
+ child->didStartLoading();
+ return child;
+}
+
+Document* HTMLImportsController::master() const
+{
+ return root()->document();
+}
+
+bool HTMLImportsController::shouldBlockScriptExecution(const Document& document) const
+{
+ ASSERT(document.importsController() == this);
+ if (HTMLImportLoader* loader = loaderFor(document))
+ return loader->shouldBlockScriptExecution();
+ return root()->state().shouldBlockScriptExecution();
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportsController::wasDetachedFrom(const Document& document)
+{
+ ASSERT(document.importsController() == this);
+ if (master() == &document)
+ clear();
+}
+#endif
+
+HTMLImportLoader* HTMLImportsController::createLoader()
+{
+ m_loaders.append(HTMLImportLoader::create(this));
+ return m_loaders.last().get();
+}
+
+HTMLImportLoader* HTMLImportsController::loaderFor(const Document& document) const
+{
+ for (size_t i = 0; i < m_loaders.size(); ++i) {
+ if (m_loaders[i]->document() == &document)
+ return m_loaders[i].get();
+ }
+
+ return 0;
+}
+
+Document* HTMLImportsController::loaderDocumentAt(size_t i) const
+{
+ return loaderAt(i)->document();
+}
+
+void HTMLImportsController::trace(Visitor* visitor)
+{
+ visitor->trace(m_root);
+ visitor->trace(m_loaders);
+ DocumentSupplement::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h
index 7cc1b92ea08..414fe464396 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h
@@ -31,9 +31,10 @@
#ifndef HTMLImportsController_h
#define HTMLImportsController_h
+#include "core/dom/DocumentSupplementable.h"
#include "core/fetch/RawResource.h"
-#include "core/html/HTMLImport.h"
#include "core/html/LinkResource.h"
+#include "core/html/imports/HTMLImport.h"
#include "platform/Supplementable.h"
#include "platform/Timer.h"
#include "wtf/FastAllocBase.h"
@@ -47,47 +48,46 @@ class ExecutionContext;
class ResourceFetcher;
class HTMLImportChild;
class HTMLImportChildClient;
+class HTMLImportLoader;
+class HTMLImportTreeRoot;
-class HTMLImportsController : public HTMLImportRoot, public DocumentSupplement {
- WTF_MAKE_FAST_ALLOCATED;
+class HTMLImportsController FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLImportsController>, public DocumentSupplement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLImportsController);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static void provideTo(Document*);
+ static void provideTo(Document&);
- explicit HTMLImportsController(Document*);
+ explicit HTMLImportsController(Document&);
virtual ~HTMLImportsController();
- // HTMLImport
- virtual HTMLImportRoot* root() OVERRIDE;
- virtual Document* document() const OVERRIDE;
- virtual void wasDetachedFromDocument() OVERRIDE;
- virtual void didFinishParsing() OVERRIDE;
- virtual bool isProcessing() const OVERRIDE;
- virtual bool isDone() const OVERRIDE;
-
- // HTMLImportRoot
- virtual void blockerGone() OVERRIDE;
- virtual HTMLImportsController* toController() OVERRIDE { return this; }
- virtual HTMLImportChild* findLinkFor(const KURL&, HTMLImport* excluding = 0) const OVERRIDE;
+ HTMLImportTreeRoot* root() const { return m_root.get(); }
+ bool shouldBlockScriptExecution(const Document&) const;
+#if !ENABLE(OILPAN)
+ void wasDetachedFrom(const Document&);
+#endif
HTMLImportChild* load(HTMLImport* parent, HTMLImportChildClient*, FetchRequest);
- void showSecurityErrorMessage(const String&);
- SecurityOrigin* securityOrigin() const;
- ResourceFetcher* fetcher() const;
+ Document* master() const;
+
+ HTMLImportLoader* createLoader();
- void scheduleUnblock();
- void unblockTimerFired(Timer<HTMLImportsController>*);
+ size_t loaderCount() const { return m_loaders.size(); }
+ HTMLImportLoader* loaderAt(size_t i) const { return m_loaders[i].get(); }
+ Document* loaderDocumentAt(size_t) const;
+ HTMLImportLoader* loaderFor(const Document&) const;
+
+ virtual void trace(Visitor*);
private:
- HTMLImportChild* createChild(const KURL&, HTMLImport* parent, HTMLImportChildClient*);
+ HTMLImportChild* createChild(const KURL&, HTMLImportLoader*, HTMLImport* parent, HTMLImportChildClient*);
+#if !ENABLE(OILPAN)
void clear();
+#endif
- Document* m_master;
- Timer<HTMLImportsController> m_unblockTimer;
-
- // List of import which has been loaded or being loaded.
- typedef Vector<OwnPtr<HTMLImportChild> > ImportList;
- ImportList m_imports;
+ OwnPtrWillBeMember<HTMLImportTreeRoot> m_root;
+ typedef WillBeHeapVector<OwnPtrWillBeMember<HTMLImportLoader> > LoaderList;
+ LoaderList m_loaders;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkImport.cpp b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
index 18e5d4a51a7..0f5a9840211 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkImport.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
@@ -29,52 +29,60 @@
*/
#include "config.h"
-#include "core/html/LinkImport.h"
+#include "core/html/imports/LinkImport.h"
#include "core/dom/Document.h"
#include "core/fetch/CrossOriginAccessControl.h"
-#include "core/html/HTMLImportChild.h"
-#include "core/html/HTMLImportsController.h"
#include "core/html/HTMLLinkElement.h"
-
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+#include "core/html/imports/HTMLImportsController.h"
namespace WebCore {
-PassOwnPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner)
+PassOwnPtrWillBeRawPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner)
{
- return adoptPtr(new LinkImport(owner));
+ return adoptPtrWillBeNoop(new LinkImport(owner));
}
LinkImport::LinkImport(HTMLLinkElement* owner)
: LinkResource(owner)
- , m_loader(0)
+ , m_child(nullptr)
{
}
LinkImport::~LinkImport()
{
- clear();
+#if !ENABLE(OILPAN)
+ if (m_child) {
+ m_child->clearClient();
+ m_child = nullptr;
+ }
+#endif
}
Document* LinkImport::importedDocument() const
{
- if (!m_loader)
+ if (!m_child || !m_owner || !m_owner->inDocument())
+ return 0;
+ if (m_child->loader()->hasError())
return 0;
- return m_loader->importedDocument();
+ return m_child->document();
}
void LinkImport::process()
{
- if (m_loader)
+ if (m_child)
return;
if (!m_owner)
return;
if (!shouldLoadResource())
return;
- if (!m_owner->document().import()) {
+ if (!m_owner->document().importsController()) {
ASSERT(m_owner->document().frame()); // The document should be the master.
- HTMLImportsController::provideTo(&m_owner->document());
+ HTMLImportsController::provideTo(m_owner->document());
}
LinkRequestBuilder builder(m_owner);
@@ -83,44 +91,60 @@ void LinkImport::process()
return;
}
- HTMLImport* parent = m_owner->document().import();
- HTMLImportsController* controller = parent->controller();
- m_loader = controller->load(parent, this, builder.build(true));
- if (!m_loader) {
+ HTMLImportsController* controller = m_owner->document().importsController();
+ HTMLImportLoader* loader = m_owner->document().importLoader();
+ HTMLImport* parent = loader ? static_cast<HTMLImport*>(loader->firstImport()) : static_cast<HTMLImport*>(controller->root());
+ m_child = controller->load(parent, this, builder.build(true));
+ if (!m_child) {
didFinish();
return;
}
}
-void LinkImport::clear()
+void LinkImport::didFinish()
{
- m_owner = 0;
- if (m_loader) {
- m_loader->clearClient();
- m_loader = 0;
- }
+ if (!m_owner || !m_owner->inDocument())
+ return;
+ m_owner->scheduleEvent();
}
-void LinkImport::ownerRemoved()
+#if !ENABLE(OILPAN)
+void LinkImport::importChildWasDestroyed(HTMLImportChild* child)
{
- clear();
+ ASSERT(m_child == child);
+ m_child = nullptr;
+ m_owner = nullptr;
}
+#endif
-void LinkImport::didFinish()
+bool LinkImport::isSync() const
{
- if (!m_owner)
- return;
- m_owner->scheduleEvent();
+ return m_owner && !m_owner->async();
}
-void LinkImport::loaderWillBeDestroyed()
+HTMLLinkElement* LinkImport::link()
{
- clear();
+ return m_owner;
}
bool LinkImport::hasLoaded() const
{
- return m_loader && m_loader->isLoaded();
+ // Should never be called after importChildWasDestroyed was called.
+ ASSERT(m_owner);
+ return m_child && m_child->isDone() && !m_child->loader()->hasError();
+}
+
+void LinkImport::ownerInserted()
+{
+ if (m_child)
+ m_child->ownerInserted();
+}
+
+void LinkImport::trace(Visitor* visitor)
+{
+ visitor->trace(m_child);
+ HTMLImportChildClient::trace(visitor);
+ LinkResource::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkImport.h b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h
index bc2ec95bfb5..e56339f68dc 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkImport.h
+++ b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h
@@ -31,8 +31,8 @@
#ifndef LinkImport_h
#define LinkImport_h
-#include "core/html/HTMLImportChildClient.h"
#include "core/html/LinkResource.h"
+#include "core/html/imports/HTMLImportChildClient.h"
#include "wtf/FastAllocBase.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
@@ -45,11 +45,12 @@ class HTMLImportChild;
//
// A LinkResource subclasss used for @rel=import.
//
-class LinkImport : public LinkResource, public HTMLImportChildClient {
- WTF_MAKE_FAST_ALLOCATED;
+class LinkImport FINAL : public LinkResource, public HTMLImportChildClient {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(LinkImport);
public:
- static PassOwnPtr<LinkImport> create(HTMLLinkElement* owner);
+ static PassOwnPtrWillBeRawPtr<LinkImport> create(HTMLLinkElement* owner);
explicit LinkImport(HTMLLinkElement* owner);
virtual ~LinkImport();
@@ -57,19 +58,22 @@ public:
// LinkResource
virtual void process() OVERRIDE;
virtual Type type() const OVERRIDE { return Import; }
- virtual void ownerRemoved() OVERRIDE;
virtual bool hasLoaded() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+ virtual void ownerInserted() OVERRIDE;
// HTMLImportChildClient
virtual void didFinish() OVERRIDE;
- virtual void loaderWillBeDestroyed() OVERRIDE;
+#if !ENABLE(OILPAN)
+ virtual void importChildWasDestroyed(HTMLImportChild*) OVERRIDE;
+#endif
+ virtual bool isSync() const OVERRIDE;
+ virtual HTMLLinkElement* link() OVERRIDE;
Document* importedDocument() const;
private:
- void clear();
-
- HTMLImportChild* m_loader;
+ RawPtrWillBeMember<HTMLImportChild> m_child;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h b/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
index 63e8c0c86dc..7254ab88480 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
@@ -26,7 +26,7 @@
#ifndef AtomicHTMLToken_h
#define AtomicHTMLToken_h
-#include "HTMLElementLookupTrie.h"
+#include "core/HTMLElementLookupTrie.h"
#include "core/dom/Attribute.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLToken.h"
@@ -150,7 +150,7 @@ public:
ASSERT_NOT_REACHED();
break;
case HTMLToken::DOCTYPE:
- m_name = token.data();
+ m_name = AtomicString(token.data());
m_doctypeData = adoptPtr(new DoctypeData());
m_doctypeData->m_hasPublicIdentifier = true;
append(m_doctypeData->m_publicIdentifier, token.publicIdentifier());
@@ -163,15 +163,15 @@ public:
case HTMLToken::StartTag:
m_attributes.reserveInitialCapacity(token.attributes().size());
for (Vector<CompactHTMLToken::Attribute>::const_iterator it = token.attributes().begin(); it != token.attributes().end(); ++it) {
- QualifiedName name(nullAtom, it->name, nullAtom);
+ QualifiedName name(nullAtom, AtomicString(it->name), nullAtom);
// FIXME: This is N^2 for the number of attributes.
if (!findAttributeInVector(m_attributes, name))
- m_attributes.append(Attribute(name, it->value));
+ m_attributes.append(Attribute(name, AtomicString(it->value)));
}
// Fall through!
case HTMLToken::EndTag:
m_selfClosing = token.selfClosing();
- m_name = token.data();
+ m_name = AtomicString(token.data());
break;
case HTMLToken::Character:
case HTMLToken::Comment:
@@ -233,9 +233,7 @@ inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList
if (attribute.name.isEmpty())
continue;
- // FIXME: We should be able to add the following ASSERT once we fix
- // https://bugs.webkit.org/show_bug.cgi?id=62971
- // ASSERT(attribute.nameRange.start);
+ ASSERT(attribute.nameRange.start);
ASSERT(attribute.nameRange.end);
ASSERT(attribute.valueRange.start);
ASSERT(attribute.valueRange.end);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
index b91dafd40b9..66a62b8d1e7 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
@@ -27,7 +27,7 @@
#include "core/html/parser/BackgroundHTMLParser.h"
#include "core/html/parser/HTMLDocumentParser.h"
-#include "core/html/parser/HTMLParserThread.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditor.h"
#include "wtf/MainThread.h"
#include "wtf/text/TextPosition.h"
@@ -76,6 +76,12 @@ static void checkThatXSSInfosAreSafeToSendToAnotherThread(const XSSInfoStream& i
#endif
+void BackgroundHTMLParser::start(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
+{
+ new BackgroundHTMLParser(reference, config);
+ // Caller must free by calling stop().
+}
+
BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
: m_weakFactory(reference, this)
, m_token(adoptPtr(new HTMLToken))
@@ -86,16 +92,62 @@ BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHT
, m_pendingTokens(adoptPtr(new CompactHTMLTokenStream))
, m_xssAuditor(config->xssAuditor.release())
, m_preloadScanner(config->preloadScanner.release())
+ , m_decoder(config->decoder.release())
+{
+}
+
+BackgroundHTMLParser::~BackgroundHTMLParser()
+{
+}
+
+void BackgroundHTMLParser::appendRawBytesFromParserThread(const char* data, int dataLength)
{
+ ASSERT(m_decoder);
+ updateDocument(m_decoder->decode(data, dataLength));
}
-void BackgroundHTMLParser::append(const String& input)
+void BackgroundHTMLParser::appendRawBytesFromMainThread(PassOwnPtr<Vector<char> > buffer)
+{
+ ASSERT(m_decoder);
+ updateDocument(m_decoder->decode(buffer->data(), buffer->size()));
+}
+
+void BackgroundHTMLParser::appendDecodedBytes(const String& input)
{
ASSERT(!m_input.current().isClosed());
m_input.append(input);
pumpTokenizer();
}
+void BackgroundHTMLParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
+{
+ ASSERT(decoder);
+ m_decoder = decoder;
+}
+
+void BackgroundHTMLParser::flush()
+{
+ ASSERT(m_decoder);
+ updateDocument(m_decoder->flush());
+}
+
+void BackgroundHTMLParser::updateDocument(const String& decodedData)
+{
+ DocumentEncodingData encodingData(*m_decoder.get());
+
+ if (encodingData != m_lastSeenEncodingData) {
+ m_lastSeenEncodingData = encodingData;
+
+ m_xssAuditor->setEncoding(encodingData.encoding());
+ callOnMainThread(bind(&HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser, m_parser, encodingData));
+ }
+
+ if (decodedData.isEmpty())
+ return;
+
+ appendDecodedBytes(decodedData);
+}
+
void BackgroundHTMLParser::resumeFrom(PassOwnPtr<Checkpoint> checkpoint)
{
m_parser = checkpoint->parser;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
index b9b5a511c49..8d315a8f23e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
@@ -26,14 +26,14 @@
#ifndef BackgroundHTMLParser_h
#define BackgroundHTMLParser_h
+#include "core/dom/DocumentEncodingData.h"
#include "core/html/parser/BackgroundHTMLInputStream.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLPreloadScanner.h"
#include "core/html/parser/HTMLSourceTracker.h"
-#include "core/html/parser/HTMLToken.h"
-#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/WeakPtr.h"
@@ -41,6 +41,7 @@
namespace WebCore {
class HTMLDocumentParser;
+class SharedBuffer;
class XSSAuditor;
class BackgroundHTMLParser {
@@ -51,13 +52,10 @@ public:
WeakPtr<HTMLDocumentParser> parser;
OwnPtr<XSSAuditor> xssAuditor;
OwnPtr<TokenPreloadScanner> preloadScanner;
+ OwnPtr<TextResourceDecoder> decoder;
};
- static void create(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
- {
- new BackgroundHTMLParser(reference, config);
- // Caller must free by calling stop().
- }
+ static void start(PassRefPtr<WeakReference<BackgroundHTMLParser> >, PassOwnPtr<Configuration>);
struct Checkpoint {
WeakPtr<HTMLDocumentParser> parser;
@@ -69,7 +67,11 @@ public:
String unparsedInput;
};
- void append(const String&);
+ void appendRawBytesFromParserThread(const char* data, int dataLength);
+
+ void appendRawBytesFromMainThread(PassOwnPtr<Vector<char> >);
+ void setDecoder(PassOwnPtr<TextResourceDecoder>);
+ void flush();
void resumeFrom(PassOwnPtr<Checkpoint>);
void startedChunkWithCheckpoint(HTMLInputCheckpoint);
void finish();
@@ -79,10 +81,13 @@ public:
private:
BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> >, PassOwnPtr<Configuration>);
+ ~BackgroundHTMLParser();
+ void appendDecodedBytes(const String&);
void markEndOfFile();
void pumpTokenizer();
void sendTokensToMainThread();
+ void updateDocument(const String& decodedData);
WeakPtrFactory<BackgroundHTMLParser> m_weakFactory;
BackgroundHTMLInputStream m_input;
@@ -99,6 +104,8 @@ private:
OwnPtr<XSSAuditor> m_xssAuditor;
OwnPtr<TokenPreloadScanner> m_preloadScanner;
+ OwnPtr<TextResourceDecoder> m_decoder;
+ DocumentEncodingData m_lastSeenEncodingData;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
index b1eea275aaa..042c52a86c8 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
@@ -28,7 +28,7 @@
#include "config.h"
#include "core/html/parser/CSSPreloadScanner.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "platform/text/SegmentedString.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
index 7161a27434e..8c328997553 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
@@ -33,7 +33,6 @@
namespace WebCore {
-class HTMLIdentifier;
class SegmentedString;
class CSSPreloadScanner {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index 96dc2484b4b..71d5b6b14c8 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -25,19 +25,20 @@
*/
#include "config.h"
-#include "core/html/parser/HTMLTreeBuilder.h"
+#include "core/html/parser/HTMLConstructionSite.h"
-#include "HTMLElementFactory.h"
-#include "HTMLNames.h"
+#include "core/HTMLElementFactory.h"
+#include "core/HTMLNames.h"
#include "core/dom/Comment.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ScriptLoader.h"
#include "core/dom/Text.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLOptGroupElement.h"
+#include "core/html/HTMLPlugInElement.h"
#include "core/html/HTMLScriptElement.h"
#include "core/html/HTMLTemplateElement.h"
#include "core/html/parser/AtomicHTMLToken.h"
@@ -46,7 +47,7 @@
#include "core/html/parser/HTMLToken.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
+#include "core/svg/SVGScriptElement.h"
#include "platform/NotImplemented.h"
#include "platform/text/TextBreakIterator.h"
#include <limits>
@@ -70,20 +71,20 @@ static bool hasImpliedEndTag(const HTMLStackItem* item)
|| item->hasTagName(dtTag)
|| item->hasTagName(liTag)
|| item->hasTagName(optionTag)
- || isHTMLOptGroupElement(item->node())
+ || item->hasTagName(optgroupTag)
|| item->hasTagName(pTag)
|| item->hasTagName(rpTag)
|| item->hasTagName(rtTag);
}
-static bool shouldUseLengthLimit(const ContainerNode* node)
+static bool shouldUseLengthLimit(const ContainerNode& node)
{
- return !node->hasTagName(scriptTag)
- && !node->hasTagName(styleTag)
- && !node->hasTagName(SVGNames::scriptTag);
+ return !isHTMLScriptElement(node)
+ && !isHTMLStyleElement(node)
+ && !isSVGScriptElement(node);
}
-static unsigned textLengthLimitForContainer(const ContainerNode* node)
+static unsigned textLengthLimitForContainer(const ContainerNode& node)
{
return shouldUseLengthLimit(node) ? Text::defaultLengthLimit : std::numeric_limits<unsigned>::max();
}
@@ -95,7 +96,7 @@ static inline bool isAllWhitespace(const String& string)
static inline void insert(HTMLConstructionSiteTask& task)
{
- if (task.parent->hasTagName(templateTag))
+ if (isHTMLTemplateElement(*task.parent))
task.parent = toHTMLTemplateElement(task.parent.get())->content();
if (ContainerNode* parent = task.child->parentNode())
@@ -113,10 +114,12 @@ static inline void executeInsertTask(HTMLConstructionSiteTask& task)
insert(task);
- task.child->beginParsingChildren();
-
- if (task.selfClosing)
- task.child->finishParsingChildren();
+ if (task.child->isElementNode()) {
+ Element& child = toElement(*task.child);
+ child.beginParsingChildren();
+ if (task.selfClosing)
+ child.finishParsingChildren();
+ }
}
static inline void executeInsertTextTask(HTMLConstructionSiteTask& task)
@@ -130,7 +133,7 @@ static inline void executeInsertTextTask(HTMLConstructionSiteTask& task)
Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : task.parent->lastChild();
if (previousChild && previousChild->isTextNode()) {
Text* previousText = toText(previousChild);
- unsigned lengthLimit = textLengthLimitForContainer(task.parent.get());
+ unsigned lengthLimit = textLengthLimitForContainer(*task.parent);
if (previousText->length() + newText->length() < lengthLimit) {
previousText->parserAppendData(newText->data());
return;
@@ -238,7 +241,7 @@ void HTMLConstructionSite::flushPendingText()
// Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary
// for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
- unsigned lengthLimit = textLengthLimitForContainer(pendingText.parent.get());
+ unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);
unsigned currentPosition = 0;
const StringBuilder& string = pendingText.stringBuilder;
@@ -269,10 +272,10 @@ void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task)
m_taskQueue.append(task);
}
-void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> prpChild, bool selfClosing)
+void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtrWillBeRawPtr<Node> prpChild, bool selfClosing)
{
ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->isElementNode() || !toScriptLoaderIfPossible(toElement(prpChild.get())));
- ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !prpChild->isPluginElement());
+ ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !isHTMLPlugInElement(prpChild));
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
task.parent = parent;
@@ -343,14 +346,26 @@ HTMLConstructionSite::~HTMLConstructionSite()
ASSERT(m_pendingText.isEmpty());
}
+void HTMLConstructionSite::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_attachmentRoot);
+ visitor->trace(m_head);
+ visitor->trace(m_form);
+ visitor->trace(m_openElements);
+ visitor->trace(m_activeFormattingElements);
+ visitor->trace(m_taskQueue);
+ visitor->trace(m_pendingText);
+}
+
void HTMLConstructionSite::detach()
{
// FIXME: We'd like to ASSERT here that we're canceling and not just discarding
// text that really should have made it into the DOM earlier, but there
// doesn't seem to be a nice way to do that.
m_pendingText.discard();
- m_document = 0;
- m_attachmentRoot = 0;
+ m_document = nullptr;
+ m_attachmentRoot = nullptr;
}
void HTMLConstructionSite::setForm(HTMLFormElement* form)
@@ -360,7 +375,7 @@ void HTMLConstructionSite::setForm(HTMLFormElement* form)
m_form = form;
}
-PassRefPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
+PassRefPtrWillBeRawPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
{
return m_form.release();
}
@@ -375,7 +390,7 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* token)
{
ASSERT(m_document);
- RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
+ RefPtrWillBeRawPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
setAttributes(element.get(), token, m_parserContentPolicy);
attachLater(m_attachmentRoot, element);
m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token));
@@ -392,7 +407,7 @@ void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken*
for (unsigned i = 0; i < token->attributes().size(); ++i) {
const Attribute& tokenAttribute = token->attributes().at(i);
- if (!element->elementData() || !element->getAttributeItem(tokenAttribute.name()))
+ if (!element->elementData() || !element->findAttributeByName(tokenAttribute.name()))
element->setAttribute(tokenAttribute.name(), tokenAttribute.value());
}
}
@@ -416,8 +431,6 @@ void HTMLConstructionSite::setDefaultCompatibilityMode()
{
if (m_isParsingFragment)
return;
- if (m_document->isSrcdocDocument())
- return;
setCompatibilityMode(Document::QuirksMode);
}
@@ -536,7 +549,7 @@ void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token)
const String& publicId = StringImpl::create8BitIfPossible(token->publicIdentifier());
const String& systemId = StringImpl::create8BitIfPossible(token->systemIdentifier());
- RefPtr<DocumentType> doctype = DocumentType::create(m_document, token->name(), publicId, systemId);
+ RefPtrWillBeRawPtr<DocumentType> doctype = DocumentType::create(m_document, token->name(), publicId, systemId);
attachLater(m_attachmentRoot, doctype.release());
// DOCTYPE nodes are only processed when parsing fragments w/o contextElements, which
@@ -586,26 +599,26 @@ void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token)
void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
{
ASSERT(!shouldFosterParent());
- RefPtr<Element> body = createHTMLElement(token);
+ RefPtrWillBeRawPtr<Element> body = createHTMLElement(token);
attachLater(currentNode(), body);
m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
- if (Frame* frame = m_document->frame())
+ if (LocalFrame* frame = m_document->frame())
frame->loader().client()->dispatchWillInsertBody();
}
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
{
- RefPtr<Element> element = createHTMLElement(token);
- ASSERT(element->hasTagName(formTag));
+ RefPtrWillBeRawPtr<Element> element = createHTMLElement(token);
+ ASSERT(isHTMLFormElement(element));
m_form = static_pointer_cast<HTMLFormElement>(element.release());
m_form->setDemoted(isDemoted);
- attachLater(currentNode(), m_form);
- m_openElements.push(HTMLStackItem::create(m_form, token));
+ attachLater(currentNode(), m_form.get());
+ m_openElements.push(HTMLStackItem::create(m_form.get(), token));
}
void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
{
- RefPtr<Element> element = createHTMLElement(token);
+ RefPtrWillBeRawPtr<Element> element = createHTMLElement(token);
attachLater(currentNode(), element);
m_openElements.push(HTMLStackItem::create(element.release(), token));
}
@@ -639,7 +652,7 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
// those flags or effects thereof.
const bool parserInserted = m_parserContentPolicy != AllowScriptingContentAndDoNotMarkAlreadyStarted;
const bool alreadyStarted = m_isParsingFragment && parserInserted;
- RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
+ RefPtrWillBeRawPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
setAttributes(element.get(), token, m_parserContentPolicy);
if (scriptingContentIsAllowed(m_parserContentPolicy))
attachLater(currentNode(), element);
@@ -651,7 +664,7 @@ void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const At
ASSERT(token->type() == HTMLToken::StartTag);
notImplemented(); // parseError when xmlns or xmlns:xlink are wrong.
- RefPtr<Element> element = createElement(token, namespaceURI);
+ RefPtrWillBeRawPtr<Element> element = createElement(token, namespaceURI);
if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptLoaderIfPossible(element.get()))
attachLater(currentNode(), element, token->selfClosing());
if (!token->selfClosing())
@@ -667,7 +680,7 @@ void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
findFosterSite(dummyTask);
// FIXME: This probably doesn't need to be done both here and in insert(Task).
- if (dummyTask.parent->hasTagName(templateTag))
+ if (isHTMLTemplateElement(*dummyTask.parent))
dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->content();
// Unclear when parent != case occurs. Somehow we insert text into two separate nodes while processing the same Token.
@@ -715,22 +728,22 @@ void HTMLConstructionSite::takeAllChildren(HTMLStackItem* newParent, HTMLElement
queueTask(task);
}
-PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
+PassRefPtrWillBeRawPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
{
QualifiedName tagName(nullAtom, token->name(), namespaceURI);
- RefPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagName, true);
+ RefPtrWillBeRawPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagName, true);
setAttributes(element.get(), token, m_parserContentPolicy);
return element.release();
}
inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
{
- if (currentNode()->hasTagName(templateTag))
+ if (isHTMLTemplateElement(*currentNode()))
return toHTMLTemplateElement(currentElement())->content()->document();
return currentNode()->document();
}
-PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
+PassRefPtrWillBeRawPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
{
Document& document = ownerDocumentForCurrentNode();
// Only associate the element with the current form if we're creating the new element
@@ -739,15 +752,15 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* tok
// 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(token->name(), document, form, true);
+ RefPtrWillBeRawPtr<Element> element = HTMLElementFactory::createHTMLElement(token->name(), document, form, true);
setAttributes(element.get(), token, m_parserContentPolicy);
ASSERT(element->isHTMLElement());
return element.release();
}
-PassRefPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
+PassRefPtrWillBeRawPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
{
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element;
// NOTE: Moving from item -> token -> item copies the Attribute vector twice!
AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attributes());
if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
@@ -784,7 +797,7 @@ void HTMLConstructionSite::reconstructTheActiveFormattingElements()
ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
- RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
+ RefPtrWillBeRawPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
attachLater(currentNode(), reconstructed->node());
m_openElements.push(reconstructed);
unopenedEntry.replaceElement(reconstructed.release());
@@ -847,7 +860,7 @@ bool HTMLConstructionSite::shouldFosterParent() const
&& currentStackItem()->causesFosterParenting();
}
-void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
+void HTMLConstructionSite::fosterParent(PassRefPtrWillBeRawPtr<Node> node)
{
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
findFosterSite(task);
@@ -856,4 +869,11 @@ void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
queueTask(task);
}
+void HTMLConstructionSite::PendingText::trace(Visitor* visitor)
+{
+ visitor->trace(parent);
+ visitor->trace(nextChild);
+}
+
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
index d4d812eb109..0bd25a0fa62 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
@@ -27,6 +27,7 @@
#ifndef HTMLConstructionSite_h
#define HTMLConstructionSite_h
+#include "core/dom/Document.h"
#include "core/dom/ParserContentPolicy.h"
#include "core/html/parser/HTMLElementStack.h"
#include "core/html/parser/HTMLFormattingElementList.h"
@@ -39,6 +40,8 @@
namespace WebCore {
struct HTMLConstructionSiteTask {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
enum Operation {
Insert,
InsertText, // Handles possible merging of text nodes.
@@ -53,6 +56,13 @@ struct HTMLConstructionSiteTask {
{
}
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(parent);
+ visitor->trace(nextChild);
+ visitor->trace(child);
+ }
+
ContainerNode* oldParent()
{
// It's sort of ugly, but we store the |oldParent| in the |child| field
@@ -62,17 +72,15 @@ struct HTMLConstructionSiteTask {
}
Operation operation;
- RefPtr<ContainerNode> parent;
- RefPtr<Node> nextChild;
- RefPtr<Node> child;
+ RefPtrWillBeMember<ContainerNode> parent;
+ RefPtrWillBeMember<Node> nextChild;
+ RefPtrWillBeMember<Node> child;
bool selfClosing;
};
} // namespace WebCore
-namespace WTF {
-template<> struct VectorTraits<WebCore::HTMLConstructionSiteTask> : SimpleClassVectorTraits { };
-} // namespace WTF
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::HTMLConstructionSiteTask);
namespace WebCore {
@@ -89,12 +97,14 @@ class Document;
class Element;
class HTMLFormElement;
-class HTMLConstructionSite {
+class HTMLConstructionSite FINAL {
WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
+ DISALLOW_ALLOCATION();
public:
HTMLConstructionSite(Document*, ParserContentPolicy);
HTMLConstructionSite(DocumentFragment*, ParserContentPolicy);
~HTMLConstructionSite();
+ void trace(Visitor*);
void detach();
@@ -150,10 +160,10 @@ public:
void insertAlreadyParsedChild(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* child);
void takeAllChildren(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* oldParent);
- PassRefPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
+ PassRefPtrWillBeRawPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
bool shouldFosterParent() const;
- void fosterParent(PassRefPtr<Node>);
+ void fosterParent(PassRefPtrWillBeRawPtr<Node>);
bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
void reconstructTheActiveFormattingElements();
@@ -179,7 +189,7 @@ public:
void setForm(HTMLFormElement*);
HTMLFormElement* form() const { return m_form.get(); }
- PassRefPtr<HTMLFormElement> takeForm();
+ PassRefPtrWillBeRawPtr<HTMLFormElement> takeForm();
ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
@@ -206,17 +216,17 @@ public:
private:
// In the common case, this queue will have only one task because most
// tokens produce only one DOM mutation.
- typedef Vector<HTMLConstructionSiteTask, 1> TaskQueue;
+ typedef WillBeHeapVector<HTMLConstructionSiteTask, 1> TaskQueue;
void setCompatibilityMode(Document::CompatibilityMode);
void setCompatibilityModeFromDoctype(const String& name, const String& publicId, const String& systemId);
- void attachLater(ContainerNode* parent, PassRefPtr<Node> child, bool selfClosing = false);
+ void attachLater(ContainerNode* parent, PassRefPtrWillBeRawPtr<Node> child, bool selfClosing = false);
void findFosterSite(HTMLConstructionSiteTask&);
- PassRefPtr<Element> createHTMLElement(AtomicHTMLToken*);
- PassRefPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
+ PassRefPtrWillBeRawPtr<Element> createHTMLElement(AtomicHTMLToken*);
+ PassRefPtrWillBeRawPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
void dispatchDocumentElementAvailableIfNeeded();
@@ -224,27 +234,29 @@ private:
void executeTask(HTMLConstructionSiteTask&);
void queueTask(const HTMLConstructionSiteTask&);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
// This is the root ContainerNode to which the parser attaches all newly
// constructed nodes. It points to a DocumentFragment when parsing fragments
// and a Document in all other cases.
- ContainerNode* m_attachmentRoot;
+ RawPtrWillBeMember<ContainerNode> m_attachmentRoot;
- RefPtr<HTMLStackItem> m_head;
- RefPtr<HTMLFormElement> m_form;
+ RefPtrWillBeMember<HTMLStackItem> m_head;
+ RefPtrWillBeMember<HTMLFormElement> m_form;
mutable HTMLElementStack m_openElements;
mutable HTMLFormattingElementList m_activeFormattingElements;
TaskQueue m_taskQueue;
- struct PendingText {
+ class PendingText FINAL {
+ DISALLOW_ALLOCATION();
+ public:
PendingText()
: whitespaceMode(WhitespaceUnknown)
{
}
- void append(PassRefPtr<ContainerNode> newParent, PassRefPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
+ void append(PassRefPtrWillBeRawPtr<ContainerNode> newParent, PassRefPtrWillBeRawPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
{
ASSERT(!parent || parent == newParent);
parent = newParent;
@@ -277,8 +289,10 @@ private:
return stringBuilder.isEmpty();
}
- RefPtr<ContainerNode> parent;
- RefPtr<Node> nextChild;
+ void trace(Visitor*);
+
+ RefPtrWillBeMember<ContainerNode> parent;
+ RefPtrWillBeMember<Node> nextChild;
StringBuilder stringBuilder;
WhitespaceMode whitespaceMode;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index 2008ae5f0e1..e5a4d251b1c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -26,9 +26,11 @@
#include "config.h"
#include "core/html/parser/HTMLDocumentParser.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/css/MediaValuesCached.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Element.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDocument.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "core/html/parser/BackgroundHTMLParser.h"
@@ -37,8 +39,11 @@
#include "core/html/parser/HTMLScriptRunner.h"
#include "core/html/parser/HTMLTreeBuilder.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
+#include "core/inspector/InspectorTraceEvents.h"
+#include "core/loader/DocumentLoader.h"
+#include "platform/SharedBuffer.h"
#include "platform/TraceEvent.h"
+#include "public/platform/WebThreadedDataReceiver.h"
#include "wtf/Functional.h"
namespace WebCore {
@@ -70,17 +75,44 @@ static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
return HTMLTokenizer::DataState;
}
-HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors)
+class ParserDataReceiver : public blink::WebThreadedDataReceiver {
+public:
+ explicit ParserDataReceiver(WeakPtr<BackgroundHTMLParser> backgroundParser)
+ : m_backgroundParser(backgroundParser)
+ {
+ }
+
+ // WebThreadedDataReceiver
+ virtual void acceptData(const char* data, int dataLength) OVERRIDE FINAL
+ {
+ ASSERT(backgroundThread() && backgroundThread()->isCurrentThread());
+ if (m_backgroundParser.get())
+ m_backgroundParser.get()->appendRawBytesFromParserThread(data, dataLength);
+ }
+
+ virtual blink::WebThread* backgroundThread() OVERRIDE FINAL
+ {
+ if (HTMLParserThread::shared())
+ return &HTMLParserThread::shared()->platformThread();
+
+ return 0;
+ }
+
+private:
+ WeakPtr<BackgroundHTMLParser> m_backgroundParser;
+};
+
+HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors)
: ScriptableDocumentParser(document)
- , m_options(document)
+ , m_options(&document)
, m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken))
, m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_options))
- , m_scriptRunner(HTMLScriptRunner::create(document, this))
- , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy(), reportErrors, m_options))
+ , m_scriptRunner(HTMLScriptRunner::create(&document, this))
+ , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy(), reportErrors, m_options))
, m_parserScheduler(HTMLParserScheduler::create(this))
- , m_xssAuditorDelegate(document)
+ , m_xssAuditorDelegate(&document)
, m_weakFactory(this)
- , m_preloader(adoptPtr(new HTMLResourcePreloader(document)))
+ , m_preloader(adoptPtr(new HTMLResourcePreloader(&document)))
, m_isPinnedToMainThread(false)
, m_endWasDelayed(false)
, m_haveBackgroundParser(false)
@@ -92,7 +124,7 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors
// FIXME: Member variables should be grouped into self-initializing structs to
// minimize code duplication between these constructors.
HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
- : ScriptableDocumentParser(&fragment->document(), parserContentPolicy)
+ : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
, m_options(&fragment->document())
, m_token(adoptPtr(new HTMLToken))
, m_tokenizer(HTMLTokenizer::create(m_options))
@@ -112,6 +144,12 @@ HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
HTMLDocumentParser::~HTMLDocumentParser()
{
+#if ENABLE(OILPAN)
+ if (m_haveBackgroundParser)
+ stopBackgroundParser();
+ // In Oilpan, HTMLDocumentParser can die together with Document, and
+ // detach() is not called in this case.
+#else
ASSERT(!m_parserScheduler);
ASSERT(!m_pumpSessionNestingLevel);
ASSERT(!m_preloadScanner);
@@ -120,6 +158,15 @@ HTMLDocumentParser::~HTMLDocumentParser()
// FIXME: We should be able to ASSERT(m_speculations.isEmpty()),
// but there are cases where that's not true currently. For example,
// we we're told to stop parsing before we've consumed all the input.
+#endif
+}
+
+void HTMLDocumentParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_treeBuilder);
+ visitor->trace(m_scriptRunner);
+ ScriptableDocumentParser::trace(visitor);
+ HTMLScriptRunnerHost::trace(visitor);
}
void HTMLDocumentParser::pinToMainThread()
@@ -167,7 +214,7 @@ void HTMLDocumentParser::prepareToStopParsing()
// 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);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
// NOTE: This pump should only ever emit buffered character tokens,
// so ForceSynchronous vs. AllowYield should be meaningless.
@@ -230,7 +277,7 @@ void HTMLDocumentParser::resumeParsingAfterYield()
ASSERT(!m_isPinnedToMainThread);
// 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);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
if (m_haveBackgroundParser) {
pumpPendingSpeculations();
@@ -248,7 +295,7 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
TextPosition scriptStartPosition = TextPosition::belowRangePosition();
- RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
+ RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
// We will not have a scriptRunner when parsing a DocumentFragment.
if (m_scriptRunner)
m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
@@ -263,7 +310,7 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
if (isWaitingForScripts()) {
if (mode == AllowYield)
- m_parserScheduler->checkForYieldBeforeScript(session);
+ session.didSeeScript = true;
// If we don't run the script, we cannot allow the next token to be taken.
if (session.needsYield)
@@ -278,7 +325,7 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
}
// FIXME: It's wrong for the HTMLDocumentParser to reach back to the
- // Frame, but this approach is how the old parser handled
+ // LocalFrame, 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
@@ -308,7 +355,7 @@ void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa
// processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
ASSERT(m_speculations.isEmpty());
chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately.
@@ -316,6 +363,11 @@ void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa
pumpPendingSpeculations();
}
+void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const DocumentEncodingData& data)
+{
+ document()->setEncodingData(data);
+}
+
void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk)
{
ASSERT(chunk);
@@ -382,8 +434,10 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
ASSERT(!isParsingFragment());
ASSERT(!isWaitingForScripts());
ASSERT(!isStopped());
+#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+#endif
ASSERT(shouldUseThreading());
ASSERT(!m_tokenizer);
ASSERT(!m_token);
@@ -406,8 +460,7 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != tokens->end(); ++it) {
ASSERT(!isWaitingForScripts());
- if (!isParsingFragment()
- && document()->frame() && document()->frame()->navigationScheduler().locationChangePending()) {
+ if (document()->frame() && document()->frame()->navigationScheduler().locationChangePending()) {
// To match main-thread parser behavior (which never checks locationChangePending on the EOF path)
// we peek to see if this chunk has an EOF and process it anyway.
@@ -442,6 +495,10 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
ASSERT(!m_tokenizer);
ASSERT(!m_token);
}
+
+ // Make sure any pending text nodes are emitted before returning.
+ if (!isStopped())
+ m_treeBuilder->flush();
}
void HTMLDocumentParser::pumpPendingSpeculations()
@@ -449,8 +506,10 @@ void HTMLDocumentParser::pumpPendingSpeculations()
// FIXME: Share this constant with the parser scheduler.
const double parserTimeLimit = 0.500;
+#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+#endif
// If this assert fails, you need to call validateSpeculations to make sure
// m_tokenizer and m_token don't have state that invalidates m_speculations.
ASSERT(!m_tokenizer);
@@ -460,6 +519,9 @@ void HTMLDocumentParser::pumpPendingSpeculations()
ASSERT(!isStopped());
// FIXME: Pass in current input length.
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zeroBasedInt()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), lineNumber().zeroBasedInt());
double startTime = currentTime();
@@ -467,11 +529,8 @@ void HTMLDocumentParser::pumpPendingSpeculations()
while (!m_speculations.isEmpty()) {
processParsedChunkFromBackgroundParser(m_speculations.takeFirst());
- // The order matters! If this isStopped(), isWaitingForScripts() can hit and ASSERT since
- // m_document can be null which is used to decide the readiness.
- if (isStopped())
- break;
- if (isWaitingForScripts())
+ // Always check isStopped first as m_document may be null.
+ if (isStopped() || isWaitingForScripts())
break;
if (currentTime() - startTime > parserTimeLimit && !m_speculations.isEmpty()) {
@@ -480,7 +539,10 @@ void HTMLDocumentParser::pumpPendingSpeculations()
}
}
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "endLine", lineNumber().zeroBasedInt());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
void HTMLDocumentParser::forcePlaintextForTextDocument()
@@ -505,12 +567,22 @@ Document* HTMLDocumentParser::contextForParsingSession()
return document();
}
+static PassRefPtr<MediaValues> createMediaValues(Document* document)
+{
+ ASSERT(document);
+ RefPtr<MediaValues> mediaValues = MediaValuesCached::create(*document);
+ ASSERT(mediaValues->isSafeToSendToAnotherThread());
+ return mediaValues;
+}
+
void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
{
ASSERT(!isStopped());
ASSERT(!isScheduledForResume());
+#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+#endif
ASSERT(m_tokenizer);
ASSERT(m_token);
ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
@@ -522,6 +594,9 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
// FIXME: m_input.current().length() is only accurate if we
// end up parsing the whole buffer in this pump. We should pass how
// much we parsed as part of didWriteHTML instead of willWriteHTML.
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "beginData", InspectorParseHtmlEvent::beginData(document(), m_input.current().currentLine().zeroBasedInt()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().currentLine().zeroBasedInt());
m_xssAuditor.init(document(), &m_xssAuditorDelegate);
@@ -546,9 +621,11 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
ASSERT(token().isUninitialized());
}
+#if !ENABLE(OILPAN)
// 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);
+#endif
if (isStopped())
return;
@@ -565,12 +642,14 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
if (isWaitingForScripts()) {
ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
if (!m_preloadScanner) {
- m_preloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), document()->devicePixelRatio()));
+ m_preloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), createMediaValues(document())));
m_preloadScanner->appendToEnd(m_input.current());
}
m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "endLine", m_input.current().currentLine().zeroBasedInt());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didWriteHTML(cookie, m_input.current().currentLine().zeroBasedInt());
}
@@ -620,11 +699,11 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
if (isStopped())
return;
- TRACE_EVENT0("webkit", "HTMLDocumentParser::insert");
+ TRACE_EVENT1("webkit", "HTMLDocumentParser::insert", "source_length", source.length());
// 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);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
if (!m_tokenizer) {
ASSERT(!inPumpSession());
@@ -642,7 +721,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
// Check the document.write() output with a separate preload scanner as
// the main scanner can't deal with insertions.
if (!m_insertionPreloadScanner)
- m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), document()->devicePixelRatio()));
+ m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), createMediaValues(document())));
m_insertionPreloadScanner->appendToEnd(source);
m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseElementURL());
@@ -653,6 +732,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
void HTMLDocumentParser::startBackgroundParser()
{
+ ASSERT(!isStopped());
ASSERT(shouldUseThreading());
ASSERT(!m_haveBackgroundParser);
m_haveBackgroundParser = true;
@@ -660,16 +740,21 @@ void HTMLDocumentParser::startBackgroundParser()
RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<BackgroundHTMLParser>::createUnbound();
m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference);
+ // TODO(oysteine): Disabled due to crbug.com/398076 until a full fix can be implemented.
+ if (RuntimeEnabledFeatures::threadedParserDataReceiverEnabled())
+ document()->loader()->attachThreadedDataReceiver(adoptPtr(new ParserDataReceiver(m_backgroundParser)));
+
OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new BackgroundHTMLParser::Configuration);
config->options = m_options;
config->parser = m_weakFactory.createWeakPtr();
config->xssAuditor = adoptPtr(new XSSAuditor);
config->xssAuditor->init(document(), &m_xssAuditorDelegate);
- config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url().copy(), document()->devicePixelRatio()));
+ config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url().copy(), createMediaValues(document())));
+ config->decoder = takeDecoder();
ASSERT(config->xssAuditor->isSafeToSendToAnotherThread());
ASSERT(config->preloadScanner->isSafeToSendToAnotherThread());
- HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::create, reference.release(), config.release()));
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::start, reference.release(), config.release()));
}
void HTMLDocumentParser::stopBackgroundParser()
@@ -687,23 +772,13 @@ void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
if (isStopped())
return;
- if (shouldUseThreading()) {
- if (!m_haveBackgroundParser)
- startBackgroundParser();
-
- ASSERT(inputSource->hasOneRef());
- TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->length());
- // NOTE: Important that the String temporary is destroyed before we post the task
- // otherwise the String could call deref() on a StringImpl now owned by the background parser.
- // We would like to ASSERT(closure.arg3()->hasOneRef()) but sadly the args are private.
- Closure closure = bind(&BackgroundHTMLParser::append, m_backgroundParser, String(inputSource));
- HTMLParserThread::shared()->postTask(closure);
- return;
- }
+ // We should never reach this point if we're using a parser thread,
+ // as appendBytes() will directly ship the data to the thread.
+ ASSERT(!shouldUseThreading());
// 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);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->length());
String source(inputSource);
@@ -876,7 +951,7 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
ASSERT(!m_lastChunkBeforeScript);
// processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
pumpPendingSpeculations();
return;
}
@@ -886,20 +961,6 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
endIfDelayed();
}
-void HTMLDocumentParser::watchForLoad(Resource* resource)
-{
- ASSERT(!resource->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 Resource.
- resource->addClient(this);
-}
-
-void HTMLDocumentParser::stopWatchingForLoad(Resource* resource)
-{
- resource->removeClient(this);
-}
-
void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
{
ASSERT(m_preloadScanner);
@@ -907,11 +968,11 @@ void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
-void HTMLDocumentParser::notifyFinished(Resource* cachedResource)
+void HTMLDocumentParser::notifyScriptLoaded(Resource* 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);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
ASSERT(m_scriptRunner);
ASSERT(!isExecutingScript());
@@ -938,7 +999,7 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
// 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);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
m_scriptRunner->executeScriptsWaitingForResources();
if (!isWaitingForScripts())
resumeParsingAfterScriptExecution();
@@ -946,7 +1007,7 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
{
- RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
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>
@@ -965,4 +1026,45 @@ void HTMLDocumentParser::resumeScheduledTasks()
m_parserScheduler->resume();
}
+void HTMLDocumentParser::appendBytes(const char* data, size_t length)
+{
+ if (!length || isStopped())
+ return;
+
+ if (shouldUseThreading()) {
+ if (!m_haveBackgroundParser)
+ startBackgroundParser();
+
+ OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length));
+ memcpy(buffer->data(), data, length);
+ TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned)length);
+
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::appendRawBytesFromMainThread, m_backgroundParser, buffer.release()));
+ return;
+ }
+
+ DecodedDataDocumentParser::appendBytes(data, length);
+}
+
+void HTMLDocumentParser::flush()
+{
+ // If we've got no decoder, we never received any data.
+ if (isDetached() || needsDecoder())
+ return;
+
+ if (m_haveBackgroundParser)
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::flush, m_backgroundParser));
+ else
+ DecodedDataDocumentParser::flush();
+}
+
+void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
+{
+ ASSERT(decoder);
+ DecodedDataDocumentParser::setDecoder(decoder);
+
+ if (m_haveBackgroundParser)
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser, takeDecoder()));
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
index 40779561ad3..227cf522507 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -40,6 +40,7 @@
#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditor.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "platform/text/SegmentedString.h"
@@ -64,14 +65,16 @@ class ScriptSourceCode;
class PumpSession;
-class HTMLDocumentParser : public ScriptableDocumentParser, HTMLScriptRunnerHost, ResourceClient {
- WTF_MAKE_FAST_ALLOCATED;
+class HTMLDocumentParser : public ScriptableDocumentParser, private HTMLScriptRunnerHost {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLDocumentParser);
public:
- static PassRefPtr<HTMLDocumentParser> create(HTMLDocument* document, bool reportErrors)
+ static PassRefPtrWillBeRawPtr<HTMLDocumentParser> create(HTMLDocument& document, bool reportErrors)
{
- return adoptRef(new HTMLDocumentParser(document, reportErrors));
+ return adoptRefWillBeNoop(new HTMLDocumentParser(document, reportErrors));
}
virtual ~HTMLDocumentParser();
+ virtual void trace(Visitor*) OVERRIDE;
// Exposed for HTMLParserScheduler
void resumeParsingAfterYield();
@@ -80,11 +83,11 @@ public:
HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
- virtual TextPosition textPosition() const;
- virtual OrdinalNumber lineNumber() const;
+ virtual TextPosition textPosition() const OVERRIDE FINAL;
+ virtual OrdinalNumber lineNumber() const OVERRIDE FINAL;
- virtual void suspendScheduledTasks();
- virtual void resumeScheduledTasks();
+ virtual void suspendScheduledTasks() OVERRIDE FINAL;
+ virtual void resumeScheduledTasks() OVERRIDE FINAL;
struct ParsedChunk {
OwnPtr<CompactHTMLTokenStream> tokens;
@@ -96,15 +99,20 @@ public:
TokenPreloadScannerCheckpoint preloadScannerCheckpoint;
};
void didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
+ void didReceiveEncodingDataFromBackgroundParser(const DocumentEncodingData&);
+
+ virtual void appendBytes(const char* bytes, size_t length) OVERRIDE;
+ virtual void flush() OVERRIDE FINAL;
+ virtual void setDecoder(PassOwnPtr<TextResourceDecoder>) OVERRIDE FINAL;
UseCounter* useCounter() { return UseCounter::getFrom(contextForParsingSession()); }
protected:
- virtual void insert(const SegmentedString&) OVERRIDE;
+ virtual void insert(const SegmentedString&) OVERRIDE FINAL;
virtual void append(PassRefPtr<StringImpl>) OVERRIDE;
- virtual void finish() OVERRIDE;
+ virtual void finish() OVERRIDE FINAL;
- HTMLDocumentParser(HTMLDocument*, bool reportErrors);
+ HTMLDocumentParser(HTMLDocument&, bool reportErrors);
HTMLDocumentParser(DocumentFragment*, Element* contextElement, ParserContentPolicy);
HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
@@ -112,31 +120,27 @@ protected:
void forcePlaintextForTextDocument();
private:
- static PassRefPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
+ static PassRefPtrWillBeRawPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
{
- return adoptRef(new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
+ return adoptRefWillBeNoop(new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
}
// DocumentParser
- virtual void pinToMainThread() OVERRIDE;
- virtual void detach() OVERRIDE;
- virtual bool hasInsertionPoint() OVERRIDE;
- virtual bool processingData() const OVERRIDE;
- virtual void prepareToStopParsing() OVERRIDE;
- virtual void stopParsing() OVERRIDE;
- virtual bool isWaitingForScripts() const OVERRIDE;
- virtual bool isExecutingScript() const OVERRIDE;
- virtual void executeScriptsWaitingForResources() OVERRIDE;
+ virtual void pinToMainThread() OVERRIDE FINAL;
+ virtual void detach() OVERRIDE FINAL;
+ virtual bool hasInsertionPoint() OVERRIDE FINAL;
+ virtual bool processingData() const OVERRIDE FINAL;
+ virtual void prepareToStopParsing() OVERRIDE FINAL;
+ virtual void stopParsing() OVERRIDE FINAL;
+ virtual bool isWaitingForScripts() const OVERRIDE FINAL;
+ virtual bool isExecutingScript() const OVERRIDE FINAL;
+ virtual void executeScriptsWaitingForResources() OVERRIDE FINAL;
// HTMLScriptRunnerHost
- virtual void watchForLoad(Resource*) OVERRIDE;
- virtual void stopWatchingForLoad(Resource*) OVERRIDE;
- virtual HTMLInputStream& inputStream() { return m_input; }
- virtual bool hasPreloadScanner() const { return m_preloadScanner.get() && !shouldUseThreading(); }
- virtual void appendCurrentInputStreamToPreloadScannerAndScan() OVERRIDE;
-
- // ResourceClient
- virtual void notifyFinished(Resource*);
+ virtual void notifyScriptLoaded(Resource*) OVERRIDE FINAL;
+ virtual HTMLInputStream& inputStream() OVERRIDE FINAL { return m_input; }
+ virtual bool hasPreloadScanner() const OVERRIDE FINAL { return m_preloadScanner.get() && !shouldUseThreading(); }
+ virtual void appendCurrentInputStreamToPreloadScannerAndScan() OVERRIDE FINAL;
void startBackgroundParser();
void stopBackgroundParser();
@@ -179,8 +183,8 @@ private:
OwnPtr<HTMLToken> m_token;
OwnPtr<HTMLTokenizer> m_tokenizer;
- OwnPtr<HTMLScriptRunner> m_scriptRunner;
- OwnPtr<HTMLTreeBuilder> m_treeBuilder;
+ OwnPtrWillBeMember<HTMLScriptRunner> m_scriptRunner;
+ OwnPtrWillBeMember<HTMLTreeBuilder> m_treeBuilder;
OwnPtr<HTMLPreloadScanner> m_preloadScanner;
OwnPtr<HTMLPreloadScanner> m_insertionPreloadScanner;
OwnPtr<HTMLParserScheduler> m_parserScheduler;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
index 9adfdf1612c..5ea0549dbae 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
@@ -27,13 +27,11 @@
#include "config.h"
#include "core/html/parser/HTMLElementStack.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Element.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLOptGroupElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -45,7 +43,7 @@ namespace {
inline bool isRootNode(HTMLStackItem* item)
{
return item->isDocumentFragmentNode()
- || isHTMLHtmlElement(item->node());
+ || item->hasTagName(htmlTag);
}
inline bool isScopeMarker(HTMLStackItem* item)
@@ -54,7 +52,7 @@ inline bool isScopeMarker(HTMLStackItem* item)
|| item->hasTagName(captionTag)
|| item->hasTagName(marqueeTag)
|| item->hasTagName(objectTag)
- || isHTMLTableElement(item->node())
+ || item->hasTagName(tableTag)
|| item->hasTagName(tdTag)
|| item->hasTagName(thTag)
|| item->hasTagName(MathMLNames::miTag)
@@ -79,7 +77,7 @@ inline bool isListItemScopeMarker(HTMLStackItem* item)
inline bool isTableScopeMarker(HTMLStackItem* item)
{
- return isHTMLTableElement(item->node())
+ return item->hasTagName(tableTag)
|| item->hasTagName(templateTag)
|| isRootNode(item);
}
@@ -115,24 +113,26 @@ inline bool isButtonScopeMarker(HTMLStackItem* item)
inline bool isSelectScopeMarker(HTMLStackItem* item)
{
- return !isHTMLOptGroupElement(item->node())
+ return !item->hasTagName(optgroupTag)
&& !item->hasTagName(optionTag);
}
}
-HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<HTMLStackItem> item, PassOwnPtr<ElementRecord> next)
+HTMLElementStack::ElementRecord::ElementRecord(PassRefPtrWillBeRawPtr<HTMLStackItem> item, PassOwnPtrWillBeRawPtr<ElementRecord> next)
: m_item(item)
, m_next(next)
{
ASSERT(m_item);
}
+#if !ENABLE(OILPAN)
HTMLElementStack::ElementRecord::~ElementRecord()
{
}
+#endif
-void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::ElementRecord::replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(item);
ASSERT(!m_item || m_item->isElementNode());
@@ -149,10 +149,18 @@ bool HTMLElementStack::ElementRecord::isAbove(ElementRecord* other) const
return false;
}
+void HTMLElementStack::ElementRecord::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_item);
+ visitor->trace(m_next);
+#endif
+}
+
HTMLElementStack::HTMLElementStack()
- : m_rootNode(0)
- , m_headElement(0)
- , m_bodyElement(0)
+ : m_rootNode(nullptr)
+ , m_headElement(nullptr)
+ , m_bodyElement(nullptr)
, m_stackDepth(0)
{
}
@@ -181,25 +189,27 @@ bool HTMLElementStack::secondElementIsHTMLBodyElement() const
void HTMLElementStack::popHTMLHeadElement()
{
ASSERT(top() == m_headElement);
- m_headElement = 0;
+ m_headElement = nullptr;
popCommon();
}
void HTMLElementStack::popHTMLBodyElement()
{
ASSERT(top() == m_bodyElement);
- m_bodyElement = 0;
+ m_bodyElement = nullptr;
popCommon();
}
void HTMLElementStack::popAll()
{
- m_rootNode = 0;
- m_headElement = 0;
- m_bodyElement = 0;
+ m_rootNode = nullptr;
+ m_headElement = nullptr;
+ m_bodyElement = nullptr;
m_stackDepth = 0;
while (m_top) {
- topNode()->finishParsingChildren();
+ Node& node = *topNode();
+ if (node.isElementNode())
+ toElement(node).finishParsingChildren();
m_top = m_top->releaseNext();
}
}
@@ -301,19 +311,19 @@ void HTMLElementStack::popUntilForeignContentScopeMarker()
pop();
}
-void HTMLElementStack::pushRootNode(PassRefPtr<HTMLStackItem> rootItem)
+void HTMLElementStack::pushRootNode(PassRefPtrWillBeRawPtr<HTMLStackItem> rootItem)
{
ASSERT(rootItem->isDocumentFragmentNode());
pushRootNodeCommon(rootItem);
}
-void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushHTMLHtmlElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
- ASSERT(isHTMLHtmlElement(item->node()));
+ ASSERT(item->hasTagName(htmlTag));
pushRootNodeCommon(item);
}
-void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
+void HTMLElementStack::pushRootNodeCommon(PassRefPtrWillBeRawPtr<HTMLStackItem> rootItem)
{
ASSERT(!m_top);
ASSERT(!m_rootNode);
@@ -321,7 +331,7 @@ void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
pushCommon(rootItem);
}
-void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushHTMLHeadElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(item->hasTagName(HTMLNames::headTag));
ASSERT(!m_headElement);
@@ -329,7 +339,7 @@ void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
pushCommon(item);
}
-void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushHTMLBodyElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(item->hasTagName(HTMLNames::bodyTag));
ASSERT(!m_bodyElement);
@@ -337,23 +347,23 @@ void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
pushCommon(item);
}
-void HTMLElementStack::push(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::push(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
- ASSERT(!isHTMLHtmlElement(item->node()));
- ASSERT(!item->hasTagName(HTMLNames::headTag));
- ASSERT(!item->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!item->hasTagName(htmlTag));
+ ASSERT(!item->hasTagName(headTag));
+ ASSERT(!item->hasTagName(bodyTag));
ASSERT(m_rootNode);
pushCommon(item);
}
-void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord* recordBelow)
+void HTMLElementStack::insertAbove(PassRefPtrWillBeRawPtr<HTMLStackItem> item, ElementRecord* recordBelow)
{
ASSERT(item);
ASSERT(recordBelow);
ASSERT(m_top);
- ASSERT(!isHTMLHtmlElement(item->node()));
- ASSERT(!item->hasTagName(HTMLNames::headTag));
- ASSERT(!item->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!item->hasTagName(htmlTag));
+ ASSERT(!item->hasTagName(headTag));
+ ASSERT(!item->hasTagName(bodyTag));
ASSERT(m_rootNode);
if (recordBelow == m_top) {
push(item);
@@ -365,7 +375,7 @@ void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord
continue;
m_stackDepth++;
- recordAbove->setNext(adoptPtr(new ElementRecord(item, recordAbove->releaseNext())));
+ recordAbove->setNext(adoptPtrWillBeNoop(new ElementRecord(item, recordAbove->releaseNext())));
recordAbove->next()->element()->beginParsingChildren();
return;
}
@@ -395,13 +405,13 @@ void HTMLElementStack::removeHTMLHeadElement(Element* element)
popHTMLHeadElement();
return;
}
- m_headElement = 0;
+ m_headElement = nullptr;
removeNonTopCommon(element);
}
void HTMLElementStack::remove(Element* element)
{
- ASSERT(!element->hasTagName(HTMLNames::headTag));
+ ASSERT(!isHTMLHeadElement(element));
if (m_top->element() == element) {
pop();
return;
@@ -556,19 +566,19 @@ ContainerNode* HTMLElementStack::rootNode() const
return m_rootNode;
}
-void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushCommon(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(m_rootNode);
m_stackDepth++;
- m_top = adoptPtr(new ElementRecord(item, m_top.release()));
+ m_top = adoptPtrWillBeNoop(new ElementRecord(item, m_top.release()));
}
void HTMLElementStack::popCommon()
{
- ASSERT(!isHTMLHtmlElement(topStackItem()->node()));
- ASSERT(!topStackItem()->hasTagName(HTMLNames::headTag) || !m_headElement);
- ASSERT(!topStackItem()->hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
+ ASSERT(!topStackItem()->hasTagName(htmlTag));
+ ASSERT(!topStackItem()->hasTagName(headTag) || !m_headElement);
+ ASSERT(!topStackItem()->hasTagName(bodyTag) || !m_bodyElement);
top()->finishParsingChildren();
m_top = m_top->releaseNext();
@@ -578,7 +588,7 @@ void HTMLElementStack::popCommon()
void HTMLElementStack::removeNonTopCommon(Element* element)
{
ASSERT(!isHTMLHtmlElement(element));
- ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!isHTMLBodyElement(element));
ASSERT(top() != element);
for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
if (pos->next()->element() == element) {
@@ -606,6 +616,14 @@ HTMLElementStack::ElementRecord* HTMLElementStack::furthestBlockForFormattingEle
return 0;
}
+void HTMLElementStack::trace(Visitor* visitor)
+{
+ visitor->trace(m_top);
+ visitor->trace(m_rootNode);
+ visitor->trace(m_headElement);
+ visitor->trace(m_bodyElement);
+}
+
#ifndef NDEBUG
void HTMLElementStack::show()
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h
index e63bbbc3e72..2afead5f97e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h
@@ -44,35 +44,40 @@ class QualifiedName;
// NOTE: The HTML5 spec uses a backwards (grows downward) stack. We're using
// more standard (grows upwards) stack terminology here.
class HTMLElementStack {
- WTF_MAKE_NONCOPYABLE(HTMLElementStack); WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(HTMLElementStack);
+ DISALLOW_ALLOCATION();
public:
HTMLElementStack();
~HTMLElementStack();
- class ElementRecord {
- WTF_MAKE_NONCOPYABLE(ElementRecord); WTF_MAKE_FAST_ALLOCATED;
+ class ElementRecord FINAL : public NoBaseWillBeGarbageCollected<ElementRecord> {
+ WTF_MAKE_NONCOPYABLE(ElementRecord); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
+#if !ENABLE(OILPAN)
~ElementRecord(); // Public for ~PassOwnPtr()
+#endif
Element* element() const { return m_item->element(); }
ContainerNode* node() const { return m_item->node(); }
const AtomicString& namespaceURI() const { return m_item->namespaceURI(); }
- PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
- void replaceElement(PassRefPtr<HTMLStackItem>);
+ PassRefPtrWillBeRawPtr<HTMLStackItem> stackItem() const { return m_item; }
+ void replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
bool isAbove(ElementRecord*) const;
ElementRecord* next() const { return m_next.get(); }
+
+ void trace(Visitor*);
private:
friend class HTMLElementStack;
- ElementRecord(PassRefPtr<HTMLStackItem>, PassOwnPtr<ElementRecord>);
+ ElementRecord(PassRefPtrWillBeRawPtr<HTMLStackItem>, PassOwnPtrWillBeRawPtr<ElementRecord>);
- PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
- void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
+ PassOwnPtrWillBeRawPtr<ElementRecord> releaseNext() { return m_next.release(); }
+ void setNext(PassOwnPtrWillBeRawPtr<ElementRecord> next) { m_next = next; }
- RefPtr<HTMLStackItem> m_item;
- OwnPtr<ElementRecord> m_next;
+ RefPtrWillBeMember<HTMLStackItem> m_item;
+ OwnPtrWillBeMember<ElementRecord> m_next;
};
unsigned stackDepth() const { return m_stackDepth; }
@@ -103,13 +108,13 @@ public:
ElementRecord* furthestBlockForFormattingElement(Element*) const;
ElementRecord* topmost(const AtomicString& tagName) const;
- void insertAbove(PassRefPtr<HTMLStackItem>, ElementRecord*);
+ void insertAbove(PassRefPtrWillBeRawPtr<HTMLStackItem>, ElementRecord*);
- void push(PassRefPtr<HTMLStackItem>);
- void pushRootNode(PassRefPtr<HTMLStackItem>);
- void pushHTMLHtmlElement(PassRefPtr<HTMLStackItem>);
- void pushHTMLHeadElement(PassRefPtr<HTMLStackItem>);
- void pushHTMLBodyElement(PassRefPtr<HTMLStackItem>);
+ void push(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushRootNode(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushHTMLHtmlElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushHTMLHeadElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushHTMLBodyElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
void pop();
void popUntil(const AtomicString& tagName);
@@ -159,26 +164,28 @@ public:
ContainerNode* rootNode() const;
+ void trace(Visitor*);
+
#ifndef NDEBUG
void show();
#endif
private:
- void pushCommon(PassRefPtr<HTMLStackItem>);
- void pushRootNodeCommon(PassRefPtr<HTMLStackItem>);
+ void pushCommon(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushRootNodeCommon(PassRefPtrWillBeRawPtr<HTMLStackItem>);
void popCommon();
void removeNonTopCommon(Element*);
- OwnPtr<ElementRecord> m_top;
+ OwnPtrWillBeMember<ElementRecord> m_top;
// We remember the root node, <head> and <body> as they are pushed. Their
// ElementRecords keep them alive. The root node 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.
- ContainerNode* m_rootNode;
- Element* m_headElement;
- Element* m_bodyElement;
+ RawPtrWillBeMember<ContainerNode> m_rootNode;
+ RawPtrWillBeMember<Element> m_headElement;
+ RawPtrWillBeMember<Element> m_bodyElement;
unsigned m_stackDepth;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp
index 97cebee4383..9866313277d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp
@@ -115,7 +115,7 @@ static bool consumeNamedEntity(SegmentedString& source, DecodedHTMLEntity& decod
}
notEnoughCharacters = source.isEmpty();
if (notEnoughCharacters) {
- // We can't an entity because there might be a longer entity
+ // We can't decide on an entity because there might be a longer entity
// that we could match if we had more data.
unconsumeCharacters(source, consumedCharacters);
return false;
@@ -130,11 +130,12 @@ static bool consumeNamedEntity(SegmentedString& source, DecodedHTMLEntity& decod
// actual entity.
unconsumeCharacters(source, consumedCharacters);
consumedCharacters.clear();
- const int length = entitySearch.mostRecentMatch()->length;
- const UChar* reference = entitySearch.mostRecentMatch()->entity;
+ const HTMLEntityTableEntry* mostRecent = entitySearch.mostRecentMatch();
+ const int length = mostRecent->length;
+ const LChar* reference = HTMLEntityTable::entityString(*mostRecent);
for (int i = 0; i < length; ++i) {
cc = source.currentChar();
- ASSERT_UNUSED(reference, cc == *reference++);
+ ASSERT_UNUSED(reference, cc == static_cast<UChar>(*reference++));
consumedCharacters.append(cc);
source.advanceAndASSERT(cc);
ASSERT(!source.isEmpty());
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp
index c4ef2b0c92f..fe847e48038 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp
@@ -47,7 +47,8 @@ HTMLEntitySearch::CompareResult HTMLEntitySearch::compare(const HTMLEntityTableE
{
if (entry->length < m_currentLength + 1)
return Before;
- UChar entryNextCharacter = entry->entity[m_currentLength];
+ const LChar* entityString = HTMLEntityTable::entityString(*entry);
+ UChar entryNextCharacter = entityString[m_currentLength];
if (entryNextCharacter == nextCharacter)
return Prefix;
return entryNextCharacter < nextCharacter ? Before : After;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h
index f0d775efee7..1e465049b57 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h
@@ -30,13 +30,14 @@
namespace WebCore {
+// Member order to optimize packing. There will be thousands of these objects.
struct HTMLEntityTableEntry {
- UChar lastCharacter() const { return entity[length - 1]; }
+ LChar lastCharacter() const;
- const UChar* entity;
- int length;
UChar32 firstValue;
- UChar32 secondValue;
+ UChar secondValue; // UChar since double char sequences only use BMP chars.
+ short entityOffset;
+ short length;
};
class HTMLEntityTable {
@@ -46,6 +47,8 @@ public:
static const HTMLEntityTableEntry* firstEntryStartingWith(UChar);
static const HTMLEntityTableEntry* lastEntryStartingWith(UChar);
+
+ static const LChar* entityString(const HTMLEntityTableEntry&);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp
index 34215d75e26..26418debc1c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp
@@ -79,7 +79,7 @@ HTMLFormattingElementList::Bookmark HTMLFormattingElementList::bookmarkFor(Eleme
return Bookmark(&at(index));
}
-void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark& bookmark)
+void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtrWillBeRawPtr<HTMLStackItem> newItem, const Bookmark& bookmark)
{
ASSERT(contains(oldElement));
ASSERT(!contains(newItem->element()));
@@ -94,7 +94,7 @@ void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStack
remove(oldElement);
}
-void HTMLFormattingElementList::append(PassRefPtr<HTMLStackItem> item)
+void HTMLFormattingElementList::append(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ensureNoahsArkCondition(item.get());
m_entries.append(item);
@@ -123,7 +123,7 @@ void HTMLFormattingElementList::clearToLastMarker()
}
}
-void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackItem* newItem, Vector<HTMLStackItem*>& remainingCandidates)
+void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackItem* newItem, WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> >& remainingCandidates)
{
ASSERT(remainingCandidates.isEmpty());
@@ -132,7 +132,7 @@ void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackIte
// Use a vector with inline capacity to avoid a malloc in the common case
// of a quickly ensuring the condition.
- Vector<HTMLStackItem*, 10> candidates;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem>, 10> candidates;
size_t newItemAttributeCount = newItem->attributes().size();
@@ -155,19 +155,19 @@ void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackIte
if (candidates.size() < kNoahsArkCapacity)
return; // There's room for the new element in the ark. There's no need to copy out the remainingCandidates.
- remainingCandidates.append(candidates);
+ remainingCandidates.appendVector(candidates);
}
void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
{
- Vector<HTMLStackItem*> candidates;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> > candidates;
tryToEnsureNoahsArkConditionQuickly(newItem, candidates);
if (candidates.isEmpty())
return;
// We pre-allocate and re-use this second vector to save one malloc per
// attribute that we verify.
- Vector<HTMLStackItem*> remainingCandidates;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> > remainingCandidates;
remainingCandidates.reserveInitialCapacity(candidates.size());
const Vector<Attribute>& attributes = newItem->attributes();
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h
index 745dba1c771..cb7c0ce34fb 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h
@@ -38,6 +38,7 @@ class Element;
// This may end up merged into HTMLElementStack.
class HTMLFormattingElementList {
WTF_MAKE_NONCOPYABLE(HTMLFormattingElementList);
+ DISALLOW_ALLOCATION();
public:
HTMLFormattingElementList();
~HTMLFormattingElementList();
@@ -46,22 +47,23 @@ public:
// between the HTMLFormattingElementList and HTMLElementStack and needs
// access to Entry::isMarker() and Entry::replaceElement() to do so.
class Entry {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
// Inline because they're hot and Vector<T> uses them.
- explicit Entry(PassRefPtr<HTMLStackItem> item)
+ explicit Entry(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
: m_item(item)
{
}
enum MarkerEntryType { MarkerEntry };
explicit Entry(MarkerEntryType)
- : m_item(0)
+ : m_item(nullptr)
{
}
~Entry() {}
bool isMarker() const { return !m_item; }
- PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
+ PassRefPtrWillBeRawPtr<HTMLStackItem> stackItem() const { return m_item; }
Element* element() const
{
// The fact that !m_item == isMarker() is an implementation detail
@@ -69,14 +71,16 @@ public:
ASSERT(m_item);
return m_item->element();
}
- void replaceElement(PassRefPtr<HTMLStackItem> item) { m_item = item; }
+ void replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item) { m_item = item; }
// Needed for use with Vector. These are super-hot and must be inline.
bool operator==(Element* element) const { return !m_item ? !element : m_item->element() == element; }
bool operator!=(Element* element) const { return !m_item ? !!element : m_item->element() != element; }
+ void trace(Visitor* visitor) { visitor->trace(m_item); }
+
private:
- RefPtr<HTMLStackItem> m_item;
+ RefPtrWillBeMember<HTMLStackItem> m_item;
};
class Bookmark {
@@ -108,11 +112,11 @@ public:
Entry* find(Element*);
bool contains(Element*);
- void append(PassRefPtr<HTMLStackItem>);
+ void append(PassRefPtrWillBeRawPtr<HTMLStackItem>);
void remove(Element*);
Bookmark bookmarkFor(Element*);
- void swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark&);
+ void swapTo(Element* oldElement, PassRefPtrWillBeRawPtr<HTMLStackItem> newItem, const Bookmark&);
void appendMarker();
// clearToLastMarker also clears the marker (per the HTML5 spec).
@@ -121,6 +125,8 @@ public:
const Entry& at(size_t i) const { return m_entries[i]; }
Entry& at(size_t i) { return m_entries[i]; }
+ void trace(Visitor* visitor) { visitor->trace(m_entries); }
+
#ifndef NDEBUG
void show();
#endif
@@ -130,12 +136,14 @@ private:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#list-of-active-formatting-elements
// These functions enforce the "Noah's Ark" condition, which removes redundant mis-nested elements.
- void tryToEnsureNoahsArkConditionQuickly(HTMLStackItem*, Vector<HTMLStackItem*>& remainingCandiates);
+ void tryToEnsureNoahsArkConditionQuickly(HTMLStackItem*, WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> >& remainingCandiates);
void ensureNoahsArkCondition(HTMLStackItem*);
- Vector<Entry> m_entries;
+ WillBeHeapVector<Entry> m_entries;
};
-}
+} // namespace WebCore
+
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::HTMLFormattingElementList::Entry);
#endif // HTMLFormattingElementList_h
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
index 038c8a1e5fb..5fa6d32e73d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/parser/HTMLMetaCharsetParser.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLTokenizer.h"
@@ -51,61 +51,12 @@ 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 == kNotFound)
- 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()
{
const HTMLToken::AttributeList& tokenAttributes = m_token.attributes();
- AttributeList attributes;
+ HTMLAttributeList attributes;
for (HTMLToken::AttributeList::const_iterator iter = tokenAttributes.begin(); iter != tokenAttributes.end(); ++iter) {
- String attributeName = StringImpl::create8BitIfPossible(iter->name);
+ String attributeName = attemptStaticStringCreation(iter->name, Likely8Bit);
String attributeValue = StringImpl::create8BitIfPossible(iter->value);
attributes.append(std::make_pair(attributeName, attributeValue));
}
@@ -114,37 +65,6 @@ bool HTMLMetaCharsetParser::processMeta()
return m_encoding.isValid();
}
-WTF::TextEncoding HTMLMetaCharsetParser::encodingFromMetaAttributes(const AttributeList& attributes)
-{
- bool gotPragma = false;
- Mode mode = None;
- String charset;
-
- for (AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
- const AtomicString& attributeName = iter->first;
- const String& attributeValue = iter->second;
-
- if (attributeName == http_equivAttr) {
- if (equalIgnoringCase(attributeValue, "content-type"))
- 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))
- return WTF::TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset));
-
- return WTF::TextEncoding();
-}
-
static const int bytesToCheckUnconditionally = 1024; // That many input bytes will be checked for meta charset even if <head> section is over.
bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
@@ -177,20 +97,20 @@ bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t 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());
+ String tagName = attemptStaticStringCreation(m_token.name(), Likely8Bit);
if (!end) {
m_tokenizer->updateStateFor(tagName);
- if (tagName == metaTag && processMeta()) {
+ if (threadSafeMatch(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)) {
+ if (!threadSafeMatch(tagName, scriptTag) && !threadSafeMatch(tagName, noscriptTag)
+ && !threadSafeMatch(tagName, styleTag) && !threadSafeMatch(tagName, linkTag)
+ && !threadSafeMatch(tagName, metaTag) && !threadSafeMatch(tagName, objectTag)
+ && !threadSafeMatch(tagName, titleTag) && !threadSafeMatch(tagName, baseTag)
+ && (end || !threadSafeMatch(tagName, htmlTag)) && (end || !threadSafeMatch(tagName, headTag))) {
m_inHeadSection = false;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
index 3393fca40d2..65d9517a2e0 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
@@ -48,22 +48,10 @@ public:
const WTF::TextEncoding& encoding() { return m_encoding; }
- typedef Vector<pair<String, String> > AttributeList;
- // The returned encoding might not be valid.
- static WTF::TextEncoding encodingFromMetaAttributes(const AttributeList&
-);
-
private:
HTMLMetaCharsetParser();
bool processMeta();
- static String extractCharset(const String&);
-
- enum Mode {
- None,
- Charset,
- Pragma,
- };
OwnPtr<HTMLTokenizer> m_tokenizer;
OwnPtr<TextCodec> m_assumedCodec;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
index f538c54cc5b..c0557a82281 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
@@ -25,14 +25,18 @@
#include "config.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/HTMLNames.h"
#include <limits>
#include "wtf/MathExtras.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/StringHash.h"
+#include "wtf/text/TextEncoding.h"
namespace WebCore {
+using namespace HTMLNames;
+
template <typename CharType>
static String stripLeadingAndTrailingHTMLSpaces(String string, const CharType* characters, unsigned length)
{
@@ -91,8 +95,7 @@ String serializeForNumberType(double number)
Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbackValue)
{
- // See HTML5 2.5.4.3 `Real numbers.' and parseToDoubleForNumberType
-
+ // http://www.whatwg.org/specs/web-apps/current-work/#floating-point-numbers and parseToDoubleForNumberType
// String::toDouble() accepts leading + and whitespace characters, which are not valid here.
const UChar firstCharacter = string[0];
if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
@@ -102,11 +105,9 @@ Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbac
if (!value.isFinite())
return fallbackValue;
- // Numbers are considered finite IEEE 754 single-precision floating point values.
- // See HTML5 2.5.4.3 `Real numbers.'
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const Decimal floatMax = Decimal::fromDouble(std::numeric_limits<float>::max());
- if (value < -floatMax || value > floatMax)
+ // Numbers are considered finite IEEE 754 Double-precision floating point values.
+ const Decimal doubleMax = Decimal::fromDouble(std::numeric_limits<double>::max());
+ if (value < -doubleMax || value > doubleMax)
return fallbackValue;
// We return +0 for -0 case.
@@ -115,8 +116,7 @@ Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbac
double parseToDoubleForNumberType(const String& string, double fallbackValue)
{
- // See HTML5 2.5.4.3 `Real numbers.'
-
+ // http://www.whatwg.org/specs/web-apps/current-work/#floating-point-numbers
// String::toDouble() accepts leading + and whitespace characters, which are not valid here.
UChar firstCharacter = string[0];
if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
@@ -131,9 +131,8 @@ double parseToDoubleForNumberType(const String& string, double fallbackValue)
if (!std::isfinite(value))
return fallbackValue;
- // Numbers are considered finite IEEE 754 single-precision floating point values.
- // See HTML5 2.5.4.3 `Real numbers.'
- if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max())
+ // Numbers are considered finite IEEE 754 Double-precision floating point values.
+ if (-std::numeric_limits<double>::max() > value || value > std::numeric_limits<double>::max())
return fallbackValue;
// The following expression converts -0 to +0.
@@ -265,6 +264,92 @@ bool parseHTMLNonNegativeInteger(const String& input, unsigned& value)
return parseHTMLNonNegativeIntegerInternal(start, start + length, value);
}
+static const char charsetString[] = "charset";
+static const size_t charsetLength = sizeof("charset") - 1;
+
+String extractCharset(const String& value)
+{
+ size_t pos = 0;
+ unsigned length = value.length();
+
+ while (pos < length) {
+ pos = value.find(charsetString, pos, false);
+ if (pos == kNotFound)
+ 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 "";
+}
+
+enum Mode {
+ None,
+ Charset,
+ Pragma,
+};
+
+WTF::TextEncoding encodingFromMetaAttributes(const HTMLAttributeList& attributes)
+{
+ bool gotPragma = false;
+ Mode mode = None;
+ String charset;
+
+ for (HTMLAttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
+ const String& attributeName = iter->first;
+ const String& attributeValue = AtomicString(iter->second);
+
+ if (threadSafeMatch(attributeName, http_equivAttr)) {
+ if (equalIgnoringCase(attributeValue, "content-type"))
+ gotPragma = true;
+ } else if (charset.isEmpty()) {
+ if (threadSafeMatch(attributeName, charsetAttr)) {
+ charset = attributeValue;
+ mode = Charset;
+ } else if (threadSafeMatch(attributeName, contentAttr)) {
+ charset = extractCharset(attributeValue);
+ if (charset.length())
+ mode = Pragma;
+ }
+ }
+ }
+
+ if (mode == Charset || (mode == Pragma && gotPragma))
+ return WTF::TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset));
+
+ return WTF::TextEncoding();
+}
+
static bool threadSafeEqual(const StringImpl* a, const StringImpl* b)
{
if (a == b)
@@ -284,7 +369,8 @@ bool threadSafeMatch(const String& localName, const QualifiedName& qName)
return threadSafeEqual(localName.impl(), qName.localName().impl());
}
-StringImpl* findStringIfStatic(const UChar* characters, unsigned length)
+template<typename CharType>
+inline StringImpl* findStringIfStatic(const CharType* characters, unsigned length)
{
// We don't need to try hashing if we know the string is too long.
if (length > StringImpl::highestStaticStringLength())
@@ -306,4 +392,27 @@ StringImpl* findStringIfStatic(const UChar* characters, unsigned length)
return it->value;
}
+String attemptStaticStringCreation(const LChar* characters, size_t size)
+{
+ String string(findStringIfStatic(characters, size));
+ if (string.impl())
+ return string;
+ return String(characters, size);
+}
+
+String attemptStaticStringCreation(const UChar* characters, size_t size, CharacterWidth width)
+{
+ String string(findStringIfStatic(characters, size));
+ if (string.impl())
+ return string;
+ if (width == Likely8Bit)
+ string = StringImpl::create8BitIfPossible(characters, size);
+ else if (width == Force8Bit)
+ string = String::make8BitFrom16BitSource(characters, size);
+ else
+ string = String(characters, size);
+
+ return string;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
index 16fd3eebe3c..d5ab2899638 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
@@ -30,12 +30,11 @@
#include "wtf/Forward.h"
#include "wtf/text/WTFString.h"
-namespace WebCore {
+namespace WTF {
+class TextEncoding;
+}
-// Space characters as defined by the HTML specification.
-bool isHTMLSpace(UChar);
-bool isHTMLLineBreak(UChar);
-bool isNotHTMLSpace(UChar);
+namespace WebCore {
// Strip leading and trailing whitespace as defined by the HTML specification.
String stripLeadingAndTrailingHTMLSpaces(const String&);
@@ -59,10 +58,13 @@ double parseToDoubleForNumberType(const String&, double fallbackValue = std::num
bool parseHTMLInteger(const String&, int&);
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers
-bool parseHTMLNonNegativeInteger(const String&, unsigned int&);
+bool parseHTMLNonNegativeInteger(const String&, unsigned&);
-// Inline implementations of some of the functions declared above.
+typedef Vector<pair<String, String> > HTMLAttributeList;
+// The returned encoding might not be valid.
+WTF::TextEncoding encodingFromMetaAttributes(const HTMLAttributeList&);
+// Space characters as defined by the HTML specification.
template<typename CharType>
inline bool isHTMLSpace(CharType character)
{
@@ -80,9 +82,15 @@ inline bool isHTMLSpace(CharType character)
}
template<typename CharType>
+inline bool isComma(CharType character)
+{
+ return character == ',';
+}
+
+template<typename CharType>
inline bool isHTMLSpaceOrComma(CharType character)
{
- return isHTMLSpace<CharType>(character) || character == ',';
+ return isComma(character) || isHTMLSpace(character);
}
inline bool isHTMLLineBreak(UChar character)
@@ -99,29 +107,29 @@ inline bool isNotHTMLSpace(CharType character)
bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
bool threadSafeMatch(const String&, const QualifiedName&);
-StringImpl* findStringIfStatic(const UChar* characters, unsigned length);
-
enum CharacterWidth {
Likely8Bit,
Force8Bit,
Force16Bit
};
+String attemptStaticStringCreation(const LChar*, size_t);
+
+String attemptStaticStringCreation(const UChar*, size_t, CharacterWidth);
+
template<size_t inlineCapacity>
-static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
+inline static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
{
- String string(findStringIfStatic(vector.data(), vector.size()));
- if (string.impl())
- return string;
- if (width == Likely8Bit)
- string = StringImpl::create8BitIfPossible(vector);
- else if (width == Force8Bit)
- string = String::make8BitFrom16BitSource(vector);
- else
- string = String(vector);
-
- return string;
+ return attemptStaticStringCreation(vector.data(), vector.size(), width);
}
+inline static String attemptStaticStringCreation(const String str)
+{
+ if (!str.is8Bit())
+ return attemptStaticStringCreation(str.characters16(), str.length(), Force16Bit);
+ return attemptStaticStringCreation(str.characters8(), str.length());
+}
+
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
index 98ceb68461d..b08cf92994e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
@@ -28,23 +28,28 @@
#include "bindings/v8/ScriptController.h"
#include "core/dom/Document.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/loader/FrameLoader.h"
namespace WebCore {
HTMLParserOptions::HTMLParserOptions(Document* document)
{
- Frame* frame = document ? document->frame() : 0;
+ LocalFrame* frame = document ? document->frame() : 0;
scriptEnabled = frame && frame->script().canExecuteScripts(NotAboutToExecuteScript);
pluginsEnabled = frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin);
- Settings* settings = document ? document->settings() : 0;
- // We force the main-thread parser for about:blank, javascript: and data: urls for compatibility
- // with historical synchronous loading/parsing behavior of those schemes.
- useThreading = settings && settings->threadedHTMLParser() && !document->url().isBlankURL()
- && (settings->useThreadedHTMLParserForDataURLs() || !document->url().protocolIsData());
+ // We force the main-thread parser for two cases:
+ // - about:blank and javascript (which uses about:blank) for compatibility
+ // with historical synchronous loading/parsing behavior.
+ // - instances where the Document has no Frame (this happens sometimes for
+ // HTML imports, and possibly other cases).
+ // FIXME: We want to use the threaded parser for XHRs (where there is no
+ // frame) so the second case should go away eventually.
+ // FIXME: Gecko does not load javascript: urls synchronously, why do we?
+ // See LayoutTests/loader/iframe-sync-loads.html
+ useThreading = document && document->frame() && !document->url().isAboutBlankURL();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
index c74628479df..61cb172ccae 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
@@ -88,34 +88,14 @@ HTMLParserScheduler::~HTMLParserScheduler()
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.
- // FIXME: We should fix this by reducing the max-parse-time instead of
- // artificially forcing the parser to yield agressively before first layout.
- if (m_parser->document()->shouldParserYieldAgressivelyBeforeScriptExecution()) {
- m_continueNextChunkTimer.startOneShot(0);
- return;
- }
m_parser->resumeParsingAfterYield();
}
-void HTMLParserScheduler::checkForYieldBeforeScript(PumpSession& session)
-{
- // If we've never painted before and a layout is pending, yield prior to running
- // scripts to give the page a chance to paint earlier.
- Document* document = m_parser->document();
- bool needsFirstPaint = document->view() && !document->view()->hasEverPainted();
- if (needsFirstPaint && document->shouldParserYieldAgressivelyBeforeScriptExecution())
- session.needsYield = true;
- session.didSeeScript = true;
-}
-
void HTMLParserScheduler::scheduleForResume()
{
- m_continueNextChunkTimer.startOneShot(0);
+ m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
}
-
void HTMLParserScheduler::suspend()
{
ASSERT(!m_isSuspendedWithActiveTimer);
@@ -131,7 +111,7 @@ void HTMLParserScheduler::resume()
if (!m_isSuspendedWithActiveTimer)
return;
m_isSuspendedWithActiveTimer = false;
- m_continueNextChunkTimer.startOneShot(0);
+ m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
index e8bfe493085..4e3364edfbf 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
@@ -38,15 +38,17 @@ class Document;
class HTMLDocumentParser;
class ActiveParserSession {
+ STACK_ALLOCATED();
public:
explicit ActiveParserSession(Document*);
~ActiveParserSession();
private:
- RefPtr<Document> m_document;
+ RefPtrWillBeMember<Document> m_document;
};
class PumpSession : public NestingLevelIncrementer, public ActiveParserSession {
+ STACK_ALLOCATED();
public:
PumpSession(unsigned& nestingLevel, Document*);
~PumpSession();
@@ -84,7 +86,6 @@ public:
}
++session.processedTokens;
}
- void checkForYieldBeforeScript(PumpSession&);
void scheduleForResume();
bool isScheduledForResume() const { return m_isSuspendedWithActiveTimer || m_continueNextChunkTimer.isActive(); }
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
index 5a0e30c3e67..5b5c6939714 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
@@ -32,13 +32,15 @@
#include "core/html/parser/HTMLParserThread.h"
#include "platform/Task.h"
+#include "platform/TaskSynchronizer.h"
#include "public/platform/Platform.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
+static HTMLParserThread* s_sharedThread = 0;
+
HTMLParserThread::HTMLParserThread()
- : m_thread(adoptPtr(blink::Platform::current()->createThread("HTMLParserThread")))
{
}
@@ -46,17 +48,66 @@ HTMLParserThread::~HTMLParserThread()
{
}
+void HTMLParserThread::init()
+{
+ ASSERT(!s_sharedThread);
+ s_sharedThread = new HTMLParserThread;
+}
+
+void HTMLParserThread::setupHTMLParserThread()
+{
+ m_pendingGCRunner = adoptPtr(new PendingGCRunner);
+ m_messageLoopInterruptor = adoptPtr(new MessageLoopInterruptor(&platformThread()));
+ platformThread().addTaskObserver(m_pendingGCRunner.get());
+ ThreadState::attach();
+ ThreadState::current()->addInterruptor(m_messageLoopInterruptor.get());
+}
+
+void HTMLParserThread::shutdown()
+{
+ ASSERT(s_sharedThread);
+ // currentThread will always be non-null in production, but can be null in Chromium unit tests.
+ if (blink::Platform::current()->currentThread() && s_sharedThread->isRunning()) {
+ TaskSynchronizer taskSynchronizer;
+ s_sharedThread->postTask(WTF::bind(&HTMLParserThread::cleanupHTMLParserThread, s_sharedThread, &taskSynchronizer));
+ taskSynchronizer.waitForTaskCompletion();
+ }
+ delete s_sharedThread;
+ s_sharedThread = 0;
+}
+
+void HTMLParserThread::cleanupHTMLParserThread(TaskSynchronizer* taskSynchronizer)
+{
+ ThreadState::current()->removeInterruptor(m_messageLoopInterruptor.get());
+ ThreadState::detach();
+ platformThread().removeTaskObserver(m_pendingGCRunner.get());
+ m_pendingGCRunner = nullptr;
+ m_messageLoopInterruptor = nullptr;
+ taskSynchronizer->taskCompleted();
+}
+
HTMLParserThread* HTMLParserThread::shared()
{
- static HTMLParserThread* thread;
- if (!thread)
- thread = new HTMLParserThread;
- return thread;
+ return s_sharedThread;
+}
+
+blink::WebThread& HTMLParserThread::platformThread()
+{
+ if (!isRunning()) {
+ m_thread = adoptPtr(blink::Platform::current()->createThread("HTMLParserThread"));
+ postTask(WTF::bind(&HTMLParserThread::setupHTMLParserThread, this));
+ }
+ return *m_thread;
+}
+
+bool HTMLParserThread::isRunning()
+{
+ return !!m_thread;
}
void HTMLParserThread::postTask(const Closure& closure)
{
- m_thread->postTask(new Task(closure));
+ platformThread().postTask(new Task(closure));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
index e0b85f9399c..42630f39cfa 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
@@ -31,22 +31,37 @@
#ifndef HTMLParserThread_h
#define HTMLParserThread_h
+#include "platform/heap/glue/MessageLoopInterruptor.h"
+#include "platform/heap/glue/PendingGCRunner.h"
+#include "public/platform/WebThread.h"
#include "wtf/Functional.h"
#include "wtf/OwnPtr.h"
-#include "public/platform/WebThread.h"
namespace WebCore {
+class TaskSynchronizer;
+
class HTMLParserThread {
public:
+ static void init();
+ static void shutdown();
+
+ // It is an error to call shared() before init() or after shutdown();
static HTMLParserThread* shared();
+
void postTask(const Closure&);
+ blink::WebThread& platformThread();
+ bool isRunning();
private:
HTMLParserThread();
~HTMLParserThread();
+ void setupHTMLParserThread();
+ void cleanupHTMLParserThread(TaskSynchronizer*);
OwnPtr<blink::WebThread> m_thread;
+ OwnPtr<PendingGCRunner> m_pendingGCRunner;
+ OwnPtr<MessageLoopInterruptor> m_messageLoopInterruptor;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp
new file mode 100644
index 00000000000..8b742b86dc1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/parser/HTMLParserThread.h"
+
+#include <gtest/gtest.h>
+
+namespace {
+
+using namespace WebCore;
+
+TEST(HTMLParserThread, Init)
+{
+ // The harness has already run init() for us, so tear down the parser first.
+ ASSERT_TRUE(HTMLParserThread::shared());
+ HTMLParserThread::shutdown();
+
+ // Make sure starting the parser thread brings it back to life.
+ ASSERT_FALSE(HTMLParserThread::shared());
+ HTMLParserThread::init();
+ ASSERT_TRUE(HTMLParserThread::shared());
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index 0d1e0645ad7..6bea3f676a1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -28,13 +28,17 @@
#include "config.h"
#include "core/html/parser/HTMLPreloadScanner.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
+#include "core/css/MediaList.h"
+#include "core/css/MediaQueryEvaluator.h"
+#include "core/css/MediaValues.h"
+#include "core/css/parser/SizesAttributeParser.h"
#include "core/html/LinkRelAttribute.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/html/parser/HTMLTokenizer.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "wtf/MainThread.h"
@@ -90,19 +94,33 @@ static String initiatorFor(const StringImpl* tagImpl)
return emptyString();
}
+static bool mediaAttributeMatches(const MediaValues& mediaValues, const String& attributeValue)
+{
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createOffMainThread(attributeValue);
+ MediaQueryEvaluator mediaQueryEvaluator("screen", mediaValues);
+ return mediaQueryEvaluator.eval(mediaQueries.get());
+}
+
class TokenPreloadScanner::StartTagScanner {
public:
- StartTagScanner(const StringImpl* tagImpl, float deviceScaleFactor)
+ StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValues)
: m_tagImpl(tagImpl)
, m_linkIsStyleSheet(false)
+ , m_matchedMediaAttribute(true)
, m_inputIsImage(false)
- , m_deviceScaleFactor(deviceScaleFactor)
- , m_encounteredImgSrc(false)
+ , m_sourceSize(0)
+ , m_sourceSizeSet(false)
, m_isCORSEnabled(false)
, m_allowCredentials(DoNotAllowStoredCredentials)
+ , m_mediaValues(mediaValues)
{
- if (!match(m_tagImpl, imgTag)
- && !match(m_tagImpl, inputTag)
+ if (match(m_tagImpl, imgTag)
+ || match(m_tagImpl, sourceTag)) {
+ if (RuntimeEnabledFeatures::pictureSizesEnabled())
+ m_sourceSize = SizesAttributeParser::findEffectiveSize(String(), m_mediaValues);
+ return;
+ }
+ if ( !match(m_tagImpl, inputTag)
&& !match(m_tagImpl, linkTag)
&& !match(m_tagImpl, scriptTag))
m_tagImpl = 0;
@@ -133,57 +151,122 @@ public:
processAttribute(iter->name, iter->value);
}
+ void handlePictureSourceURL(String& sourceURL)
+ {
+ if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && sourceURL.isEmpty())
+ sourceURL = m_srcsetImageCandidate.toString();
+ else if (match(m_tagImpl, imgTag) && !sourceURL.isEmpty())
+ setUrlToLoad(sourceURL, AllowURLReplacement);
+ }
+
PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL, const SegmentedString& source)
{
- if (!shouldPreload())
+ if (!shouldPreload() || !m_matchedMediaAttribute)
return nullptr;
TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii());
TextPosition position = TextPosition(source.currentLine(), source.currentColumn());
- OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute);
+ OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, resourceType());
if (isCORSEnabled())
- request->setCrossOriginEnabled(allowCredentials());
+ request->setCrossOriginEnabled(allowStoredCredentials());
request->setCharset(charset());
return request.release();
}
private:
template<typename NameType>
+ void processScriptAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set crossorigin multiple times.
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, crossoriginAttr))
+ setCrossOriginAllowed(attributeValue);
+ }
+
+ template<typename NameType>
+ void processImgAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ if (match(attributeName, srcAttr) && m_imgSrcUrl.isNull()) {
+ m_imgSrcUrl = attributeValue;
+ setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue, m_srcsetImageCandidate), AllowURLReplacement);
+ } else if (match(attributeName, crossoriginAttr)) {
+ setCrossOriginAllowed(attributeValue);
+ } else if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetAttributeValue = attributeValue;
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue);
+ setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement);
+ } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && match(attributeName, sizesAttr) && !m_sourceSizeSet) {
+ m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues);
+ m_sourceSizeSet = true;
+ if (!m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
+ setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement);
+ }
+ }
+ }
+
+ template<typename NameType>
+ void processLinkAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set rel/media/crossorigin multiple times.
+ if (match(attributeName, hrefAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, relAttr))
+ m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
+ else if (match(attributeName, mediaAttr))
+ m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue);
+ else if (match(attributeName, crossoriginAttr))
+ setCrossOriginAllowed(attributeValue);
+ }
+
+ template<typename NameType>
+ void processInputAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set type multiple times.
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, typeAttr))
+ m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image);
+ }
+
+ template<typename NameType>
+ void processSourceAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ if (!RuntimeEnabledFeatures::pictureEnabled())
+ return;
+ if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetAttributeValue = attributeValue;
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue);
+ } else if (match(attributeName, sizesAttr) && !m_sourceSizeSet) {
+ m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues);
+ m_sourceSizeSet = true;
+ if (!m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
+ }
+ } else if (match(attributeName, mediaAttr)) {
+ // FIXME - Don't match media multiple times.
+ m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue);
+ }
+
+ }
+
+ template<typename NameType>
void processAttribute(const NameType& attributeName, const String& attributeValue)
{
if (match(attributeName, charsetAttr))
m_charset = attributeValue;
- if (match(m_tagImpl, scriptTag)) {
- if (match(attributeName, srcAttr))
- setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, crossoriginAttr))
- setCrossOriginAllowed(attributeValue);
- } else if (match(m_tagImpl, imgTag)) {
- if (match(attributeName, srcAttr) && !m_encounteredImgSrc) {
- m_encounteredImgSrc = true;
- setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor, attributeValue, m_srcsetImageCandidate), AllowURLReplacement);
- } else if (match(attributeName, crossoriginAttr)) {
- setCrossOriginAllowed(attributeValue);
- } else if (RuntimeEnabledFeatures::srcsetEnabled()
- && match(attributeName, srcsetAttr)
- && m_srcsetImageCandidate.isEmpty()) {
- m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_deviceScaleFactor, attributeValue);
- setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcsetImageCandidate), AllowURLReplacement);
- }
- } else if (match(m_tagImpl, linkTag)) {
- if (match(attributeName, hrefAttr))
- setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, relAttr))
- m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
- else if (match(attributeName, mediaAttr))
- m_mediaAttribute = attributeValue;
- } else if (match(m_tagImpl, inputTag)) {
- if (match(attributeName, srcAttr))
- setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, typeAttr))
- m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image);
- }
+ if (match(m_tagImpl, scriptTag))
+ processScriptAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, imgTag))
+ processImgAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, linkTag))
+ processLinkAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, inputTag))
+ processInputAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, sourceTag))
+ processSourceAttribute(attributeName, attributeValue);
}
static bool relAttributeIsStyleSheet(const String& attributeValue)
@@ -240,7 +323,7 @@ private:
return m_isCORSEnabled;
}
- StoredCredentials allowCredentials() const
+ StoredCredentials allowStoredCredentials() const
{
return m_allowCredentials;
}
@@ -259,19 +342,23 @@ private:
ImageCandidate m_srcsetImageCandidate;
String m_charset;
bool m_linkIsStyleSheet;
- String m_mediaAttribute;
+ bool m_matchedMediaAttribute;
bool m_inputIsImage;
- float m_deviceScaleFactor;
- bool m_encounteredImgSrc;
+ String m_imgSrcUrl;
+ String m_srcsetAttributeValue;
+ unsigned m_sourceSize;
+ bool m_sourceSizeSet;
bool m_isCORSEnabled;
StoredCredentials m_allowCredentials;
+ RefPtr<MediaValues> m_mediaValues;
};
-TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, float deviceScaleFactor)
+TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<MediaValues> mediaValues)
: m_documentURL(documentURL)
, m_inStyle(false)
- , m_deviceScaleFactor(deviceScaleFactor)
+ , m_inPicture(false)
, m_templateCount(0)
+ , m_mediaValues(mediaValues)
{
}
@@ -328,7 +415,10 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString&
if (m_inStyle)
m_cssScanner.reset();
m_inStyle = false;
+ return;
}
+ if (match(tagImpl, pictureTag))
+ m_inPicture = false;
return;
}
case HTMLToken::StartTag: {
@@ -350,9 +440,16 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString&
updatePredictedBaseURL(token);
return;
}
+ if (RuntimeEnabledFeatures::pictureEnabled() && (match(tagImpl, pictureTag))) {
+ m_inPicture = true;
+ m_pictureSourceURL = String();
+ return;
+ }
- StartTagScanner scanner(tagImpl, m_deviceScaleFactor);
+ StartTagScanner scanner(tagImpl, m_mediaValues);
scanner.processAttributes(token.attributes());
+ if (m_inPicture)
+ scanner.handlePictureSourceURL(m_pictureSourceURL);
OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL, source);
if (request)
requests.append(request.release());
@@ -372,8 +469,8 @@ void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute->value)).copy();
}
-HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const KURL& documentURL, float deviceScaleFactor)
- : m_scanner(documentURL, deviceScaleFactor)
+HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const KURL& documentURL, PassRefPtr<MediaValues> mediaValues)
+ : m_scanner(documentURL, mediaValues)
, m_tokenizer(HTMLTokenizer::create(options))
{
}
@@ -391,6 +488,8 @@ void HTMLPreloadScanner::scan(HTMLResourcePreloader* preloader, const KURL& star
{
ASSERT(isMainThread()); // HTMLTokenizer::updateStateFor only works on the main thread.
+ TRACE_EVENT1("webkit", "HTMLPreloadScanner::scan", "source_length", m_source.length());
+
// When we start scanning, our best prediction of the baseElementURL is the real one!
if (!startingBaseElementURL.isEmpty())
m_scanner.setPredictedBaseElementURL(startingBaseElementURL);
@@ -399,7 +498,7 @@ void HTMLPreloadScanner::scan(HTMLResourcePreloader* preloader, const KURL& star
while (m_tokenizer->nextToken(m_source, m_token)) {
if (m_token.type() == HTMLToken::StartTag)
- m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+ m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name(), Likely8Bit));
m_scanner.scan(m_token, m_source, requests);
m_token.clear();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
index 956d30b3d28..96046e1259d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
@@ -40,11 +40,12 @@ typedef size_t TokenPreloadScannerCheckpoint;
class HTMLParserOptions;
class HTMLTokenizer;
class SegmentedString;
+class MediaValues;
class TokenPreloadScanner {
WTF_MAKE_NONCOPYABLE(TokenPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
- TokenPreloadScanner(const KURL& documentURL, float deviceScaleFactor);
+ TokenPreloadScanner(const KURL& documentURL, PassRefPtr<MediaValues>);
~TokenPreloadScanner();
void scan(const HTMLToken&, const SegmentedString&, PreloadRequestStream& requests);
@@ -89,8 +90,10 @@ private:
const KURL m_documentURL;
KURL m_predictedBaseElementURL;
bool m_inStyle;
- float m_deviceScaleFactor;
+ bool m_inPicture;
+ String m_pictureSourceURL;
size_t m_templateCount;
+ RefPtr<MediaValues> m_mediaValues;
Vector<Checkpoint> m_checkpoints;
};
@@ -98,7 +101,7 @@ private:
class HTMLPreloadScanner {
WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
- HTMLPreloadScanner(const HTMLParserOptions&, const KURL& documentURL, float deviceScaleFactor);
+ HTMLPreloadScanner(const HTMLParserOptions&, const KURL& documentURL, PassRefPtr<MediaValues>);
~HTMLPreloadScanner();
void appendToEnd(const SegmentedString&);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
index 08e70a6a278..76857627141 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
@@ -29,9 +29,7 @@
#include "core/dom/Document.h"
#include "core/fetch/FetchInitiatorInfo.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLImport.h"
-#include "core/css/MediaList.h"
-#include "core/css/MediaQueryEvaluator.h"
+#include "core/html/imports/HTMLImport.h"
#include "core/rendering/RenderObject.h"
#include "public/platform/Platform.h"
@@ -42,20 +40,19 @@ bool PreloadRequest::isSafeToSendToAnotherThread() const
return m_initiatorName.isSafeToSendToAnotherThread()
&& m_charset.isSafeToSendToAnotherThread()
&& m_resourceURL.isSafeToSendToAnotherThread()
- && m_mediaAttribute.isSafeToSendToAnotherThread()
&& m_baseURL.isSafeToSendToAnotherThread();
}
KURL PreloadRequest::completeURL(Document* document)
{
- return document->completeURL(m_resourceURL, m_baseURL.isEmpty() ? document->url() : m_baseURL);
+ return document->completeURLWithOverride(m_resourceURL, m_baseURL.isEmpty() ? document->url() : m_baseURL);
}
FetchRequest PreloadRequest::resourceRequest(Document* document)
{
ASSERT(isMainThread());
FetchInitiatorInfo initiatorInfo;
- initiatorInfo.name = m_initiatorName;
+ initiatorInfo.name = AtomicString(m_initiatorName);
initiatorInfo.position = m_initiatorPosition;
FetchRequest request(ResourceRequest(completeURL(document)), initiatorInfo);
@@ -73,28 +70,11 @@ void HTMLResourcePreloader::takeAndPreload(PreloadRequestStream& r)
preload(it->release());
}
-static bool mediaAttributeMatches(Frame* frame, RenderStyle* renderStyle, const String& attributeValue)
-{
- RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(attributeValue);
- MediaQueryEvaluator mediaQueryEvaluator("screen", frame, renderStyle);
- return mediaQueryEvaluator.eval(mediaQueries.get());
-}
-
void HTMLResourcePreloader::preload(PassOwnPtr<PreloadRequest> preload)
{
- Document* executingDocument = m_document->import() ? m_document->import()->master() : m_document;
- Document* loadingDocument = m_document;
-
- ASSERT(executingDocument->frame());
- ASSERT(executingDocument->renderer());
- ASSERT(executingDocument->renderer()->style());
- if (!preload->media().isEmpty() && !mediaAttributeMatches(executingDocument->frame(), executingDocument->renderer()->style(), preload->media()))
- return;
-
FetchRequest request = preload->resourceRequest(m_document);
blink::Platform::current()->histogramCustomCounts("WebCore.PreloadDelayMs", static_cast<int>(1000 * (monotonicallyIncreasingTime() - preload->discoveryTime())), 0, 2000, 20);
- loadingDocument->fetcher()->preload(preload->resourceType(), request, preload->charset());
+ m_document->fetcher()->preload(preload->resourceType(), request, preload->charset());
}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
index 48686b6ca73..ee6868c143c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
@@ -35,14 +35,9 @@ namespace WebCore {
class PreloadRequest {
public:
- static PassOwnPtr<PreloadRequest> create(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType, const String& mediaAttribute)
- {
- return adoptPtr(new PreloadRequest(initiatorName, initiatorPosition, resourceURL, baseURL, resourceType, mediaAttribute));
- }
-
static PassOwnPtr<PreloadRequest> create(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType)
{
- return adoptPtr(new PreloadRequest(initiatorName, initiatorPosition, resourceURL, baseURL, resourceType, ""));
+ return adoptPtr(new PreloadRequest(initiatorName, initiatorPosition, resourceURL, baseURL, resourceType));
}
bool isSafeToSendToAnotherThread() const;
@@ -50,7 +45,6 @@ public:
FetchRequest resourceRequest(Document*);
const String& charset() const { return m_charset; }
- const String& media() const { return m_mediaAttribute; }
double discoveryTime() const { return m_discoveryTime; }
void setCharset(const String& charset) { m_charset = charset.isolatedCopy(); }
void setCrossOriginEnabled(StoredCredentials allowCredentials)
@@ -62,13 +56,12 @@ public:
Resource::Type resourceType() const { return m_resourceType; }
private:
- PreloadRequest(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType, const String& mediaAttribute)
+ PreloadRequest(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType)
: m_initiatorName(initiatorName)
, m_initiatorPosition(initiatorPosition)
, m_resourceURL(resourceURL.isolatedCopy())
, m_baseURL(baseURL.copy())
, m_resourceType(resourceType)
- , m_mediaAttribute(mediaAttribute.isolatedCopy())
, m_isCORSEnabled(false)
, m_allowCredentials(DoNotAllowStoredCredentials)
, m_discoveryTime(monotonicallyIncreasingTime())
@@ -83,7 +76,6 @@ private:
KURL m_baseURL;
String m_charset;
Resource::Type m_resourceType;
- String m_mediaAttribute;
bool m_isCORSEnabled;
StoredCredentials m_allowCredentials;
double m_discoveryTime;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
index 1cb6555c243..70c4c25f3b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
@@ -33,10 +33,10 @@
#include "core/dom/Microtask.h"
#include "core/dom/ScriptLoader.h"
#include "core/fetch/ScriptResource.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/parser/HTMLInputStream.h"
#include "core/html/parser/HTMLScriptRunnerHost.h"
#include "core/html/parser/NestingLevelIncrementer.h"
-#include "core/frame/Frame.h"
#include "platform/NotImplemented.h"
namespace WebCore {
@@ -54,7 +54,23 @@ HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* hos
HTMLScriptRunner::~HTMLScriptRunner()
{
- // FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction?
+#if ENABLE(OILPAN)
+ // If the document is destructed without having explicitly
+ // detached the parser (and this script runner object), perform
+ // detach steps now. This will happen if the Document, the parser
+ // and this script runner object are swept out in the same GC.
+ detach();
+#else
+ // Verify that detach() has been called.
+ ASSERT(!m_document);
+#endif
+}
+
+void HTMLScriptRunner::detach()
+{
+ if (!m_document)
+ return;
+
if (m_parserBlockingScript.resource() && m_parserBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parserBlockingScript);
@@ -63,23 +79,25 @@ HTMLScriptRunner::~HTMLScriptRunner()
if (pendingScript.resource() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
}
-}
-
-void HTMLScriptRunner::detach()
-{
- m_document = 0;
+ m_document = nullptr;
}
static KURL documentURLForScriptExecution(Document* document)
{
- if (!document || !document->frame())
+ if (!document)
+ return KURL();
+
+ if (!document->frame()) {
+ if (document->importsController())
+ return document->url();
return KURL();
+ }
// Use the URL of the currently active document for this frame.
return document->frame()->document()->url();
}
-inline PassRefPtr<Event> createScriptLoadEvent()
+inline PassRefPtrWillBeRawPtr<Event> createScriptLoadEvent()
{
return Event::create(EventTypeNames::load);
}
@@ -97,7 +115,7 @@ ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript&
bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
{
- m_hasScriptsWaitingForResources = !m_document->haveStylesheetsAndImportsLoaded();
+ m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady();
if (m_hasScriptsWaitingForResources)
return false;
if (script.resource() && !script.resource()->isLoaded())
@@ -109,14 +127,14 @@ void HTMLScriptRunner::executeParsingBlockingScript()
{
ASSERT(m_document);
ASSERT(!isExecutingScript());
- ASSERT(m_document->haveStylesheetsAndImportsLoaded());
+ ASSERT(m_document->isScriptExecutionReady());
ASSERT(isPendingScriptReady(m_parserBlockingScript));
InsertionPointRecord insertionPointRecord(m_host->inputStream());
- executePendingScriptAndDispatchEvent(m_parserBlockingScript);
+ executePendingScriptAndDispatchEvent(m_parserBlockingScript, PendingScriptBlockingParser);
}
-void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript)
+void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript, PendingScriptType pendingScriptType)
{
bool errorOccurred = false;
ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
@@ -125,11 +143,18 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
if (pendingScript.resource() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
- if (!isExecutingScript())
+ if (!isExecutingScript()) {
Microtask::performCheckpoint();
+ if (pendingScriptType == PendingScriptBlockingParser) {
+ m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady();
+ // The parser cannot be unblocked as a microtask requested another resource
+ if (m_hasScriptsWaitingForResources)
+ return;
+ }
+ }
// Clear the pending script before possible rentrancy from executeScript()
- RefPtr<Element> element = pendingScript.releaseElementAndClear();
+ RefPtrWillBeRawPtr<Element> element = pendingScript.releaseElementAndClear();
if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element.get())) {
NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_document);
@@ -137,8 +162,8 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
scriptLoader->dispatchErrorEvent();
else {
ASSERT(isExecutingScript());
- if (scriptLoader->executePotentiallyCrossOriginScript(sourceCode))
- element->dispatchEvent(createScriptLoadEvent());
+ scriptLoader->executeScript(sourceCode);
+ element->dispatchEvent(createScriptLoadEvent());
}
}
ASSERT(!isExecutingScript());
@@ -147,20 +172,30 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
void HTMLScriptRunner::watchForLoad(PendingScript& pendingScript)
{
ASSERT(!pendingScript.watchingForLoad());
- m_host->watchForLoad(pendingScript.resource());
+ ASSERT(!pendingScript.resource()->isLoaded());
+ // addClient() will call notifyFinished() if the load is complete.
+ // Callers do not expect to be re-entered from this call, so they
+ // should not become a client of an already-loaded Resource.
+ pendingScript.resource()->addClient(this);
pendingScript.setWatchingForLoad(true);
}
void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
{
ASSERT(pendingScript.watchingForLoad());
- m_host->stopWatchingForLoad(pendingScript.resource());
+ pendingScript.resource()->removeClient(this);
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.
-void HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, const TextPosition& scriptStartPosition)
+void HTMLScriptRunner::notifyFinished(Resource* cachedResource)
+{
+ m_host->notifyScriptLoaded(cachedResource);
+}
+
+// Implements the steps for 'An end tag whose tag name is "script"'
+// http://whatwg.org/html#scriptEndTag
+// Script handling lives outside the tree builder to keep each class simple.
+void HTMLScriptRunner::execute(PassRefPtrWillBeRawPtr<Element> scriptElement, const TextPosition& scriptStartPosition)
{
ASSERT(scriptElement);
// FIXME: If scripting is disabled, always just return.
@@ -207,7 +242,7 @@ void HTMLScriptRunner::executeScriptsWaitingForResources()
// to prevent parser or script re-entry during </style> parsing.
ASSERT(hasScriptsWaitingForResources());
ASSERT(!isExecutingScript());
- ASSERT(m_document->haveStylesheetsAndImportsLoaded());
+ ASSERT(m_document->isScriptExecutionReady());
executeParsingBlockingScripts();
}
@@ -222,7 +257,7 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing()
return false;
}
PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst();
- executePendingScriptAndDispatchEvent(first);
+ executePendingScriptAndDispatchEvent(first, PendingScriptDeferred);
// FIXME: What is this m_document check for?
if (!m_document)
return false;
@@ -268,8 +303,8 @@ bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Elemen
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
+// Implements the initial steps for 'An end tag whose tag name is "script"'
+// http://whatwg.org/html#scriptEndTag
void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStartPosition)
{
ASSERT(m_document);
@@ -285,10 +320,8 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar
if (!scriptLoader)
return;
- // FIXME: This may be too agressive as we always deliver mutations at
- // every script element, even if it's not ready to execute yet. There's
- // unfortuantely no obvious way to tell if prepareScript is going to
- // execute the script from out here.
+ ASSERT(scriptLoader->isParserInserted());
+
if (!isExecutingScript())
Microtask::performCheckpoint();
@@ -316,4 +349,12 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar
}
}
+void HTMLScriptRunner::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_host);
+ visitor->trace(m_parserBlockingScript);
+ visitor->trace(m_scriptsToExecuteAfterParsing);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
index 82d8bc2568a..46f2979bca1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
@@ -27,6 +27,8 @@
#define HTMLScriptRunner_h
#include "core/dom/PendingScript.h"
+#include "core/fetch/ResourceClient.h"
+#include "platform/heap/Handle.h"
#include "wtf/Deque.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/TextPosition.h"
@@ -37,23 +39,23 @@ class Resource;
class ScriptResource;
class Document;
class Element;
-class Frame;
+class LocalFrame;
class HTMLScriptRunnerHost;
class ScriptSourceCode;
-class HTMLScriptRunner {
- WTF_MAKE_NONCOPYABLE(HTMLScriptRunner); WTF_MAKE_FAST_ALLOCATED;
+class HTMLScriptRunner FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLScriptRunner>, private ResourceClient {
+ WTF_MAKE_NONCOPYABLE(HTMLScriptRunner); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<HTMLScriptRunner> create(Document* document, HTMLScriptRunnerHost* host)
+ static PassOwnPtrWillBeRawPtr<HTMLScriptRunner> create(Document* document, HTMLScriptRunnerHost* host)
{
- return adoptPtr(new HTMLScriptRunner(document, host));
+ return adoptPtrWillBeNoop(new HTMLScriptRunner(document, host));
}
~HTMLScriptRunner();
void detach();
// Processes the passed in script and any pending scripts if possible.
- void execute(PassRefPtr<Element> scriptToProcess, const TextPosition& scriptStartPosition);
+ void execute(PassRefPtrWillBeRawPtr<Element> scriptToProcess, const TextPosition& scriptStartPosition);
void executeScriptsWaitingForLoad(Resource*);
bool hasScriptsWaitingForResources() const { return m_hasScriptsWaitingForResources; }
@@ -63,13 +65,23 @@ public:
bool hasParserBlockingScript() const;
bool isExecutingScript() const { return !!m_scriptNestingLevel; }
+ // ResourceClient
+ virtual void notifyFinished(Resource*) OVERRIDE;
+
+ void trace(Visitor*);
+
private:
HTMLScriptRunner(Document*, HTMLScriptRunnerHost*);
- Frame* frame() const;
+ LocalFrame* frame() const;
+
+ enum PendingScriptType {
+ PendingScriptBlockingParser,
+ PendingScriptDeferred
+ };
void executeParsingBlockingScript();
- void executePendingScriptAndDispatchEvent(PendingScript&);
+ void executePendingScriptAndDispatchEvent(PendingScript&, PendingScriptType);
void executeParsingBlockingScripts();
void requestParsingBlockingScript(Element*);
@@ -84,8 +96,8 @@ private:
bool isPendingScriptReady(const PendingScript&);
ScriptSourceCode sourceFromPendingScript(const PendingScript&, bool& errorOccurred) const;
- Document* m_document;
- HTMLScriptRunnerHost* m_host;
+ RawPtrWillBeMember<Document> m_document;
+ RawPtrWillBeMember<HTMLScriptRunnerHost> m_host;
PendingScript m_parserBlockingScript;
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;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h
index e5323a2c3ae..ec3a8b68925 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h
@@ -30,20 +30,16 @@
namespace WebCore {
-class Resource;
-class Element;
class HTMLInputStream;
-class ScriptSourceCode;
+class Resource;
+class Visitor;
-class HTMLScriptRunnerHost {
+class HTMLScriptRunnerHost : public WillBeGarbageCollectedMixin {
public:
virtual ~HTMLScriptRunnerHost() { }
+ virtual void trace(Visitor*) { }
- // Implementors should call cachedResource->addClient() here or soon after.
- virtual void watchForLoad(Resource*) = 0;
- // Implementors must call cachedResource->removeClient() immediately.
- virtual void stopWatchingForLoad(Resource*) = 0;
-
+ virtual void notifyScriptLoaded(Resource*) = 0;
virtual HTMLInputStream& inputStream() = 0;
virtual bool hasPreloadScanner() const = 0;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
index 7002dffab3b..f1af160e354 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,50 +34,176 @@
#include "core/html/parser/HTMLParserIdioms.h"
#include "platform/ParsingUtilities.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-static bool compareByScaleFactor(const ImageCandidate& first, const ImageCandidate& second)
+static bool compareByDensity(const ImageCandidate& first, const ImageCandidate& second)
{
- return first.scaleFactor() < second.scaleFactor();
+ return first.density() < second.density();
}
+enum DescriptorTokenizerState {
+ Start,
+ InParenthesis,
+ AfterToken,
+};
+
+struct DescriptorToken {
+ unsigned start;
+ unsigned length;
+
+ DescriptorToken(unsigned start, unsigned length)
+ : start(start)
+ , length(length)
+ {
+ }
+
+ unsigned lastIndex()
+ {
+ return start + length - 1;
+ }
+
+ template<typename CharType>
+ int toInt(const CharType* attribute, bool& isValid)
+ {
+ return charactersToInt(attribute + start, length - 1, &isValid);
+ }
+
+ template<typename CharType>
+ float toFloat(const CharType* attribute, bool& isValid)
+ {
+ return charactersToFloat(attribute + start, length - 1, &isValid);
+ }
+};
+
template<typename CharType>
-inline bool isComma(CharType character)
+static void appendDescriptorAndReset(const CharType* attributeStart, const CharType*& descriptorStart, const CharType* position, Vector<DescriptorToken>& descriptors)
{
- return character == ',';
+ if (position > descriptorStart)
+ descriptors.append(DescriptorToken(descriptorStart - attributeStart, position - descriptorStart));
+ descriptorStart = 0;
}
+// The following is called appendCharacter to match the spec's terminology.
template<typename CharType>
-static bool parseDescriptors(const CharType* descriptorsStart, const CharType* descriptorsEnd, float& imgScaleFactor)
+static void appendCharacter(const CharType* descriptorStart, const CharType* position)
{
- const CharType* position = descriptorsStart;
- bool isValid = true;
- bool isScaleFactorFound = false;
- while (position < descriptorsEnd) {
- // 13.1. Let descriptor list be the result of splitting unparsed descriptors on spaces.
- skipWhile<CharType, isHTMLSpace<CharType> >(position, descriptorsEnd);
- const CharType* currentDescriptorStart = position;
- skipWhile<CharType, isNotHTMLSpace<CharType> >(position, descriptorsEnd);
- const CharType* currentDescriptorEnd = position;
+ // Since we don't copy the tokens, this just set the point where the descriptor tokens start.
+ if (!descriptorStart)
+ descriptorStart = position;
+}
+template<typename CharType>
+static bool isEOF(const CharType* position, const CharType* end)
+{
+ return position >= end;
+}
+
+template<typename CharType>
+static void tokenizeDescriptors(const CharType* attributeStart,
+ const CharType*& position,
+ const CharType* attributeEnd,
+ Vector<DescriptorToken>& descriptors)
+{
+ DescriptorTokenizerState state = Start;
+ const CharType* descriptorsStart = position;
+ const CharType* currentDescriptorStart = descriptorsStart;
+ while (true) {
+ switch (state) {
+ case Start:
+ if (isEOF(position, attributeEnd)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, attributeEnd, descriptors);
+ return;
+ }
+ if (isComma(*position)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, position, descriptors);
+ ++position;
+ return;
+ }
+ if (isHTMLSpace(*position)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, position, descriptors);
+ currentDescriptorStart = position + 1;
+ state = AfterToken;
+ } else if (*position == '(') {
+ appendCharacter(currentDescriptorStart, position);
+ state = InParenthesis;
+ } else {
+ appendCharacter(currentDescriptorStart, position);
+ }
+ break;
+ case InParenthesis:
+ if (isEOF(position, attributeEnd)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, attributeEnd, descriptors);
+ return;
+ }
+ if (*position == ')') {
+ appendCharacter(currentDescriptorStart, position);
+ state = Start;
+ } else {
+ appendCharacter(currentDescriptorStart, position);
+ }
+ break;
+ case AfterToken:
+ if (isEOF(position, attributeEnd))
+ return;
+ if (!isHTMLSpace(*position)) {
+ state = Start;
+ currentDescriptorStart = position;
+ --position;
+ }
+ break;
+ }
++position;
- ASSERT(currentDescriptorEnd > currentDescriptorStart);
- --currentDescriptorEnd;
- unsigned descriptorLength = currentDescriptorEnd - currentDescriptorStart;
- if (*currentDescriptorEnd == 'x') {
- if (isScaleFactorFound)
- return false;
- imgScaleFactor = charactersToFloat(currentDescriptorStart, descriptorLength, &isValid);
- isScaleFactorFound = true;
- } else {
+ }
+}
+
+template<typename CharType>
+static bool parseDescriptors(const CharType* attribute, Vector<DescriptorToken>& descriptors, DescriptorParsingResult& result)
+{
+ for (Vector<DescriptorToken>::iterator it = descriptors.begin(); it != descriptors.end(); ++it) {
+ if (it->length == 0)
continue;
+ CharType c = attribute[it->lastIndex()];
+ bool isValid = false;
+ if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'w') {
+ if (result.hasDensity() || result.hasWidth())
+ return false;
+ int resourceWidth = it->toInt(attribute, isValid);
+ if (!isValid || resourceWidth <= 0)
+ return false;
+ result.setResourceWidth(resourceWidth);
+ } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'h') {
+ // This is here only for future compat purposes.
+ // The value of the 'h' descriptor is not used.
+ if (result.hasDensity() || result.hasHeight())
+ return false;
+ int resourceHeight = it->toInt(attribute, isValid);
+ if (!isValid || resourceHeight <= 0)
+ return false;
+ result.setResourceHeight(resourceHeight);
+ } else if (c == 'x') {
+ if (result.hasDensity() || result.hasHeight() || result.hasWidth())
+ return false;
+ float density = it->toFloat(attribute, isValid);
+ if (!isValid || density < 0)
+ return false;
+ result.setDensity(density);
}
}
- return isValid;
+ return true;
}
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#processing-the-image-candidates
+static bool parseDescriptors(const String& attribute, Vector<DescriptorToken>& descriptors, DescriptorParsingResult& result)
+{
+ // FIXME: See if StringView can't be extended to replace DescriptorToken here.
+ if (attribute.is8Bit()) {
+ return parseDescriptors(attribute.characters8(), descriptors, result);
+ }
+ return parseDescriptors(attribute.characters16(), descriptors, result);
+}
+
+// http://picture.responsiveimages.org/#parse-srcset-attr
template<typename CharType>
static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, const CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandidates)
{
@@ -84,37 +211,46 @@ static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
const CharType* attributeEnd = position + length;
while (position < attributeEnd) {
- float imgScaleFactor = 1.0;
-
- // 4. Splitting loop: Skip whitespace.
- skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
- if (position == attributeEnd)
+ // 4. Splitting loop: Collect a sequence of characters that are space characters or U+002C COMMA characters.
+ skipWhile<CharType, isHTMLSpaceOrComma<CharType> >(position, attributeEnd);
+ if (position == attributeEnd) {
+ // Contrary to spec language - descriptor parsing happens on each candidate, so when we reach the attributeEnd, we can exit.
break;
- const CharType* imageURLStart = position;
-
- // If The current candidate is either totally empty or only contains space, skipping.
- if (*position == ',') {
- ++position;
- continue;
}
+ const CharType* imageURLStart = position;
+ // 6. Collect a sequence of characters that are not space characters, and let that be url.
- // 5. Collect a sequence of characters that are not space characters, and let that be url.
skipUntil<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
const CharType* imageURLEnd = position;
- if (position != attributeEnd && *(position - 1) == ',') {
- --imageURLEnd;
+ DescriptorParsingResult result;
+
+ // 8. If url ends with a U+002C COMMA character (,)
+ if (isComma(*(position - 1))) {
+ // Remove all trailing U+002C COMMA characters from url.
+ imageURLEnd = position - 1;
+ reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart);
+ ++imageURLEnd;
+ // If url is empty, then jump to the step labeled splitting loop.
+ if (imageURLStart == imageURLEnd)
+ continue;
} else {
- // 7. Collect a sequence of characters that are not "," (U+002C) characters, and let that be descriptors.
- skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
- const CharType* descriptorsStart = position;
- skipUntil<CharType, isComma<CharType> >(position, attributeEnd);
- const CharType* descriptorsEnd = position;
- if (!parseDescriptors(descriptorsStart, descriptorsEnd, imgScaleFactor))
+ // Advancing position here (contrary to spec) to avoid an useless extra state machine step.
+ // Filed a spec bug: https://github.com/ResponsiveImagesCG/picture-element/issues/189
+ ++position;
+ Vector<DescriptorToken> descriptorTokens;
+ tokenizeDescriptors(attributeStart, position, attributeEnd, descriptorTokens);
+ // Contrary to spec language - descriptor parsing happens on each candidate.
+ // This is a black-box equivalent, to avoid storing descriptor lists for each candidate.
+ if (!parseDescriptors(attribute, descriptorTokens, result))
continue;
}
- imageCandidates.append(ImageCandidate(attribute, imageURLStart - attributeStart, imageURLEnd - imageURLStart, imgScaleFactor));
+ ASSERT(imageURLEnd > attributeStart);
+ unsigned imageURLStartingPosition = imageURLStart - attributeStart;
+ ASSERT(imageURLEnd > imageURLStart);
+ unsigned imageURLLength = imageURLEnd - imageURLStart;
+ imageCandidates.append(ImageCandidate(attribute, imageURLStartingPosition, imageURLLength, result, ImageCandidate::SrcsetOrigin));
// 11. Return to the step labeled splitting loop.
}
}
@@ -130,36 +266,61 @@ static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.characters16(), attribute.length(), imageCandidates);
}
-static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<ImageCandidate>& imageCandidates)
+static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, unsigned sourceSize, Vector<ImageCandidate>& imageCandidates)
{
+ const float defaultDensityValue = 1.0;
+ bool ignoreSrc = false;
if (imageCandidates.isEmpty())
return ImageCandidate();
- std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByScaleFactor);
+ // http://picture.responsiveimages.org/#normalize-source-densities
+ for (Vector<ImageCandidate>::iterator it = imageCandidates.begin(); it != imageCandidates.end(); ++it) {
+ if (it->resourceWidth() > 0) {
+ it->setDensity((float)it->resourceWidth() / (float)sourceSize);
+ ignoreSrc = true;
+ } else if (it->density() < 0) {
+ it->setDensity(defaultDensityValue);
+ }
+ }
+
+ std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByDensity);
unsigned i;
for (i = 0; i < imageCandidates.size() - 1; ++i) {
- if (imageCandidates[i].scaleFactor() >= deviceScaleFactor)
+ if ((imageCandidates[i].density() >= deviceScaleFactor) && (!ignoreSrc || !imageCandidates[i].srcOrigin()))
break;
}
- return imageCandidates[i];
+
+ if (imageCandidates[i].srcOrigin() && ignoreSrc) {
+ ASSERT(i > 0);
+ --i;
+ }
+ float winningDensity = imageCandidates[i].density();
+
+ unsigned winner = i;
+ // 16. If an entry b in candidates has the same associated ... pixel density as an earlier entry a in candidates,
+ // then remove entry b
+ while ((i > 0) && (imageCandidates[--i].density() == winningDensity))
+ winner = i;
+
+ return imageCandidates[winner];
}
-ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const String& srcsetAttribute)
+ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, unsigned sourceSize, const String& srcsetAttribute)
{
Vector<ImageCandidate> imageCandidates;
parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates);
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates);
+ return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates);
}
-ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute)
+ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, const String& srcsetAttribute)
{
if (srcsetAttribute.isNull()) {
if (srcAttribute.isNull())
return ImageCandidate();
- return ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1);
+ return ImageCandidate(srcAttribute, 0, srcAttribute.length(), DescriptorParsingResult(), ImageCandidate::SrcOrigin);
}
Vector<ImageCandidate> imageCandidates;
@@ -167,12 +328,12 @@ ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const St
parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates);
if (!srcAttribute.isEmpty())
- imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1.0));
+ imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), DescriptorParsingResult(), ImageCandidate::SrcOrigin));
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates);
+ return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates);
}
-String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, ImageCandidate& srcsetImageCandidate)
+String bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, ImageCandidate& srcsetImageCandidate)
{
if (srcsetImageCandidate.isEmpty())
return srcAttribute;
@@ -181,9 +342,9 @@ String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr
imageCandidates.append(srcsetImageCandidate);
if (!srcAttribute.isEmpty())
- imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1.0));
+ imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), DescriptorParsingResult(), ImageCandidate::SrcOrigin));
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString();
+ return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates).toString();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
index 8964ffbcd5f..5ba5bff7f4f 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,27 +36,85 @@
namespace WebCore {
+enum { UninitializedDescriptor = -1 };
+
+class DescriptorParsingResult {
+public:
+ DescriptorParsingResult()
+ : m_density(UninitializedDescriptor)
+ , m_resourceWidth(UninitializedDescriptor)
+ , m_resourceHeight(UninitializedDescriptor)
+ {
+ }
+
+ bool hasDensity() const { return m_density >= 0; }
+ bool hasWidth() const { return m_resourceWidth >= 0; }
+ bool hasHeight() const { return m_resourceHeight >= 0; }
+
+ float density() const { ASSERT(hasDensity()); return m_density; }
+ unsigned resourceWidth() const { ASSERT(hasWidth()); return m_resourceWidth; }
+ unsigned resourceHeight() const { ASSERT(hasHeight()); return m_resourceHeight; }
+
+ void setResourceWidth(int width) { ASSERT(width >= 0); m_resourceWidth = (unsigned)width; }
+ void setResourceHeight(int height) { ASSERT(height >= 0); m_resourceHeight = (unsigned)height; }
+ void setDensity(float densityToSet) { ASSERT(densityToSet >= 0); m_density = densityToSet; }
+
+private:
+ float m_density;
+ int m_resourceWidth;
+ int m_resourceHeight;
+};
+
class ImageCandidate {
public:
+ enum OriginAttribute {
+ SrcsetOrigin,
+ SrcOrigin
+ };
+
ImageCandidate()
- : m_scaleFactor(1.0)
+ : m_density(1.0)
+ , m_resourceWidth(UninitializedDescriptor)
+ , m_originAttribute(SrcsetOrigin)
{
}
- ImageCandidate(const String& source, unsigned start, unsigned length, float scaleFactor)
+ ImageCandidate(const String& source, unsigned start, unsigned length, const DescriptorParsingResult& result, OriginAttribute originAttribute)
: m_string(source.createView(start, length))
- , m_scaleFactor(scaleFactor)
+ , m_density(result.hasDensity()?result.density():UninitializedDescriptor)
+ , m_resourceWidth(result.hasWidth()?result.resourceWidth():UninitializedDescriptor)
+ , m_originAttribute(originAttribute)
{
}
String toString() const
{
- return m_string.toString();
+ return String(m_string.toString());
+ }
+
+ AtomicString url() const
+ {
+ return AtomicString(m_string.toString());
+ }
+
+ void setDensity(float factor)
+ {
+ m_density = factor;
+ }
+
+ float density() const
+ {
+ return m_density;
+ }
+
+ int resourceWidth() const
+ {
+ return m_resourceWidth;
}
- inline float scaleFactor() const
+ bool srcOrigin() const
{
- return m_scaleFactor;
+ return (m_originAttribute == SrcOrigin);
}
inline bool isEmpty() const
@@ -65,14 +124,16 @@ public:
private:
StringView m_string;
- float m_scaleFactor;
+ float m_density;
+ int m_resourceWidth;
+ OriginAttribute m_originAttribute;
};
-ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const String& srcsetAttribute);
+ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, unsigned sourceSize, const String& srcsetAttribute);
-ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute);
+ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, const String& srcsetAttribute);
-String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, ImageCandidate& srcsetImageCandidate);
+String bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, ImageCandidate& srcsetImageCandidate);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp
new file mode 100644
index 00000000000..76236102f90
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp
@@ -0,0 +1,102 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/parser/HTMLSrcsetParser.h"
+
+#include <gtest/gtest.h>
+#include <limits.h>
+
+namespace WebCore {
+
+typedef struct {
+ float deviceScaleFactor;
+ int effectiveSize;
+ const char* srcInput;
+ const char* srcsetInput;
+ const char* outputURL;
+ float outputDensity;
+ int outputResourceWidth;
+} TestCase;
+
+TEST(ImageCandidateTest, Basic)
+{
+ ImageCandidate candidate;
+ ASSERT_EQ(candidate.density(), 1);
+ ASSERT_EQ(candidate.resourceWidth(), -1);
+ ASSERT_EQ(candidate.srcOrigin(), false);
+
+}
+
+TEST(HTMLSrcsetParserTest, Basic)
+{
+ TestCase testCases[] = {
+ {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
+ {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1},
+ {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif , 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
+ {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+ {2.0, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "3x.gif", 3.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", ",,1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
+ {2.0, -1, "", ",1x,", "1x", 1.0, -1},
+ {2.0, -1, "", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 2.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "2x.gif", 2.0, -1},
+ {4.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "2x.gif", 2.0, -1},
+ {4.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "4x.gif", 4.0, -1},
+ {1.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "1x", 1.0, -1},
+ {5.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "4x.gif", 4.0, -1},
+ {2.0, -1, "", "1x.gif 1x, data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K 2x", "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K", 2.0, -1 },
+ {2.0, -1, "1x.gif", "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K 2x", "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K", 2.0, -1 },
+ {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#green", 2.0, -1 },
+ {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#green", 2.0, -1 },
+ {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {2.0, 400, "", "400.gif 400w, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+ {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
+ {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0, 800},
+ {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
+ {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
+ {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+ {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif", std::numeric_limits<float>::infinity(), 400},
+ {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1.4x.gif", 1.4, -1},
+ {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1},
+ {1.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "1x.gif", 1.0, -1},
+ {2.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "2x.gif", 2.0, -1},
+ {0, 0, 0, 0, 0, 0} // Do not remove the terminator line.
+ };
+
+ for (unsigned i = 0; testCases[i].srcInput; ++i) {
+ TestCase test = testCases[i];
+ ImageCandidate candidate = bestFitSourceForImageAttributes(test.deviceScaleFactor, test.effectiveSize, test.srcInput, test.srcsetInput);
+ ASSERT_EQ(test.outputDensity, candidate.density());
+ ASSERT_EQ(test.outputResourceWidth, candidate.resourceWidth());
+ ASSERT_STREQ(test.outputURL, candidate.toString().ascii().data());
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h
index d3dd15ca269..e15c2c119cc 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h
@@ -26,9 +26,9 @@
#ifndef HTMLStackItem_h
#define HTMLStackItem_h
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Element.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "wtf/RefCounted.h"
@@ -39,7 +39,7 @@ namespace WebCore {
class ContainerNode;
-class HTMLStackItem : public RefCounted<HTMLStackItem> {
+class HTMLStackItem : public RefCountedWillBeGarbageCollectedFinalized<HTMLStackItem> {
public:
enum ItemType {
ItemForContextElement,
@@ -47,15 +47,15 @@ public:
};
// Used by document fragment node and context element.
- static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, ItemType type)
+ static PassRefPtrWillBeRawPtr<HTMLStackItem> create(PassRefPtrWillBeRawPtr<ContainerNode> node, ItemType type)
{
- return adoptRef(new HTMLStackItem(node, type));
+ return adoptRefWillBeNoop(new HTMLStackItem(node, type));
}
// Used by HTMLElementStack and HTMLFormattingElementList.
- static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+ static PassRefPtrWillBeRawPtr<HTMLStackItem> create(PassRefPtrWillBeRawPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
{
- return adoptRef(new HTMLStackItem(node, token, namespaceURI));
+ return adoptRefWillBeNoop(new HTMLStackItem(node, token, namespaceURI));
}
Element* element() const { return toElement(m_node.get()); }
@@ -172,7 +172,6 @@ public:
|| tagName == HTMLNames::iframeTag
|| tagName == HTMLNames::imgTag
|| tagName == HTMLNames::inputTag
- || tagName == HTMLNames::isindexTag
|| tagName == HTMLNames::liTag
|| tagName == HTMLNames::linkTag
|| tagName == HTMLNames::listingTag
@@ -208,8 +207,10 @@ public:
|| tagName == HTMLNames::xmpTag;
}
+ void trace(Visitor* visitor) { visitor->trace(m_node); }
+
private:
- HTMLStackItem(PassRefPtr<ContainerNode> node, ItemType type)
+ HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node, ItemType type)
: m_node(node)
{
switch (type) {
@@ -224,7 +225,7 @@ private:
}
}
- HTMLStackItem(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+ HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
: m_node(node)
, m_tokenLocalName(token->name())
, m_tokenAttributes(token->attributes())
@@ -233,7 +234,7 @@ private:
{
}
- RefPtr<ContainerNode> m_node;
+ RefPtrWillBeMember<ContainerNode> m_node;
AtomicString m_tokenLocalName;
Vector<Attribute> m_tokenAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h
index 64f3044631b..e2b67fc33aa 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h
@@ -27,7 +27,6 @@
#define HTMLToken_h
#include "core/dom/Attribute.h"
-#include "core/html/parser/HTMLToken.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -104,7 +103,12 @@ public:
m_range.start = 0;
m_range.end = 0;
m_baseOffset = 0;
- m_data.clear();
+ // Don't call Vector::clear() as that would destroy the
+ // alloced VectorBuffer. If the innerHTML'd content has
+ // two 257 character text nodes in a row, we'll needlessly
+ // thrash malloc. When we finally finish the parse the
+ // HTMLToken will be destroyed and the VectorBuffer released.
+ m_data.shrink(0);
m_orAllData = 0;
}
@@ -326,9 +330,7 @@ public:
{
ASSERT(character);
ASSERT(m_type == StartTag || m_type == EndTag);
- // FIXME: We should be able to add the following ASSERT once we fix
- // https://bugs.webkit.org/show_bug.cgi?id=62971
- // ASSERT(m_currentAttribute->nameRange.start);
+ ASSERT(m_currentAttribute->nameRange.start);
m_currentAttribute->name.append(character);
}
@@ -426,6 +428,7 @@ public:
m_orAllData |= character;
}
+ // Only for XSSAuditor
void eraseCharacters()
{
ASSERT(m_type == Character);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
index ed8c954a64b..8b03782d45e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
@@ -28,8 +28,10 @@
#include "config.h"
#include "core/html/parser/HTMLTokenizer.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/HTMLTokenizerNames.h"
#include "core/html/parser/HTMLEntityParser.h"
+#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLTreeBuilder.h"
#include "platform/NotImplemented.h"
#include "core/xml/parser/MarkupTokenizerInlines.h"
@@ -37,7 +39,9 @@
#include "wtf/text/AtomicString.h"
#include "wtf/unicode/Unicode.h"
-using namespace WTF;
+// Please don't use DEFINE_STATIC_LOCAL in this file. The HTMLTokenizer is used
+// from multiple threads and DEFINE_STATIC_LOCAL isn't threadsafe.
+#undef DEFINE_STATIC_LOCAL
namespace WebCore {
@@ -1071,11 +1075,8 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
END_STATE()
HTML_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);
+ SegmentedString::LookAheadResult result = source.lookAhead(HTMLTokenizerNames::dashDash);
if (result == SegmentedString::DidMatch) {
source.advanceAndASSERT('-');
source.advanceAndASSERT('-');
@@ -1084,14 +1085,14 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
} else if (result == SegmentedString::NotEnoughCharacters)
return haveBufferedCharacterToken();
} else if (cc == 'D' || cc == 'd') {
- SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(doctypeString);
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(HTMLTokenizerNames::doctype);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERTIgnoringCase(source, "doctype");
HTML_SWITCH_TO(DOCTYPEState);
} else if (result == SegmentedString::NotEnoughCharacters)
return haveBufferedCharacterToken();
} else if (cc == '[' && shouldAllowCDATA()) {
- SegmentedString::LookAheadResult result = source.lookAhead(cdataString);
+ SegmentedString::LookAheadResult result = source.lookAhead(HTMLTokenizerNames::cdata);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERT(source, "[CDATA[");
HTML_SWITCH_TO(CDATASectionState);
@@ -1274,17 +1275,15 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
m_token->setForceQuirks();
return emitAndReconsumeIn(source, HTMLTokenizer::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);
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(HTMLTokenizerNames::publicString);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERTIgnoringCase(source, "public");
HTML_SWITCH_TO(AfterDOCTYPEPublicKeywordState);
} else if (result == SegmentedString::NotEnoughCharacters)
return haveBufferedCharacterToken();
} else if (cc == 'S' || cc == 's') {
- SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(systemString);
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(HTMLTokenizerNames::system);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERTIgnoringCase(source, "system");
HTML_SWITCH_TO(AfterDOCTYPESystemKeywordState);
@@ -1596,20 +1595,20 @@ String HTMLTokenizer::bufferedCharacters() const
return characters.toString();
}
-void HTMLTokenizer::updateStateFor(const AtomicString& tagName)
+void HTMLTokenizer::updateStateFor(const String& tagName)
{
- if (tagName == textareaTag || tagName == titleTag)
+ if (threadSafeMatch(tagName, textareaTag) || threadSafeMatch(tagName, titleTag))
setState(HTMLTokenizer::RCDATAState);
- else if (tagName == plaintextTag)
+ else if (threadSafeMatch(tagName, plaintextTag))
setState(HTMLTokenizer::PLAINTEXTState);
- else if (tagName == scriptTag)
+ else if (threadSafeMatch(tagName, scriptTag))
setState(HTMLTokenizer::ScriptDataState);
- else if (tagName == styleTag
- || tagName == iframeTag
- || tagName == xmpTag
- || (tagName == noembedTag && m_options.pluginsEnabled)
- || tagName == noframesTag
- || (tagName == noscriptTag && m_options.scriptEnabled))
+ else if (threadSafeMatch(tagName, styleTag)
+ || threadSafeMatch(tagName, iframeTag)
+ || threadSafeMatch(tagName, xmpTag)
+ || (threadSafeMatch(tagName, noembedTag) && m_options.pluginsEnabled)
+ || threadSafeMatch(tagName, noframesTag)
+ || (threadSafeMatch(tagName, noscriptTag) && m_options.scriptEnabled))
setState(HTMLTokenizer::RAWTEXTState);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
index aa7c059bf78..3a4ca7f96a1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
@@ -126,7 +126,6 @@ public:
State state;
UChar additionalAllowedCharacter;
bool skipNextNewLine;
- bool forceNullCharacterReplacement;
bool shouldAllowCDATA;
Checkpoint()
@@ -134,7 +133,6 @@ public:
, state()
, additionalAllowedCharacter('\0')
, skipNextNewLine(false)
- , forceNullCharacterReplacement(false)
, shouldAllowCDATA(false)
{
}
@@ -176,7 +174,7 @@ public:
// * CDATA sections in foreign content will be tokenized as bogus comments
// instead of as character tokens.
//
- void updateStateFor(const AtomicString& tagName);
+ void updateStateFor(const String& tagName);
bool forceNullCharacterReplacement() const { return m_forceNullCharacterReplacement; }
void setForceNullCharacterReplacement(bool value) { m_forceNullCharacterReplacement = value; }
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in
new file mode 100644
index 00000000000..0eab51f4ea0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in
@@ -0,0 +1,8 @@
+namespace="HTMLTokenizer"
+
+-- Symbol=dashDash
+doctype
+[CDATA[ Symbol=cdata
+# The symbol "public" conflicts with the C++ keyword.
+public Symbol=publicString
+system
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
index 4196cde09f0..092240a2c3b 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -27,19 +27,17 @@
#include "config.h"
#include "core/html/parser/HTMLTreeBuilder.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "core/dom/DocumentFragment.h"
+#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLFormElement.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLOptGroupElement.h"
-#include "core/html/HTMLTableElement.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -136,18 +134,10 @@ static bool isFormattingTag(const AtomicString& tagName)
return tagName == aTag || isNonAnchorFormattingTag(tagName);
}
-static HTMLFormElement* closestFormAncestor(Element* element)
+static HTMLFormElement* closestFormAncestor(Element& element)
{
ASSERT(isMainThread());
- while (element) {
- if (element->hasTagName(formTag))
- return toHTMLFormElement(element);
- ContainerNode* parent = element->parentNode();
- if (!parent || !parent->isElementNode())
- return 0;
- element = toElement(parent);
- }
- return 0;
+ return Traversal<HTMLFormElement>::firstAncestorOrSelf(element);
}
class HTMLTreeBuilder::CharacterTokenBuffer {
@@ -305,27 +295,33 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
, m_options(options)
{
ASSERT(isMainThread());
- // FIXME: This assertion will become invalid if <http://webkit.org/b/60316> is fixed.
ASSERT(contextElement);
- if (contextElement) {
- // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
- // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
- // and instead use the DocumentFragment as a root node.
- m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStackItem::ItemForDocumentFragmentNode));
- if (contextElement->hasTagName(templateTag))
- m_templateInsertionModes.append(TemplateContentsMode);
+ // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
+ // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
+ // and instead use the DocumentFragment as a root node.
+ m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStackItem::ItemForDocumentFragmentNode));
- resetInsertionModeAppropriately();
- m_tree.setForm(closestFormAncestor(contextElement));
- }
+ if (isHTMLTemplateElement(*contextElement))
+ m_templateInsertionModes.append(TemplateContentsMode);
+
+ resetInsertionModeAppropriately();
+ m_tree.setForm(closestFormAncestor(*contextElement));
}
HTMLTreeBuilder::~HTMLTreeBuilder()
{
}
+void HTMLTreeBuilder::trace(Visitor* visitor)
+{
+ visitor->trace(m_fragmentContext);
+ visitor->trace(m_tree);
+ visitor->trace(m_parser);
+ visitor->trace(m_scriptToProcess);
+}
+
void HTMLTreeBuilder::detach()
{
#ifndef NDEBUG
@@ -339,14 +335,14 @@ void HTMLTreeBuilder::detach()
}
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
- : m_fragment(0)
+ : m_fragment(nullptr)
{
}
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement)
: m_fragment(fragment)
{
- ASSERT(!fragment->hasChildNodes());
+ ASSERT(!fragment->hasChildren());
m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackItem::ItemForContextElement);
}
@@ -354,7 +350,13 @@ HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
{
}
-PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
+void HTMLTreeBuilder::FragmentParsingContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_fragment);
+ visitor->trace(m_contextElementStackItem);
+}
+
+PassRefPtrWillBeRawPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
{
ASSERT(m_scriptToProcess);
ASSERT(!m_tree.hasPendingTasks());
@@ -461,13 +463,6 @@ void HTMLTreeBuilder::processFakeEndTag(const QualifiedName& tagName)
processFakeEndTag(tagName.localName());
}
-void HTMLTreeBuilder::processFakeCharacters(const String& characters)
-{
- ASSERT(!characters.isEmpty());
- CharacterTokenBuffer buffer(characters);
- processCharacterBuffer(buffer);
-}
-
void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
{
if (!m_tree.openElements()->inButtonScope(pTag.localName()))
@@ -476,49 +471,6 @@ void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
processEndTag(&endP);
}
-Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken* token)
-{
- Vector<Attribute> attributes = token->attributes();
- for (int i = attributes.size() - 1; i >= 0; --i) {
- const QualifiedName& name = attributes.at(i).name();
- if (name.matches(nameAttr) || name.matches(actionAttr) || name.matches(promptAttr))
- attributes.remove(i);
- }
-
- attributes.append(Attribute(nameAttr, isindexTag.localName()));
- return attributes;
-}
-
-void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
-{
- ASSERT(token->type() == HTMLToken::StartTag);
- ASSERT(token->name() == isindexTag);
-
- if (m_parser->useCounter())
- m_parser->useCounter()->count(UseCounter::IsIndexElement);
-
- parseError(token);
- if (m_tree.form())
- return;
- notImplemented(); // Acknowledge self-closing flag
- processFakeStartTag(formTag);
- Attribute* actionAttribute = token->getAttributeItem(actionAttr);
- if (actionAttribute)
- m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
- processFakeStartTag(hrTag);
- processFakeStartTag(labelTag);
- Attribute* promptAttribute = token->getAttributeItem(promptAttr);
- if (promptAttribute)
- processFakeCharacters(promptAttribute->value());
- else
- processFakeCharacters(Locale::defaultLocale().queryString(blink::WebLocalizedString::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 HTMLStackItem* item)
@@ -540,7 +492,7 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token)
m_framesetOk = false;
HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
while (1) {
- RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> item = nodeRecord->stackItem();
if (shouldClose(item.get())) {
ASSERT(item->isElementNode());
processFakeEndTag(item->localName());
@@ -572,8 +524,8 @@ static void adjustSVGTagNameCase(AtomicHTMLToken* token)
static PrefixedNameToQualifiedNameMap* caseMap = 0;
if (!caseMap) {
caseMap = new PrefixedNameToQualifiedNameMap;
- const QualifiedName* const* svgTags = SVGNames::getSVGTags();
- mapLoweredLocalNameToName(caseMap, svgTags, SVGNames::SVGTagsCount);
+ OwnPtr<const QualifiedName*[]> svgTags = SVGNames::getSVGTags();
+ mapLoweredLocalNameToName(caseMap, svgTags.get(), SVGNames::SVGTagsCount);
}
const QualifiedName& casedName = caseMap->get(token->name());
@@ -582,14 +534,14 @@ static void adjustSVGTagNameCase(AtomicHTMLToken* token)
token->setName(casedName.localName());
}
-template<const QualifiedName* const* getAttrs(), unsigned length>
+template<PassOwnPtr<const QualifiedName*[]> getAttrs(), unsigned length>
static void adjustAttributes(AtomicHTMLToken* token)
{
static PrefixedNameToQualifiedNameMap* caseMap = 0;
if (!caseMap) {
caseMap = new PrefixedNameToQualifiedNameMap;
- const QualifiedName* const* attrs = getAttrs();
- mapLoweredLocalNameToName(caseMap, attrs, length);
+ OwnPtr<const QualifiedName*[]> attrs = getAttrs();
+ mapLoweredLocalNameToName(caseMap, attrs.get(), length);
}
for (unsigned i = 0; i < token->attributes().size(); ++i) {
@@ -627,11 +579,11 @@ static void adjustForeignAttributes(AtomicHTMLToken* token)
if (!map) {
map = new PrefixedNameToQualifiedNameMap;
- const QualifiedName* const* attrs = XLinkNames::getXLinkAttrs();
- addNamesWithPrefix(map, xlinkAtom, attrs, XLinkNames::XLinkAttrsCount);
+ OwnPtr<const QualifiedName*[]> attrs = XLinkNames::getXLinkAttrs();
+ addNamesWithPrefix(map, xlinkAtom, attrs.get(), XLinkNames::XLinkAttrsCount);
- attrs = XMLNames::getXMLAttrs();
- addNamesWithPrefix(map, xmlAtom, attrs, XMLNames::XMLAttrsCount);
+ OwnPtr<const QualifiedName*[]> xmlAttrs = XMLNames::getXMLAttrs();
+ addNamesWithPrefix(map, xmlAtom, xmlAttrs.get(), XMLNames::XMLAttrsCount);
map->add(WTF::xmlnsAtom, XMLNSNames::xmlnsAttr);
map->add("xmlns:xlink", QualifiedName(xmlnsAtom, xlinkAtom, XMLNSNames::xmlnsNamespaceURI));
@@ -859,10 +811,6 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
m_framesetOk = false;
return;
}
- if (token->name() == isindexTag) {
- processIsindexStartTagForInBody(token);
- return;
- }
if (token->name() == textareaTag) {
m_tree.insertHTMLElement(token);
m_shouldSkipLeadingNewline = true;
@@ -969,7 +917,7 @@ bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token)
{
ASSERT(token->name() == templateTag.localName());
if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
- ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement()->hasTagName(templateTag)));
+ ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && isHTMLTemplateElement(m_fragmentContext.contextElement())));
parseError(token);
return false;
}
@@ -995,7 +943,7 @@ bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(AtomicHTMLToken* tok
bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
{
- if (m_tree.currentIsRootNode() || m_tree.currentNode()->hasTagName(templateTag)) {
+ if (m_tree.currentIsRootNode() || isHTMLTemplateElement(*m_tree.currentNode())) {
ASSERT(isParsingFragmentOrTemplateContents());
// FIXME: parse error
return false;
@@ -1396,7 +1344,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
processEndTag(&endOption);
}
- if (isHTMLOptGroupElement(m_tree.currentStackItem()->node())) {
+ if (m_tree.currentStackItem()->hasTagName(optgroupTag)) {
AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
processEndTag(&endOptgroup);
}
@@ -1505,7 +1453,7 @@ void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token)
ASSERT(token->type() == HTMLToken::EndTag);
HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
while (1) {
- RefPtr<HTMLStackItem> item = record->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> item = record->stackItem();
if (item->matchesHTMLTag(token->name())) {
m_tree.generateImpliedEndTagsWithExclusion(token->name());
if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
@@ -1564,7 +1512,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
}
// 7.
ASSERT(furthestBlock->isAbove(formattingElementRecord));
- RefPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
// 8.
HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
// 9.
@@ -1587,7 +1535,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
if (node == formattingElementRecord)
break;
// 9.7
- RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
+ RefPtrWillBeRawPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
nodeEntry->replaceElement(newItem);
@@ -1604,7 +1552,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
// 10.
m_tree.insertAlreadyParsedChild(commonAncestor.get(), lastNode);
// 11.
- RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
+ RefPtrWillBeRawPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
// 12.
m_tree.takeAllChildren(newItem.get(), furthestBlock);
// 13.
@@ -1623,7 +1571,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
bool last = false;
HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
while (1) {
- RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> item = nodeRecord->stackItem();
if (item->node() == m_tree.openElements()->rootNode()) {
last = true;
if (isParsingFragment())
@@ -1636,7 +1584,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
while (item->node() != m_tree.openElements()->rootNode() && !item->hasTagName(templateTag)) {
nodeRecord = nodeRecord->next();
item = nodeRecord->stackItem();
- if (isHTMLTableElement(item->node()))
+ if (item->hasTagName(tableTag))
return setInsertionMode(InSelectInTableMode);
}
}
@@ -1653,7 +1601,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
if (item->hasTagName(colgroupTag)) {
return setInsertionMode(InColumnGroupMode);
}
- if (isHTMLTableElement(item->node()))
+ if (item->hasTagName(tableTag))
return setInsertionMode(InTableMode);
if (item->hasTagName(headTag)) {
if (!m_fragmentContext.fragment() || m_fragmentContext.contextElement() != item->node())
@@ -1665,7 +1613,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
if (item->hasTagName(framesetTag)) {
return setInsertionMode(InFramesetMode);
}
- if (isHTMLHtmlElement(item->node())) {
+ if (item->hasTagName(htmlTag)) {
if (m_tree.headStackItem())
return setInsertionMode(AfterHeadMode);
@@ -1839,7 +1787,7 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token)
return;
}
if (token->name() == formTag) {
- RefPtr<Element> node = m_tree.takeForm();
+ RefPtrWillBeRawPtr<Element> node = m_tree.takeForm();
if (!node || !m_tree.openElements()->inScope(node.get())) {
parseError(token);
return;
@@ -2212,9 +2160,9 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
case InSelectMode:
ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
if (token->name() == optgroupTag) {
- if (m_tree.currentStackItem()->hasTagName(optionTag) && m_tree.oneBelowTop() && isHTMLOptGroupElement(m_tree.oneBelowTop()->node()))
+ if (m_tree.currentStackItem()->hasTagName(optionTag) && m_tree.oneBelowTop() && m_tree.oneBelowTop()->hasTagName(optgroupTag))
processFakeEndTag(optionTag);
- if (isHTMLOptGroupElement(m_tree.currentStackItem()->node())) {
+ if (m_tree.currentStackItem()->hasTagName(optgroupTag)) {
m_tree.openElements()->pop();
return;
}
@@ -2366,11 +2314,11 @@ ReprocessBuffer:
ASSERT(insertionMode() == InTableMode || insertionMode() == InTableBodyMode || insertionMode() == InRowMode);
ASSERT(m_pendingTableCharacters.isEmpty());
if (m_tree.currentStackItem()->isElementNode()
- && (isHTMLTableElement(m_tree.currentStackItem()->node())
- || m_tree.currentStackItem()->hasTagName(HTMLNames::tbodyTag)
- || m_tree.currentStackItem()->hasTagName(HTMLNames::tfootTag)
- || m_tree.currentStackItem()->hasTagName(HTMLNames::theadTag)
- || m_tree.currentStackItem()->hasTagName(HTMLNames::trTag))) {
+ && (m_tree.currentStackItem()->hasTagName(tableTag)
+ || m_tree.currentStackItem()->hasTagName(tbodyTag)
+ || m_tree.currentStackItem()->hasTagName(tfootTag)
+ || m_tree.currentStackItem()->hasTagName(theadTag)
+ || m_tree.currentStackItem()->hasTagName(trTag))) {
m_originalInsertionMode = m_insertionMode;
setInsertionMode(InTableTextMode);
// Note that we fall through to the InTableTextMode case below.
@@ -2407,7 +2355,6 @@ ReprocessBuffer:
// FIXME: parse error
setInsertionMode(InBodyMode);
goto ReprocessBuffer;
- break;
}
case TextMode: {
ASSERT(insertionMode() == TextMode);
@@ -2423,7 +2370,6 @@ ReprocessBuffer:
return;
defaultForInHeadNoscript();
goto ReprocessBuffer;
- break;
}
case InFramesetMode:
case AfterFramesetMode: {
@@ -2514,7 +2460,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
ASSERT(isParsingFragment());
return; // FIXME: Should we break here instead of returning?
}
- ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || m_tree.currentNode()->hasTagName(templateTag));
+ ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || isHTMLTemplateElement(m_tree.currentNode()));
processColgroupEndTagForInColumnGroup();
// Fall through
case InFramesetMode:
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
index 60ead95f286..9c9dcdfae8d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
@@ -30,6 +30,7 @@
#include "core/html/parser/HTMLConstructionSite.h"
#include "core/html/parser/HTMLElementStack.h"
#include "core/html/parser/HTMLParserOptions.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
@@ -44,24 +45,25 @@ class AtomicHTMLToken;
class Document;
class DocumentFragment;
class Element;
-class Frame;
+class LocalFrame;
class HTMLToken;
class HTMLDocument;
class Node;
class HTMLDocumentParser;
-class HTMLTreeBuilder {
- WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
+class HTMLTreeBuilder FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLTreeBuilder> {
+ WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, ParserContentPolicy parserContentPolicy, bool reportErrors, const HTMLParserOptions& options)
+ static PassOwnPtrWillBeRawPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, ParserContentPolicy parserContentPolicy, bool reportErrors, const HTMLParserOptions& options)
{
- return adoptPtr(new HTMLTreeBuilder(parser, document, parserContentPolicy, reportErrors, options));
+ return adoptPtrWillBeNoop(new HTMLTreeBuilder(parser, document, parserContentPolicy, reportErrors, options));
}
- static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+ static PassOwnPtrWillBeRawPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
{
- return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, parserContentPolicy, options));
+ return adoptPtrWillBeNoop(new HTMLTreeBuilder(parser, fragment, contextElement, parserContentPolicy, options));
}
~HTMLTreeBuilder();
+ void trace(Visitor*);
const HTMLElementStack* openElements() const { return m_tree.openElements(); }
@@ -75,7 +77,7 @@ public:
bool hasParserBlockingScript() const { return !!m_scriptToProcess; }
// Must be called to take the parser-blocking script before calling the parser again.
- PassRefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
+ PassRefPtrWillBeRawPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
// Done, close any open tags, etc.
void finished();
@@ -153,7 +155,6 @@ private:
void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>());
void processFakeEndTag(const QualifiedName&);
void processFakeEndTag(const AtomicString&);
- void processFakeCharacters(const String&);
void processFakePEndTagIfPInButtonScope();
void processGenericRCDATAStartTag(AtomicHTMLToken*);
@@ -195,6 +196,7 @@ private:
class FragmentParsingContext {
WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
+ DISALLOW_ALLOCATION();
public:
FragmentParsingContext();
FragmentParsingContext(DocumentFragment*, Element* contextElement);
@@ -204,9 +206,11 @@ private:
Element* contextElement() const { ASSERT(m_fragment); return m_contextElementStackItem->element(); }
HTMLStackItem* contextElementStackItem() const { ASSERT(m_fragment); return m_contextElementStackItem.get(); }
+ void trace(Visitor*);
+
private:
- DocumentFragment* m_fragment;
- RefPtr<HTMLStackItem> m_contextElementStackItem;
+ RawPtrWillBeMember<DocumentFragment> m_fragment;
+ RefPtrWillBeMember<HTMLStackItem> m_contextElementStackItem;
};
bool m_framesetOk;
@@ -231,9 +235,9 @@ private:
// 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;
+ RawPtrWillBeMember<HTMLDocumentParser> m_parser;
- RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
+ RefPtrWillBeMember<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
HTMLParserOptions m_options;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
index 37273cbaea0..2f369953c05 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilder.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
index b46ff5ad2e9..d504a4c5703 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
@@ -27,14 +27,16 @@
#include "core/html/parser/HTMLViewSourceParser.h"
#include "core/dom/DOMImplementation.h"
+#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLToken.h"
+#include "core/html/parser/XSSAuditorDelegate.h"
namespace WebCore {
-HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document, const String& mimeType)
+HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument& document, const String& mimeType)
: DecodedDataDocumentParser(document)
- , m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(document)))
+ , m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(&document)))
{
if (mimeType != "text/html" && !DOMImplementation::isXMLMIMEType(mimeType))
m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
@@ -42,17 +44,21 @@ HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document, con
void HTMLViewSourceParser::pumpTokenizer()
{
+ m_xssAuditor.init(document(), 0);
+
while (true) {
m_sourceTracker.start(m_input.current(), m_tokenizer.get(), m_token);
if (!m_tokenizer->nextToken(m_input.current(), m_token))
return;
m_sourceTracker.end(m_input.current(), m_tokenizer.get(), m_token);
- document()->addSource(m_sourceTracker.sourceForToken(m_token), m_token);
+ OwnPtr<XSSInfo> xssInfo = m_xssAuditor.filterToken(FilterTokenRequest(m_token, m_sourceTracker, m_tokenizer->shouldAllowCDATA()));
+ HTMLViewSourceDocument::SourceAnnotation annotation = xssInfo ? HTMLViewSourceDocument::AnnotateSourceAsXSS : HTMLViewSourceDocument::AnnotateSourceAsSafe;
+ document()->addSource(m_sourceTracker.sourceForToken(m_token), m_token, annotation);
// FIXME: The tokenizer should do this work for us.
if (m_token.type() == HTMLToken::StartTag)
- m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+ m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name(), Likely8Bit));
m_token.clear();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h
index d1f0bec23c8..853387be4ab 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h
@@ -31,19 +31,20 @@
#include "core/html/parser/HTMLInputStream.h"
#include "core/html/parser/HTMLSourceTracker.h"
#include "core/html/parser/HTMLTokenizer.h"
+#include "core/html/parser/XSSAuditor.h"
namespace WebCore {
class HTMLViewSourceParser FINAL : public DecodedDataDocumentParser {
public:
- static PassRefPtr<HTMLViewSourceParser> create(HTMLViewSourceDocument* document, const String& mimeType)
+ static PassRefPtrWillBeRawPtr<HTMLViewSourceParser> create(HTMLViewSourceDocument& document, const String& mimeType)
{
- return adoptRef(new HTMLViewSourceParser(document, mimeType));
+ return adoptRefWillBeNoop(new HTMLViewSourceParser(document, mimeType));
}
virtual ~HTMLViewSourceParser() { }
private:
- HTMLViewSourceParser(HTMLViewSourceDocument*, const String& mimeType);
+ HTMLViewSourceParser(HTMLViewSourceDocument&, const String& mimeType);
// DocumentParser
virtual void insert(const SegmentedString&) OVERRIDE { ASSERT_NOT_REACHED(); }
@@ -59,6 +60,7 @@ private:
HTMLToken m_token;
HTMLSourceTracker m_sourceTracker;
OwnPtr<HTMLTokenizer> m_tokenizer;
+ XSSAuditor m_xssAuditor;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h b/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h
index fa1d110bdf3..478210e394e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h
@@ -26,11 +26,13 @@
#ifndef NestingLevelIncrementer_h
#define NestingLevelIncrementer_h
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
class NestingLevelIncrementer {
+ STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(NestingLevelIncrementer);
public:
explicit NestingLevelIncrementer(unsigned& nestingLevel)
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp
index 38175a0f6bf..b7fc5151e67 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp
@@ -25,14 +25,14 @@
#include "config.h"
#include "core/html/parser/TextDocumentParser.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/parser/HTMLTreeBuilder.h"
namespace WebCore {
using namespace HTMLNames;
-TextDocumentParser::TextDocumentParser(HTMLDocument* document)
+TextDocumentParser::TextDocumentParser(HTMLDocument& document)
: HTMLDocumentParser(document, false)
, m_haveInsertedFakePreElement(false)
{
@@ -42,11 +42,11 @@ TextDocumentParser::~TextDocumentParser()
{
}
-void TextDocumentParser::append(PassRefPtr<StringImpl> text)
+void TextDocumentParser::appendBytes(const char* data, size_t length)
{
if (!m_haveInsertedFakePreElement)
insertFakePreElement();
- HTMLDocumentParser::append(text);
+ HTMLDocumentParser::appendBytes(data, length);
}
void TextDocumentParser::insertFakePreElement()
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h
index 6b5bb9e6a4c..d1de29543dc 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h
@@ -30,18 +30,18 @@
namespace WebCore {
-class TextDocumentParser : public HTMLDocumentParser {
+class TextDocumentParser FINAL : public HTMLDocumentParser {
public:
- static PassRefPtr<TextDocumentParser> create(HTMLDocument* document)
+ static PassRefPtrWillBeRawPtr<TextDocumentParser> create(HTMLDocument& document)
{
- return adoptRef(new TextDocumentParser(document));
+ return adoptRefWillBeNoop(new TextDocumentParser(document));
}
virtual ~TextDocumentParser();
private:
- explicit TextDocumentParser(HTMLDocument*);
+ explicit TextDocumentParser(HTMLDocument&);
- virtual void append(PassRefPtr<StringImpl>);
+ virtual void appendBytes(const char*, size_t) OVERRIDE;
void insertFakePreElement();
bool m_haveInsertedFakePreElement;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp
new file mode 100644
index 00000000000..1f21e244f2a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp
@@ -0,0 +1,439 @@
+/*
+ Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+ Copyright (C) 2005, 2006, 2007 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 "core/html/parser/TextResourceDecoder.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/DOMImplementation.h"
+#include "core/html/parser/HTMLMetaCharsetParser.h"
+#include "platform/text/TextEncodingDetector.h"
+#include "wtf/StringExtras.h"
+#include "wtf/text/TextCodec.h"
+#include "wtf/text/TextEncodingRegistry.h"
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4;
+}
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5;
+}
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5 && p[6] == b6 && p[7] == b7;
+}
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5 && p[6] == b6 && p[7] == b7 && p[8] == b8 && p[9] == b9;
+}
+
+// You might think we should put these find functions elsewhere, perhaps with the
+// similar functions that operate on UChar, but arguably only the decoder has
+// a reason to process strings of char rather than UChar.
+
+static int find(const char* subject, size_t subjectLength, const char* target)
+{
+ size_t targetLength = strlen(target);
+ if (targetLength > subjectLength)
+ return -1;
+ for (size_t i = 0; i <= subjectLength - targetLength; ++i) {
+ bool match = true;
+ for (size_t j = 0; j < targetLength; ++j) {
+ if (subject[i + j] != target[j]) {
+ match = false;
+ break;
+ }
+ }
+ if (match)
+ return i;
+ }
+ return -1;
+}
+
+static WTF::TextEncoding findTextEncoding(const char* encodingName, int length)
+{
+ Vector<char, 64> buffer(length + 1);
+ memcpy(buffer.data(), encodingName, length);
+ buffer[length] = '\0';
+ return buffer.data();
+}
+
+TextResourceDecoder::ContentType TextResourceDecoder::determineContentType(const String& mimeType)
+{
+ if (equalIgnoringCase(mimeType, "text/css"))
+ return CSSContent;
+ if (equalIgnoringCase(mimeType, "text/html"))
+ return HTMLContent;
+ if (DOMImplementation::isXMLMIMEType(mimeType))
+ return XMLContent;
+ return PlainTextContent;
+}
+
+const WTF::TextEncoding& TextResourceDecoder::defaultEncoding(ContentType contentType, const WTF::TextEncoding& specifiedDefaultEncoding)
+{
+ // Despite 8.5 "Text/xml with Omitted Charset" of RFC 3023, we assume UTF-8 instead of US-ASCII
+ // for text/xml. This matches Firefox.
+ if (contentType == XMLContent)
+ return UTF8Encoding();
+ if (!specifiedDefaultEncoding.isValid())
+ return Latin1Encoding();
+ return specifiedDefaultEncoding;
+}
+
+TextResourceDecoder::TextResourceDecoder(const String& mimeType, const WTF::TextEncoding& specifiedDefaultEncoding, bool usesEncodingDetector)
+ : m_contentType(determineContentType(mimeType))
+ , m_encoding(defaultEncoding(m_contentType, specifiedDefaultEncoding))
+ , m_source(DefaultEncoding)
+ , m_hintEncoding(0)
+ , m_checkedForBOM(false)
+ , m_checkedForCSSCharset(false)
+ , m_checkedForXMLCharset(false)
+ , m_checkedForMetaCharset(false)
+ , m_useLenientXMLDecoding(false)
+ , m_sawError(false)
+ , m_usesEncodingDetector(usesEncodingDetector)
+{
+}
+
+TextResourceDecoder::~TextResourceDecoder()
+{
+}
+
+void TextResourceDecoder::setEncoding(const WTF::TextEncoding& encoding, EncodingSource source)
+{
+ // In case the encoding didn't exist, we keep the old one (helps some sites specifying invalid encodings).
+ if (!encoding.isValid())
+ return;
+
+ // When encoding comes from meta tag (i.e. it cannot be XML files sent via XHR),
+ // treat x-user-defined as windows-1252 (bug 18270)
+ if (source == EncodingFromMetaTag && !strcasecmp(encoding.name(), "x-user-defined"))
+ m_encoding = "windows-1252";
+ else if (source == EncodingFromMetaTag || source == EncodingFromXMLHeader || source == EncodingFromCSSCharset)
+ m_encoding = encoding.closestByteBasedEquivalent();
+ else
+ m_encoding = encoding;
+
+ m_codec.clear();
+ m_source = source;
+}
+
+// Returns the position of the encoding string.
+static int findXMLEncoding(const char* str, int len, int& encodingLength)
+{
+ int pos = find(str, len, "encoding");
+ if (pos == -1)
+ return -1;
+ pos += 8;
+
+ // Skip spaces and stray control characters.
+ while (pos < len && str[pos] <= ' ')
+ ++pos;
+
+ // Skip equals sign.
+ if (pos >= len || str[pos] != '=')
+ return -1;
+ ++pos;
+
+ // Skip spaces and stray control characters.
+ while (pos < len && str[pos] <= ' ')
+ ++pos;
+
+ // Skip quotation mark.
+ if (pos >= len)
+ return - 1;
+ char quoteMark = str[pos];
+ if (quoteMark != '"' && quoteMark != '\'')
+ return -1;
+ ++pos;
+
+ // Find the trailing quotation mark.
+ int end = pos;
+ while (end < len && str[end] != quoteMark)
+ ++end;
+ if (end >= len)
+ return -1;
+
+ encodingLength = end - pos;
+ return pos;
+}
+
+size_t TextResourceDecoder::checkForBOM(const char* data, size_t len)
+{
+ // Check for UTF-16/32 or UTF-8 BOM mark at the beginning, which is a sure sign of a Unicode encoding.
+ // We let it override even a user-chosen encoding.
+ ASSERT(!m_checkedForBOM);
+
+ size_t lengthOfBOM = 0;
+
+ size_t bufferLength = m_buffer.size();
+
+ size_t buf1Len = bufferLength;
+ size_t buf2Len = len;
+ const unsigned char* buf1 = reinterpret_cast<const unsigned char*>(m_buffer.data());
+ const unsigned char* buf2 = reinterpret_cast<const unsigned char*>(data);
+ unsigned char c1 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c2 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c3 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c4 = buf2Len ? (--buf2Len, *buf2++) : 0;
+
+ // Check for the BOM.
+ if (c1 == 0xFF && c2 == 0xFE) {
+ if (c3 || c4) {
+ setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 2;
+ } else {
+ setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 4;
+ }
+ } else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) {
+ setEncoding(UTF8Encoding(), AutoDetectedEncoding);
+ lengthOfBOM = 3;
+ } else if (c1 == 0xFE && c2 == 0xFF) {
+ setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 2;
+ } else if (!c1 && !c2 && c3 == 0xFE && c4 == 0xFF) {
+ setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 4;
+ }
+
+ if (lengthOfBOM || bufferLength + len >= 4)
+ m_checkedForBOM = true;
+
+ return lengthOfBOM;
+}
+
+bool TextResourceDecoder::checkForCSSCharset(const char* data, size_t len, bool& movedDataToBuffer)
+{
+ if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
+ m_checkedForCSSCharset = true;
+ return true;
+ }
+
+ size_t oldSize = m_buffer.size();
+ m_buffer.grow(oldSize + len);
+ memcpy(m_buffer.data() + oldSize, data, len);
+
+ movedDataToBuffer = true;
+
+ if (m_buffer.size() <= 13) // strlen('@charset "x";') == 13
+ return false;
+
+ const char* dataStart = m_buffer.data();
+ const char* dataEnd = dataStart + m_buffer.size();
+
+ if (bytesEqual(dataStart, '@', 'c', 'h', 'a', 'r', 's', 'e', 't', ' ', '"')) {
+ dataStart += 10;
+ const char* pos = dataStart;
+
+ while (pos < dataEnd && *pos != '"')
+ ++pos;
+ if (pos == dataEnd)
+ return false;
+
+ int encodingNameLength = pos - dataStart;
+
+ ++pos;
+ if (pos == dataEnd)
+ return false;
+
+ if (*pos == ';')
+ setEncoding(findTextEncoding(dataStart, encodingNameLength), EncodingFromCSSCharset);
+ }
+
+ m_checkedForCSSCharset = true;
+ return true;
+}
+
+bool TextResourceDecoder::checkForXMLCharset(const char* data, size_t len, bool& movedDataToBuffer)
+{
+ if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
+ m_checkedForXMLCharset = true;
+ return true;
+ }
+
+ // This is not completely efficient, since the function might go
+ // through the HTML head several times.
+
+ size_t oldSize = m_buffer.size();
+ m_buffer.grow(oldSize + len);
+ memcpy(m_buffer.data() + oldSize, data, len);
+
+ movedDataToBuffer = true;
+
+ const char* ptr = m_buffer.data();
+ const char* pEnd = ptr + m_buffer.size();
+
+ // Is there enough data available to check for XML declaration?
+ if (m_buffer.size() < 8)
+ return false;
+
+ // Handle XML declaration, which can have encoding in it. This encoding is honored even for HTML documents.
+ // It is an error for an XML declaration not to be at the start of an XML document, and it is ignored in HTML documents in such case.
+ if (bytesEqual(ptr, '<', '?', 'x', 'm', 'l')) {
+ const char* xmlDeclarationEnd = ptr;
+ while (xmlDeclarationEnd != pEnd && *xmlDeclarationEnd != '>')
+ ++xmlDeclarationEnd;
+ if (xmlDeclarationEnd == pEnd)
+ return false;
+ // No need for +1, because we have an extra "?" to lose at the end of XML declaration.
+ int len = 0;
+ int pos = findXMLEncoding(ptr, xmlDeclarationEnd - ptr, len);
+ if (pos != -1)
+ setEncoding(findTextEncoding(ptr + pos, len), EncodingFromXMLHeader);
+ // continue looking for a charset - it may be specified in an HTTP-Equiv meta
+ } else if (bytesEqual(ptr, '<', 0, '?', 0, 'x', 0)) {
+ setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
+ } else if (bytesEqual(ptr, 0, '<', 0, '?', 0, 'x')) {
+ setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
+ } else if (bytesEqual(ptr, '<', 0, 0, 0, '?', 0, 0, 0)) {
+ setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
+ } else if (bytesEqual(ptr, 0, 0, 0, '<', 0, 0, 0, '?')) {
+ setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
+ }
+
+ m_checkedForXMLCharset = true;
+ return true;
+}
+
+void TextResourceDecoder::checkForMetaCharset(const char* data, size_t length)
+{
+ if (m_source == UserChosenEncoding || m_source == EncodingFromHTTPHeader || m_source == AutoDetectedEncoding) {
+ m_checkedForMetaCharset = true;
+ return;
+ }
+
+ if (!m_charsetParser)
+ m_charsetParser = HTMLMetaCharsetParser::create();
+
+ if (!m_charsetParser->checkForMetaCharset(data, length))
+ return;
+
+ setEncoding(m_charsetParser->encoding(), EncodingFromMetaTag);
+ m_charsetParser.clear();
+ m_checkedForMetaCharset = true;
+ return;
+}
+
+// We use the encoding detector in two cases:
+// 1. Encoding detector is turned ON and no other encoding source is
+// available (that is, it's DefaultEncoding).
+// 2. Encoding detector is turned ON and the encoding is set to
+// the encoding of the parent frame, which is also auto-detected.
+// Note that condition #2 is NOT satisfied unless parent-child frame
+// relationship is compliant to the same-origin policy. If they're from
+// different domains, |m_source| would not be set to EncodingFromParentFrame
+// in the first place.
+bool TextResourceDecoder::shouldAutoDetect() const
+{
+ // Just checking m_hintEncoding suffices here because it's only set
+ // in setHintEncoding when the source is AutoDetectedEncoding.
+ return m_usesEncodingDetector
+ && (m_source == DefaultEncoding || (m_source == EncodingFromParentFrame && m_hintEncoding));
+}
+
+String TextResourceDecoder::decode(const char* data, size_t len)
+{
+ size_t lengthOfBOM = 0;
+ if (!m_checkedForBOM)
+ lengthOfBOM = checkForBOM(data, len);
+
+ bool movedDataToBuffer = false;
+
+ if (m_contentType == CSSContent && !m_checkedForCSSCharset) {
+ if (!checkForCSSCharset(data, len, movedDataToBuffer))
+ return emptyString();
+ }
+
+ if ((m_contentType == HTMLContent || m_contentType == XMLContent) && !m_checkedForXMLCharset) {
+ if (!checkForXMLCharset(data, len, movedDataToBuffer))
+ return emptyString();
+ }
+
+ const char* dataForDecode = data + lengthOfBOM;
+ size_t lengthForDecode = len - lengthOfBOM;
+
+ if (!m_buffer.isEmpty()) {
+ if (!movedDataToBuffer) {
+ size_t oldSize = m_buffer.size();
+ m_buffer.grow(oldSize + len);
+ memcpy(m_buffer.data() + oldSize, data, len);
+ }
+
+ dataForDecode = m_buffer.data() + lengthOfBOM;
+ lengthForDecode = m_buffer.size() - lengthOfBOM;
+ }
+
+ if (m_contentType == HTMLContent && !m_checkedForMetaCharset)
+ checkForMetaCharset(dataForDecode, lengthForDecode);
+
+ if (shouldAutoDetect()) {
+ WTF::TextEncoding detectedEncoding;
+ if (detectTextEncoding(data, len, m_hintEncoding, &detectedEncoding))
+ setEncoding(detectedEncoding, EncodingFromContentSniffing);
+ }
+
+ ASSERT(m_encoding.isValid());
+
+ if (!m_codec)
+ m_codec = newTextCodec(m_encoding);
+
+ String result = m_codec->decode(dataForDecode, lengthForDecode, DoNotFlush, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
+
+ m_buffer.clear();
+ return result;
+}
+
+String TextResourceDecoder::flush()
+{
+ // If we can not identify the encoding even after a document is completely
+ // loaded, we need to detect the encoding if other conditions for
+ // autodetection is satisfied.
+ if (m_buffer.size() && shouldAutoDetect()
+ && ((!m_checkedForXMLCharset && (m_contentType == HTMLContent || m_contentType == XMLContent)) || (!m_checkedForCSSCharset && (m_contentType == CSSContent)))) {
+ WTF::TextEncoding detectedEncoding;
+ if (detectTextEncoding(m_buffer.data(), m_buffer.size(), m_hintEncoding, &detectedEncoding))
+ setEncoding(detectedEncoding, EncodingFromContentSniffing);
+ }
+
+ if (!m_codec)
+ m_codec = newTextCodec(m_encoding);
+
+ String result = m_codec->decode(m_buffer.data(), m_buffer.size(), FetchEOF, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
+ m_buffer.clear();
+ m_codec.clear();
+ m_checkedForBOM = false; // Skip BOM again when re-decoding.
+ return result;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h
new file mode 100644
index 00000000000..5ad2ad561f8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
+ Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ Copyright (C) 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 TextResourceDecoder_h
+#define TextResourceDecoder_h
+
+#include "wtf/RefCounted.h"
+#include "wtf/text/TextEncoding.h"
+
+namespace WebCore {
+
+class DocumentEncodingData;
+class HTMLMetaCharsetParser;
+
+class TextResourceDecoder {
+public:
+ enum EncodingSource {
+ DefaultEncoding,
+ AutoDetectedEncoding,
+ EncodingFromContentSniffing,
+ EncodingFromXMLHeader,
+ EncodingFromMetaTag,
+ EncodingFromCSSCharset,
+ EncodingFromHTTPHeader,
+ UserChosenEncoding,
+ EncodingFromParentFrame
+ };
+
+ static PassOwnPtr<TextResourceDecoder> create(const String& mimeType, const WTF::TextEncoding& defaultEncoding = WTF::TextEncoding(), bool usesEncodingDetector = false)
+ {
+ return adoptPtr(new TextResourceDecoder(mimeType, defaultEncoding, usesEncodingDetector));
+ }
+ ~TextResourceDecoder();
+
+ void setEncoding(const WTF::TextEncoding&, EncodingSource);
+ const WTF::TextEncoding& encoding() const { return m_encoding; }
+ bool encodingWasDetectedHeuristically() const
+ {
+ return m_source == AutoDetectedEncoding
+ || m_source == EncodingFromContentSniffing;
+ }
+
+ String decode(const char* data, size_t length);
+ String flush();
+
+ void setHintEncoding(const WTF::TextEncoding& encoding)
+ {
+ m_hintEncoding = encoding.name();
+ }
+
+ void useLenientXMLDecoding() { m_useLenientXMLDecoding = true; }
+ bool sawError() const { return m_sawError; }
+
+private:
+ TextResourceDecoder(const String& mimeType, const WTF::TextEncoding& defaultEncoding, bool usesEncodingDetector);
+
+ enum ContentType { PlainTextContent, HTMLContent, XMLContent, CSSContent }; // PlainText only checks for BOM.
+ static ContentType determineContentType(const String& mimeType);
+ static const WTF::TextEncoding& defaultEncoding(ContentType, const WTF::TextEncoding& defaultEncoding);
+
+ size_t checkForBOM(const char*, size_t);
+ bool checkForCSSCharset(const char*, size_t, bool& movedDataToBuffer);
+ bool checkForXMLCharset(const char*, size_t, bool& movedDataToBuffer);
+ void checkForMetaCharset(const char*, size_t);
+ void detectJapaneseEncoding(const char*, size_t);
+ bool shouldAutoDetect() const;
+
+ ContentType m_contentType;
+ WTF::TextEncoding m_encoding;
+ OwnPtr<TextCodec> m_codec;
+ EncodingSource m_source;
+ const char* m_hintEncoding;
+ Vector<char> m_buffer;
+ bool m_checkedForBOM;
+ bool m_checkedForCSSCharset;
+ bool m_checkedForXMLCharset;
+ bool m_checkedForMetaCharset;
+ bool m_useLenientXMLDecoding; // Don't stop on XML decoding errors.
+ bool m_sawError;
+ bool m_usesEncodingDetector;
+
+ OwnPtr<HTMLMetaCharsetParser> m_charsetParser;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
index a43fca982b5..5189447af88 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
@@ -27,22 +27,23 @@
#include "config.h"
#include "core/html/parser/XSSAuditor.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLParamElement.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "core/loader/DocumentLoader.h"
#include "core/frame/Settings.h"
#include "platform/JSONValues.h"
#include "platform/network/FormData.h"
#include "platform/text/DecodeEscapeSequences.h"
+#include "wtf/ASCIICType.h"
#include "wtf/MainThread.h"
namespace {
@@ -63,14 +64,11 @@ static bool isNonCanonicalCharacter(UChar c)
// Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character.
// Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the
// adverse effect that we remove any legitimate zeros from a string.
+ // We also remove forward-slash, because it is common for some servers to collapse successive path components, eg,
+ // a//b becomes a/b.
//
- // For instance: new String("http://localhost:8000") => new String("http://localhost:8").
- return (c == '\\' || c == '0' || c == '\0' || c >= 127);
-}
-
-static String canonicalize(const String& string)
-{
- return string.removeCharacters(&isNonCanonicalCharacter);
+ // For instance: new String("http://localhost:8000") => new String("http:localhost:8").
+ return (c == '\\' || c == '0' || c == '\0' || c == '/' || c >= 127);
}
static bool isRequiredForInjection(UChar c)
@@ -96,17 +94,28 @@ static bool isJSNewline(UChar c)
static bool startsHTMLCommentAt(const String& string, size_t start)
{
- return (start + 3 < string.length() && string[start] == '<' && string[start+1] == '!' && string[start+2] == '-' && string[start+3] == '-');
+ return (start + 3 < string.length() && string[start] == '<' && string[start + 1] == '!' && string[start + 2] == '-' && string[start + 3] == '-');
}
static bool startsSingleLineCommentAt(const String& string, size_t start)
{
- return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '/');
+ return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '/');
}
static bool startsMultiLineCommentAt(const String& string, size_t start)
{
- return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '*');
+ return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '*');
+}
+
+static bool startsOpeningScriptTagAt(const String& string, size_t start)
+{
+ return start + 6 < string.length() && string[start] == '<'
+ && WTF::toASCIILowerUnchecked(string[start + 1]) == 's'
+ && WTF::toASCIILowerUnchecked(string[start + 2]) == 'c'
+ && WTF::toASCIILowerUnchecked(string[start + 3]) == 'r'
+ && WTF::toASCIILowerUnchecked(string[start + 4]) == 'i'
+ && WTF::toASCIILowerUnchecked(string[start + 5]) == 'p'
+ && WTF::toASCIILowerUnchecked(string[start + 6]) == 't';
}
// If other files need this, we should move this to core/html/parser/HTMLParserIdioms.h
@@ -171,10 +180,60 @@ static String fullyDecodeString(const String& string, const WTF::TextEncoding& e
workingString = decode16BitUnicodeEscapeSequences(decodeStandardURLEscapeSequences(workingString, encoding));
} while (workingString.length() < oldWorkingStringLength);
workingString.replace('+', ' ');
- workingString = canonicalize(workingString);
return workingString;
}
+static void truncateForSrcLikeAttribute(String& decodedSnippet)
+{
+ // In HTTP URLs, characters following the first ?, #, or third slash may come from
+ // the page itself and can be merely ignored by an attacker's server when a remote
+ // script or script-like resource is requested. In DATA URLS, the payload starts at
+ // the first comma, and the the first /*, //, or <!-- may introduce a comment. Characters
+ // following this may come from the page itself and may be ignored when the script is
+ // executed. For simplicity, we don't differentiate based on URL scheme, and stop at
+ // the first # or ?, the third slash, or the first slash or < once a comma is seen.
+ int slashCount = 0;
+ bool commaSeen = false;
+ for (size_t currentLength = 0; currentLength < decodedSnippet.length(); ++currentLength) {
+ UChar currentChar = decodedSnippet[currentLength];
+ if (currentChar == '?'
+ || currentChar == '#'
+ || ((currentChar == '/' || currentChar == '\\') && (commaSeen || ++slashCount > 2))
+ || (currentChar == '<' && commaSeen)) {
+ decodedSnippet.truncate(currentLength);
+ return;
+ }
+ if (currentChar == ',')
+ commaSeen = true;
+ }
+}
+
+static void truncateForScriptLikeAttribute(String& decodedSnippet)
+{
+ // Beware of trailing characters which came from the page itself, not the
+ // injected vector. Excluding the terminating character covers common cases
+ // where the page immediately ends the attribute, but doesn't cover more
+ // complex cases where there is other page data following the injection.
+ // Generally, these won't parse as javascript, so the injected vector
+ // typically excludes them from consideration via a single-line comment or
+ // by enclosing them in a string literal terminated later by the page's own
+ // closing punctuation. Since the snippet has not been parsed, the vector
+ // may also try to introduce these via entities. As a result, we'd like to
+ // stop before the first "//", the first <!--, the first entity, or the first
+ // quote not immediately following the first equals sign (taking whitespace
+ // into consideration). To keep things simpler, we don't try to distinguish
+ // between entity-introducing amperands vs. other uses, nor do we bother to
+ // check for a second slash for a comment, nor do we bother to check for
+ // !-- following a less-than sign. We stop instead on any ampersand
+ // slash, or less-than sign.
+ size_t position = 0;
+ if ((position = decodedSnippet.find("=")) != kNotFound
+ && (position = decodedSnippet.find(isNotHTMLSpace<UChar>, position + 1)) != kNotFound
+ && (position = decodedSnippet.find(isTerminatingCharacter, isHTMLQuote(decodedSnippet[position]) ? position + 1 : position)) != kNotFound) {
+ decodedSnippet.truncate(position);
+ }
+}
+
static ReflectedXSSDisposition combineXSSProtectionHeaderAndCSP(ReflectedXSSDisposition xssProtection, ReflectedXSSDisposition reflectedXSS)
{
ReflectedXSSDisposition result = std::max(xssProtection, reflectedXSS);
@@ -190,15 +249,16 @@ static bool isSemicolonSeparatedAttribute(const HTMLToken::Attribute& attribute)
return threadSafeMatch(attribute.name, SVGNames::valuesAttr);
}
-static bool semicolonSeparatedValueContainsJavaScriptURL(const String& value)
+static String semicolonSeparatedValueContainingJavaScriptURL(const String& value)
{
Vector<String> valueList;
value.split(';', valueList);
for (size_t i = 0; i < valueList.size(); ++i) {
- if (protocolIsJavaScript(valueList[i]))
- return true;
+ String stripped = stripLeadingAndTrailingHTMLSpaces(valueList[i]);
+ if (protocolIsJavaScript(stripped))
+ return stripped;
}
- return false;
+ return emptyString();
}
XSSAuditor::XSSAuditor()
@@ -227,9 +287,6 @@ void XSSAuditor::initForFragment()
void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
{
- const size_t miniumLengthForSuffixTree = 512; // FIXME: Tune this parameter.
- const int suffixTreeDepth = 5;
-
ASSERT(isMainThread());
if (m_state != Uninitialized)
return;
@@ -243,7 +300,7 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
m_documentURL = document->url().copy();
- // In theory, the Document could have detached from the Frame after the
+ // In theory, the Document could have detached from the LocalFrame after the
// XSSAuditor was constructed.
if (!document->frame()) {
m_isEnabled = false;
@@ -264,11 +321,6 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
if (document->encoding().isValid())
m_encoding = document->encoding();
- m_decodedURL = fullyDecodeString(m_documentURL.string(), m_encoding);
- if (m_decodedURL.find(isRequiredForInjection) == kNotFound)
- m_decodedURL = String();
-
- String httpBodyAsString;
if (DocumentLoader* documentLoader = document->frame()->loader().documentLoader()) {
DEFINE_STATIC_LOCAL(const AtomicString, XSSProtectionHeader, ("X-XSS-Protection", AtomicString::ConstructFromLiteral));
const AtomicString& headerValue = documentLoader->response().httpHeaderField(XSSProtectionHeader);
@@ -298,23 +350,40 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
// FIXME: Combine the two report URLs in some reasonable way.
if (auditorDelegate)
auditorDelegate->setReportURL(xssProtectionReportURL.copy());
+
FormData* httpBody = documentLoader->request().httpBody();
- if (httpBody && !httpBody->isEmpty()) {
- httpBodyAsString = httpBody->flattenToString();
- if (!httpBodyAsString.isEmpty()) {
- m_decodedHTTPBody = fullyDecodeString(httpBodyAsString, m_encoding);
- if (m_decodedHTTPBody.find(isRequiredForInjection) == kNotFound)
- m_decodedHTTPBody = String();
- if (m_decodedHTTPBody.length() >= miniumLengthForSuffixTree)
- m_decodedHTTPBodySuffixTree = adoptPtr(new SuffixTree<ASCIICodebook>(m_decodedHTTPBody, suffixTreeDepth));
- }
- }
+ if (httpBody && !httpBody->isEmpty())
+ m_httpBodyAsString = httpBody->flattenToString();
}
- if (m_decodedURL.isEmpty() && m_decodedHTTPBody.isEmpty()) {
- m_isEnabled = false;
+ setEncoding(m_encoding);
+}
+
+void XSSAuditor::setEncoding(const WTF::TextEncoding& encoding)
+{
+ const size_t miniumLengthForSuffixTree = 512; // FIXME: Tune this parameter.
+ const int suffixTreeDepth = 5;
+
+ if (!encoding.isValid())
return;
+
+ m_encoding = encoding;
+
+ m_decodedURL = canonicalize(m_documentURL.string(), NoTruncation);
+ if (m_decodedURL.find(isRequiredForInjection) == kNotFound)
+ m_decodedURL = String();
+
+ if (!m_httpBodyAsString.isEmpty()) {
+ m_decodedHTTPBody = canonicalize(m_httpBodyAsString, NoTruncation);
+ m_httpBodyAsString = String();
+ if (m_decodedHTTPBody.find(isRequiredForInjection) == kNotFound)
+ m_decodedHTTPBody = String();
+ if (m_decodedHTTPBody.length() >= miniumLengthForSuffixTree)
+ m_decodedHTTPBodySuffixTree = adoptPtr(new SuffixTree<ASCIICodebook>(m_decodedHTTPBody, suffixTreeDepth));
}
+
+ if (m_decodedURL.isEmpty() && m_decodedHTTPBody.isEmpty())
+ m_isEnabled = false;
}
PassOwnPtr<XSSInfo> XSSAuditor::filterToken(const FilterTokenRequest& request)
@@ -392,7 +461,7 @@ bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request)
return false;
if ((m_state == SuppressingAdjacentCharacterTokens)
- || (m_scriptTagFoundInRequest && isContainedInRequest(decodedSnippetForJavaScript(request)))) {
+ || (m_scriptTagFoundInRequest && isContainedInRequest(canonicalizedSnippetForJavaScript(request)))) {
request.token.eraseCharacters();
request.token.appendToCharacter(' '); // Technically, character tokens can't be empty.
m_state = SuppressingAdjacentCharacterTokens;
@@ -409,10 +478,10 @@ bool XSSAuditor::filterScriptToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, scriptTag));
bool didBlockScript = false;
- m_scriptTagFoundInRequest = isContainedInRequest(decodedSnippetForName(request));
+ m_scriptTagFoundInRequest = isContainedInRequest(canonicalizedSnippetForTagName(request));
if (m_scriptTagFoundInRequest) {
- didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttribute);
- didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr, blankURL().string(), SrcLikeAttribute);
+ didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttributeTruncation);
+ didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr, blankURL().string(), SrcLikeAttributeTruncation);
}
return didBlockScript;
}
@@ -423,8 +492,8 @@ bool XSSAuditor::filterObjectToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, objectTag));
bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
- didBlockScript |= eraseAttributeIfInjected(request, dataAttr, blankURL().string(), SrcLikeAttribute);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request))) {
+ didBlockScript |= eraseAttributeIfInjected(request, dataAttr, blankURL().string(), SrcLikeAttributeTruncation);
didBlockScript |= eraseAttributeIfInjected(request, typeAttr);
didBlockScript |= eraseAttributeIfInjected(request, classidAttr);
}
@@ -444,7 +513,7 @@ bool XSSAuditor::filterParamToken(const FilterTokenRequest& request)
if (!HTMLParamElement::isURLParameter(String(nameAttribute.value)))
return false;
- return eraseAttributeIfInjected(request, valueAttr, blankURL().string(), SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, valueAttr, blankURL().string(), SrcLikeAttributeTruncation);
}
bool XSSAuditor::filterEmbedToken(const FilterTokenRequest& request)
@@ -453,9 +522,9 @@ bool XSSAuditor::filterEmbedToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, embedTag));
bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
- didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttribute);
- didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttribute);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request))) {
+ didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttributeTruncation);
+ didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttributeTruncation);
didBlockScript |= eraseAttributeIfInjected(request, typeAttr);
}
return didBlockScript;
@@ -467,8 +536,8 @@ bool XSSAuditor::filterAppletToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, appletTag));
bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
- didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttribute);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request))) {
+ didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttributeTruncation);
didBlockScript |= eraseAttributeIfInjected(request, objectAttr);
}
return didBlockScript;
@@ -479,9 +548,9 @@ bool XSSAuditor::filterFrameToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, iframeTag) || hasName(request.token, frameTag));
- bool didBlockScript = eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttribute);
- if (isContainedInRequest(decodedSnippetForName(request)))
- didBlockScript |= eraseAttributeIfInjected(request, srcAttr, String(), SrcLikeAttribute);
+ bool didBlockScript = eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttributeTruncation);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request)))
+ didBlockScript |= eraseAttributeIfInjected(request, srcAttr, String(), SrcLikeAttributeTruncation);
return didBlockScript;
}
@@ -515,7 +584,7 @@ bool XSSAuditor::filterInputToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, inputTag));
- return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttributeTruncation);
}
bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
@@ -523,7 +592,7 @@ bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, buttonTag));
- return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttributeTruncation);
}
bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& request)
@@ -532,14 +601,24 @@ bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
bool didBlockScript = false;
for (size_t i = 0; i < request.token.attributes().size(); ++i) {
+ bool eraseAttribute = false;
+ bool valueContainsJavaScriptURL = false;
const HTMLToken::Attribute& attribute = request.token.attributes().at(i);
- bool isInlineEventHandler = isNameOfInlineEventHandler(attribute.name);
- // FIXME: It would be better if we didn't create a new String for every attribute in the document.
- String strippedValue = stripLeadingAndTrailingHTMLSpaces(String(attribute.value));
- bool valueContainsJavaScriptURL = (!isInlineEventHandler && protocolIsJavaScript(strippedValue)) || (isSemicolonSeparatedAttribute(attribute) && semicolonSeparatedValueContainsJavaScriptURL(strippedValue));
- if (!isInlineEventHandler && !valueContainsJavaScriptURL)
- continue;
- if (!isContainedInRequest(decodedSnippetForAttribute(request, attribute, ScriptLikeAttribute)))
+ // FIXME: Don't create a new String for every attribute.value in the document.
+ if (isNameOfInlineEventHandler(attribute.name)) {
+ eraseAttribute = isContainedInRequest(canonicalize(snippetFromAttribute(request, attribute), ScriptLikeAttributeTruncation));
+ } else if (isSemicolonSeparatedAttribute(attribute)) {
+ String subValue = semicolonSeparatedValueContainingJavaScriptURL(String(attribute.value));
+ if (!subValue.isEmpty()) {
+ valueContainsJavaScriptURL = true;
+ eraseAttribute = isContainedInRequest(canonicalize(nameFromAttribute(request, attribute), NoTruncation))
+ && isContainedInRequest(canonicalize(subValue, ScriptLikeAttributeTruncation));
+ }
+ } else if (protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(String(attribute.value)))) {
+ valueContainsJavaScriptURL = true;
+ eraseAttribute = isContainedInRequest(canonicalize(snippetFromAttribute(request, attribute), ScriptLikeAttributeTruncation));
+ }
+ if (!eraseAttribute)
continue;
request.token.eraseValueOfAttribute(i);
if (valueContainsJavaScriptURL)
@@ -549,96 +628,79 @@ bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
return didBlockScript;
}
-bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, const QualifiedName& attributeName, const String& replacementValue, AttributeKind treatment)
+bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, const QualifiedName& attributeName, const String& replacementValue, TruncationKind treatment)
{
size_t indexOfAttribute = 0;
- if (findAttributeWithName(request.token, attributeName, indexOfAttribute)) {
- const HTMLToken::Attribute& attribute = request.token.attributes().at(indexOfAttribute);
- if (isContainedInRequest(decodedSnippetForAttribute(request, attribute, treatment))) {
- if (threadSafeMatch(attributeName, srcAttr) && isLikelySafeResource(String(attribute.value)))
- return false;
- if (threadSafeMatch(attributeName, http_equivAttr) && !isDangerousHTTPEquiv(String(attribute.value)))
- return false;
- request.token.eraseValueOfAttribute(indexOfAttribute);
- if (!replacementValue.isEmpty())
- request.token.appendToAttributeValue(indexOfAttribute, replacementValue);
- return true;
- }
+ if (!findAttributeWithName(request.token, attributeName, indexOfAttribute))
+ return false;
+
+ const HTMLToken::Attribute& attribute = request.token.attributes().at(indexOfAttribute);
+ if (!isContainedInRequest(canonicalize(snippetFromAttribute(request, attribute), treatment)))
+ return false;
+
+ if (threadSafeMatch(attributeName, srcAttr)) {
+ if (isLikelySafeResource(String(attribute.value)))
+ return false;
+ } else if (threadSafeMatch(attributeName, http_equivAttr)) {
+ if (!isDangerousHTTPEquiv(String(attribute.value)))
+ return false;
}
- return false;
+
+ request.token.eraseValueOfAttribute(indexOfAttribute);
+ if (!replacementValue.isEmpty())
+ request.token.appendToAttributeValue(indexOfAttribute, replacementValue);
+
+ return true;
}
-String XSSAuditor::decodedSnippetForName(const FilterTokenRequest& request)
+String XSSAuditor::canonicalizedSnippetForTagName(const FilterTokenRequest& request)
{
// Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
- return fullyDecodeString(request.sourceTracker.sourceForToken(request.token), m_encoding).substring(0, request.token.name().size() + 1);
+ return canonicalize(request.sourceTracker.sourceForToken(request.token).substring(0, request.token.name().size() + 1), NoTruncation);
+}
+
+String XSSAuditor::nameFromAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute)
+{
+ // The range inlcudes the character which terminates the name. So,
+ // for an input of |name="value"|, the snippet is |name=|.
+ int start = attribute.nameRange.start - request.token.startIndex();
+ int end = attribute.valueRange.start - request.token.startIndex();
+ return request.sourceTracker.sourceForToken(request.token).substring(start, end - start);
}
-String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute, AttributeKind treatment)
+String XSSAuditor::snippetFromAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute)
{
- // The range doesn't inlcude the character which terminates the value. So,
+ // The range doesn't include the character which terminates the value. So,
// for an input of |name="value"|, the snippet is |name="value|. For an
// unquoted input of |name=value |, the snippet is |name=value|.
// FIXME: We should grab one character before the name also.
int start = attribute.nameRange.start - request.token.startIndex();
int end = attribute.valueRange.end - request.token.startIndex();
- String decodedSnippet = fullyDecodeString(request.sourceTracker.sourceForToken(request.token).substring(start, end - start), m_encoding);
- decodedSnippet.truncate(kMaximumFragmentLengthTarget);
- if (treatment == SrcLikeAttribute) {
- int slashCount = 0;
- bool commaSeen = false;
- // In HTTP URLs, characters following the first ?, #, or third slash may come from
- // the page itself and can be merely ignored by an attacker's server when a remote
- // script or script-like resource is requested. In DATA URLS, the payload starts at
- // the first comma, and the the first /*, //, or <!-- may introduce a comment. Characters
- // following this may come from the page itself and may be ignored when the script is
- // executed. For simplicity, we don't differentiate based on URL scheme, and stop at
- // the first # or ?, the third slash, or the first slash or < once a comma is seen.
- for (size_t currentLength = 0; currentLength < decodedSnippet.length(); ++currentLength) {
- UChar currentChar = decodedSnippet[currentLength];
- if (currentChar == '?'
- || currentChar == '#'
- || ((currentChar == '/' || currentChar == '\\') && (commaSeen || ++slashCount > 2))
- || (currentChar == '<' && commaSeen)) {
- decodedSnippet.truncate(currentLength);
- break;
- }
- if (currentChar == ',')
- commaSeen = true;
- }
- } else if (treatment == ScriptLikeAttribute) {
- // Beware of trailing characters which came from the page itself, not the
- // injected vector. Excluding the terminating character covers common cases
- // where the page immediately ends the attribute, but doesn't cover more
- // complex cases where there is other page data following the injection.
- // Generally, these won't parse as javascript, so the injected vector
- // typically excludes them from consideration via a single-line comment or
- // by enclosing them in a string literal terminated later by the page's own
- // closing punctuation. Since the snippet has not been parsed, the vector
- // may also try to introduce these via entities. As a result, we'd like to
- // stop before the first "//", the first <!--, the first entity, or the first
- // quote not immediately following the first equals sign (taking whitespace
- // into consideration). To keep things simpler, we don't try to distinguish
- // between entity-introducing amperands vs. other uses, nor do we bother to
- // check for a second slash for a comment, nor do we bother to check for
- // !-- following a less-than sign. We stop instead on any ampersand
- // slash, or less-than sign.
- size_t position = 0;
- if ((position = decodedSnippet.find("=")) != kNotFound
- && (position = decodedSnippet.find(isNotHTMLSpace<UChar>, position + 1)) != kNotFound
- && (position = decodedSnippet.find(isTerminatingCharacter, isHTMLQuote(decodedSnippet[position]) ? position + 1 : position)) != kNotFound) {
- decodedSnippet.truncate(position);
- }
+ return request.sourceTracker.sourceForToken(request.token).substring(start, end - start);
+}
+
+String XSSAuditor::canonicalize(String snippet, TruncationKind treatment)
+{
+ String decodedSnippet = fullyDecodeString(snippet, m_encoding);
+
+ if (treatment != NoTruncation) {
+ decodedSnippet.truncate(kMaximumFragmentLengthTarget);
+ if (treatment == SrcLikeAttributeTruncation)
+ truncateForSrcLikeAttribute(decodedSnippet);
+ else if (treatment == ScriptLikeAttributeTruncation)
+ truncateForScriptLikeAttribute(decodedSnippet);
}
- return decodedSnippet;
+
+ return decodedSnippet.removeCharacters(&isNonCanonicalCharacter);
}
-String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request)
+String XSSAuditor::canonicalizedSnippetForJavaScript(const FilterTokenRequest& request)
{
String string = request.sourceTracker.sourceForToken(request.token);
size_t startPosition = 0;
size_t endPosition = string.length();
size_t foundPosition = kNotFound;
+ size_t lastNonSpacePosition = kNotFound;
// Skip over initial comments to find start of code.
while (startPosition < endPosition) {
@@ -667,32 +729,40 @@ String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request
String result;
while (startPosition < endPosition && !result.length()) {
- // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we
- // encounter a comma, or when we exceed the maximum length target. The comma rule
- // covers a common parameter concatenation case performed by some webservers.
- // After hitting the length target, we can only stop at a point where we know we are
- // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
- // not stopping inside a (possibly multiply encoded) %-esacpe sequence by breaking on
- // whitespace only. We should have enough text in these cases to avoid false positives.
+ // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we encounter a comma,
+ // when we hit an opening <script> tag, or when we exceed the maximum length target. The comma rule
+ // covers a common parameter concatenation case performed by some web servers.
+ lastNonSpacePosition = kNotFound;
for (foundPosition = startPosition; foundPosition < endPosition; foundPosition++) {
if (!request.shouldAllowCDATA) {
- if (startsSingleLineCommentAt(string, foundPosition) || startsMultiLineCommentAt(string, foundPosition)) {
- foundPosition += 2;
- break;
- }
- if (startsHTMLCommentAt(string, foundPosition)) {
- foundPosition += 4;
+ if (startsSingleLineCommentAt(string, foundPosition)
+ || startsMultiLineCommentAt(string, foundPosition)
+ || startsHTMLCommentAt(string, foundPosition)) {
break;
}
}
- if (string[foundPosition] == ',' || (foundPosition > startPosition + kMaximumFragmentLengthTarget && isHTMLSpace<UChar>(string[foundPosition]))) {
+ if (string[foundPosition] == ',')
+ break;
+
+ if (lastNonSpacePosition != kNotFound && startsOpeningScriptTagAt(string, foundPosition)) {
+ foundPosition = lastNonSpacePosition;
break;
}
+ if (foundPosition > startPosition + kMaximumFragmentLengthTarget) {
+ // After hitting the length target, we can only stop at a point where we know we are
+ // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
+ // not stopping inside a (possibly multiply encoded) %-escape sequence by breaking on
+ // whitespace only. We should have enough text in these cases to avoid false positives.
+ if (isHTMLSpace<UChar>(string[foundPosition]))
+ break;
+ }
+ if (!isHTMLSpace<UChar>(string[foundPosition]))
+ lastNonSpacePosition = foundPosition;
}
-
- result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding);
+ result = canonicalize(string.substring(startPosition, foundPosition - startPosition), NoTruncation);
startPosition = foundPosition + 1;
}
+
return result;
}
@@ -732,7 +802,8 @@ bool XSSAuditor::isSafeToSendToAnotherThread() const
{
return m_documentURL.isSafeToSendToAnotherThread()
&& m_decodedURL.isSafeToSendToAnotherThread()
- && m_decodedHTTPBody.isSafeToSendToAnotherThread();
+ && m_decodedHTTPBody.isSafeToSendToAnotherThread()
+ && m_httpBodyAsString.isSafeToSendToAnotherThread();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
index db2655f4a8a..53a38ac606d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
@@ -64,6 +64,8 @@ public:
PassOwnPtr<XSSInfo> filterToken(const FilterTokenRequest&);
bool isSafeToSendToAnotherThread() const;
+ void setEncoding(const WTF::TextEncoding&);
+
private:
static const size_t kMaximumFragmentLengthTarget = 100;
@@ -74,10 +76,11 @@ private:
SuppressingAdjacentCharacterTokens
};
- enum AttributeKind {
- NormalAttribute,
- SrcLikeAttribute,
- ScriptLikeAttribute
+ enum TruncationKind {
+ NoTruncation,
+ NormalAttributeTruncation,
+ SrcLikeAttributeTruncation,
+ ScriptLikeAttributeTruncation
};
bool filterStartToken(const FilterTokenRequest&);
@@ -96,12 +99,13 @@ private:
bool filterButtonToken(const FilterTokenRequest&);
bool eraseDangerousAttributesIfInjected(const FilterTokenRequest&);
- bool eraseAttributeIfInjected(const FilterTokenRequest&, const QualifiedName&, const String& replacementValue = String(), AttributeKind treatment = NormalAttribute);
+ bool eraseAttributeIfInjected(const FilterTokenRequest&, const QualifiedName&, const String& replacementValue = String(), TruncationKind treatment = NormalAttributeTruncation);
- String decodedSnippetForToken(const HTMLToken&);
- String decodedSnippetForName(const FilterTokenRequest&);
- String decodedSnippetForAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&, AttributeKind treatment = NormalAttribute);
- String decodedSnippetForJavaScript(const FilterTokenRequest&);
+ String canonicalizedSnippetForTagName(const FilterTokenRequest&);
+ String canonicalizedSnippetForJavaScript(const FilterTokenRequest&);
+ String nameFromAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&);
+ String snippetFromAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&);
+ String canonicalize(String, TruncationKind);
bool isContainedInRequest(const String&);
bool isLikelySafeResource(const String& url);
@@ -115,6 +119,7 @@ private:
String m_decodedURL;
String m_decodedHTTPBody;
+ String m_httpBodyAsString;
OwnPtr<SuffixTree<ASCIICodebook> > m_decodedHTTPBodySuffixTree;
State m_state;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
index 5ea9b66ccf7..9b329e85ccd 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
@@ -27,7 +27,7 @@
#include "core/html/parser/XSSAuditorDelegate.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
@@ -100,8 +100,8 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, xssInfo.buildConsoleError());
- // stopAllLoaders can detach the Frame, so protect it.
- RefPtr<Frame> protect(m_document->frame());
+ // stopAllLoaders can detach the LocalFrame, so protect it.
+ RefPtr<LocalFrame> protect(m_document->frame());
FrameLoader& frameLoader = m_document->frame()->loader();
if (xssInfo.m_didBlockEntirePage)
frameLoader.stopAllLoaders();
@@ -116,7 +116,7 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
}
if (xssInfo.m_didBlockEntirePage)
- m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+ m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), Referrer());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table b/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table
index 8c408fead9a..587e8a8f5d1 100755
--- a/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table
+++ b/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table
@@ -27,6 +27,11 @@
# (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 python script creates the raw data that is our entity
+database. The representation is one string database containing all
+strings we could need, and then a mapping from offset+length -> entity
+data. That is compact, easy to use and efficient."""
+
import csv
import os.path
import string
@@ -35,17 +40,6 @@ 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):
if not value:
return "0";
@@ -67,9 +61,8 @@ if len(sys.argv) < 4 or sys.argv[1] != "-o":
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()
+with open(input_path) as html_entity_names_file:
+ entries = list(csv.reader(html_entity_names_file))
entries.sort(key = lambda entry: entry[ENTITY])
entity_count = len(entries)
@@ -101,7 +94,7 @@ output_file.write("""/*
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// THIS FILE IS GENERATED BY WebCore/html/parser/create-html-entity-table
+// THIS FILE IS GENERATED BY core/html/parser/create-html-entity-table
// DO NOT EDIT (unless you are a ninja)!
#include "config.h"
@@ -112,62 +105,126 @@ namespace WebCore {
namespace {
""")
+assert len(entries) > 0, "Code assumes a non-empty entity array."
+def check_ascii(entity_string):
+ for c in entity_string:
+ code = ord(c)
+ assert 0 <= code <= 127, (c + " is not ASCII. Need to change type " +
+ "of storage from LChar to UChar to support " +
+ "this entity.")
+
+output_file.write("static const LChar staticEntityStringStorage[] = {\n")
+output_file.write("'")
+all_data = ""
+entity_offset = 0
+first_output = True
+saved_by_reusing = 0
for entry in entries:
- output_file.write("static const UChar %s[] = %s;\n" % (
- convert_entity_to_cpp_name(entry[ENTITY]),
- convert_entity_to_uchar_array(entry[ENTITY])))
+ check_ascii(entry[ENTITY])
+ # Reuse substrings from earlier entries. This saves 1-2000
+ # characters, but it's O(n^2) and not very smart. The optimal
+ # solution has to solve the "Shortest Common Superstring" problem
+ # and that is NP-Complete or worse.
+ #
+ # This would be even more efficient if we didn't store the
+ # semi-colon in the array but as a bit in the entry.
+ entity = entry[ENTITY]
+ already_existing_offset = all_data.find(entity)
+ if already_existing_offset != -1:
+ # Reusing space.
+ this_offset = already_existing_offset
+ saved_by_reusing += len(entity)
+ else:
+ if not first_output:
+ output_file.write(",\n'")
+ first_output = False
+
+ # Try the end of the string and see if we can reuse that to
+ # fit the start of the new entity.
+ data_to_add = entity
+ this_offset = entity_offset
+ for truncated_len in range(len(entity) - 1, 0, -1):
+ if all_data.endswith(entity[:truncated_len]):
+ data_to_add = entity[truncated_len:]
+ this_offset = entity_offset - truncated_len
+ saved_by_reusing += truncated_len
+ break
+
+ output_file.write("', '".join(data_to_add))
+ all_data += data_to_add
+ output_file.write("'")
+ entity_offset += len(data_to_add)
+ assert len(entry) == 2, "We will use slot [2] in the list for the offset."
+ assert this_offset < 32768 # Stored in a 16 bit short.
+ entry.append(this_offset)
+
+output_file.write("};\n")
+
+index = {}
+for offset, entry in enumerate(entries):
+ starting_letter = entry[ENTITY][0]
+ if starting_letter not in index:
+ index[starting_letter] = offset
output_file.write("""
static const HTMLEntityTableEntry staticEntityTable[%s] = {\n""" % entity_count)
-index = {}
-offset = 0
for entry in entries:
- letter = entry[ENTITY][0]
- if letter not in index:
- index[letter] = offset
values = entry[VALUE].split(' ')
assert len(values) <= 2, values
- output_file.write(' { %s, %s, %s, %s },\n' % (
- convert_entity_to_cpp_name(entry[ENTITY]),
- len(entry[ENTITY]),
+ output_file.write(' { %s, %s, %s, %s }, // &%s\n' % (
convert_value_to_int(values[0]),
- convert_value_to_int(values[1] if len(values) >= 2 else "")))
- offset += 1
+ convert_value_to_int(values[1] if len(values) >= 2 else ""),
+ entry[2],
+ len(entry[ENTITY]),
+ entry[ENTITY],
+ ))
output_file.write("""};
""")
-output_file.write("static const HTMLEntityTableEntry* uppercaseOffset[] = {\n")
+output_file.write("""
+}
+""")
+
+output_file.write("static const short uppercaseOffset[] = {\n")
for letter in string.ascii_uppercase:
- output_file.write("%s\n" % offset_table_entry(index[letter]))
-output_file.write("%s\n" % offset_table_entry(index['a']))
+ output_file.write("%d,\n" % index[letter])
+output_file.write("%d\n" % index['a'])
output_file.write("""};
-static const HTMLEntityTableEntry* lowercaseOffset[] = {\n""")
+static const short lowercaseOffset[] = {\n""")
for letter in string.ascii_lowercase:
- output_file.write("%s\n" % offset_table_entry(index[letter]))
-output_file.write("%s\n" % offset_table_entry(entity_count))
+ output_file.write("%d,\n" % index[letter])
+output_file.write("%d\n" % entity_count)
output_file.write("""};
+const LChar* HTMLEntityTable::entityString(const HTMLEntityTableEntry& entry)
+{
+ return staticEntityStringStorage + entry.entityOffset;
+}
+
+LChar HTMLEntityTableEntry::lastCharacter() const
+{
+ return HTMLEntityTable::entityString(*this)[length - 1];
}
const HTMLEntityTableEntry* HTMLEntityTable::firstEntryStartingWith(UChar c)
{
if (c >= 'A' && c <= 'Z')
- return uppercaseOffset[c - 'A'];
+ return &staticEntityTable[uppercaseOffset[c - 'A']];
if (c >= 'a' && c <= 'z')
- return lowercaseOffset[c - 'a'];
+ return &staticEntityTable[lowercaseOffset[c - 'a']];
return 0;
}
const HTMLEntityTableEntry* HTMLEntityTable::lastEntryStartingWith(UChar c)
{
if (c >= 'A' && c <= 'Z')
- return uppercaseOffset[c - 'A' + 1] - 1;
+ return &staticEntityTable[uppercaseOffset[c - 'A' + 1]] - 1;
if (c >= 'a' && c <= 'z')
- return lowercaseOffset[c - 'a' + 1] - 1;
+ return &staticEntityTable[lowercaseOffset[c - 'a' + 1]] - 1;
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp
index cb928e81dce..adbd8f8adde 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp
@@ -27,9 +27,9 @@
#include "core/html/shadow/ClearButtonElement.h"
#include "core/events/MouseEvent.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
@@ -43,10 +43,10 @@ inline ClearButtonElement::ClearButtonElement(Document& document, ClearButtonOwn
{
}
-PassRefPtr<ClearButtonElement> ClearButtonElement::create(Document& document, ClearButtonOwner& clearButtonOwner)
+PassRefPtrWillBeRawPtr<ClearButtonElement> ClearButtonElement::create(Document& document, ClearButtonOwner& clearButtonOwner)
{
- RefPtr<ClearButtonElement> element = adoptRef(new ClearButtonElement(document, clearButtonOwner));
- element->setPseudo(AtomicString("-webkit-clear-button", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<ClearButtonElement> element = adoptRefWillBeNoop(new ClearButtonElement(document, clearButtonOwner));
+ element->setShadowPseudoId(AtomicString("-webkit-clear-button", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::clearButton());
return element.release();
}
@@ -54,8 +54,8 @@ PassRefPtr<ClearButtonElement> ClearButtonElement::create(Document& document, Cl
void ClearButtonElement::detach(const AttachContext& context)
{
if (m_capturing) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
}
HTMLDivElement::detach(context);
}
@@ -65,8 +65,8 @@ void ClearButtonElement::releaseCapture()
if (!m_capturing)
return;
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_capturing = false;
}
}
@@ -87,7 +87,7 @@ void ClearButtonElement::defaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
frame->eventHandler().setCapturingMouseEventsNode(this);
m_capturing = true;
}
@@ -97,8 +97,8 @@ void ClearButtonElement::defaultEventHandler(Event* event)
}
if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
if (m_capturing) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_capturing = false;
}
if (hovered()) {
@@ -117,4 +117,10 @@ bool ClearButtonElement::isClearButtonElement() const
return true;
}
+void ClearButtonElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_clearButtonOwner);
+ HTMLDivElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h
index 47c91115e31..eba5309fa30 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h
@@ -33,7 +33,7 @@ namespace WebCore {
class ClearButtonElement FINAL : public HTMLDivElement {
public:
- class ClearButtonOwner {
+ class ClearButtonOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~ClearButtonOwner() { }
virtual void focusAndSelectClearButtonOwner() = 0;
@@ -41,18 +41,20 @@ public:
virtual void clearValue() = 0;
};
- static PassRefPtr<ClearButtonElement> create(Document&, ClearButtonOwner&);
+ static PassRefPtrWillBeRawPtr<ClearButtonElement> create(Document&, ClearButtonOwner&);
void releaseCapture();
- void removeClearButtonOwner() { m_clearButtonOwner = 0; }
+ void removeClearButtonOwner() { m_clearButtonOwner = nullptr; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
ClearButtonElement(Document&, ClearButtonOwner&);
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool isMouseFocusable() const { return false; }
- virtual void defaultEventHandler(Event*);
+ virtual bool isMouseFocusable() const OVERRIDE { return false; }
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool isClearButtonElement() const OVERRIDE;
- ClearButtonOwner* m_clearButtonOwner;
+ RawPtrWillBeMember<ClearButtonOwner> m_clearButtonOwner;
bool m_capturing;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
index eb3508e9dc8..3b337ddf0f1 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
@@ -27,8 +27,9 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/shadow/DateTimeEditElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/events/MouseEvent.h"
#include "core/html/forms/DateTimeFieldsState.h"
@@ -147,7 +148,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
switch (fieldType) {
case DateTimeFormat::FieldTypeDayOfMonth: {
- RefPtr<DateTimeFieldElement> field = DateTimeDayFieldElement::create(document, m_editElement, m_parameters.placeholderForDay, m_dayRange);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeDayFieldElement::create(document, m_editElement, m_parameters.placeholderForDay, m_dayRange);
m_editElement.addField(field);
if (shouldDayOfMonthFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -158,7 +159,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour11: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerHour * 12);
- RefPtr<DateTimeFieldElement> field = DateTimeHour11FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour11FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -169,7 +170,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour12: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerHour * 12);
- RefPtr<DateTimeFieldElement> field = DateTimeHour12FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour12FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -180,7 +181,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour23: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerDay);
- RefPtr<DateTimeFieldElement> field = DateTimeHour23FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour23FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -191,7 +192,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour24: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerDay);
- RefPtr<DateTimeFieldElement> field = DateTimeHour24FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour24FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -202,7 +203,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeMinute: {
DateTimeNumericFieldElement::Step step = createStep(msPerMinute, msPerHour);
- RefPtr<DateTimeNumericFieldElement> field = DateTimeMinuteFieldElement::create(document, m_editElement, m_minuteRange, step);
+ RefPtrWillBeRawPtr<DateTimeNumericFieldElement> field = DateTimeMinuteFieldElement::create(document, m_editElement, m_minuteRange, step);
m_editElement.addField(field);
if (shouldMinuteFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -221,7 +222,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
minMonth = m_parameters.minimum.month();
maxMonth = m_parameters.maximum.month();
}
- RefPtr<DateTimeFieldElement> field;
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field;
switch (count) {
case countForNarrowMonth: // Fallthrough.
case countForAbbreviatedMonth:
@@ -243,7 +244,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
}
case DateTimeFormat::FieldTypePeriod: {
- RefPtr<DateTimeFieldElement> field = DateTimeAMPMFieldElement::create(document, m_editElement, m_parameters.locale.timeAMPMLabels());
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeAMPMFieldElement::create(document, m_editElement, m_parameters.locale.timeAMPMLabels());
m_editElement.addField(field);
if (shouldAMPMFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -254,7 +255,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeSecond: {
DateTimeNumericFieldElement::Step step = createStep(msPerSecond, msPerMinute);
- RefPtr<DateTimeNumericFieldElement> field = DateTimeSecondFieldElement::create(document, m_editElement, m_secondRange, step);
+ RefPtrWillBeRawPtr<DateTimeNumericFieldElement> field = DateTimeSecondFieldElement::create(document, m_editElement, m_secondRange, step);
m_editElement.addField(field);
if (shouldSecondFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -270,7 +271,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeFractionalSecond: {
DateTimeNumericFieldElement::Step step = createStep(1, msPerSecond);
- RefPtr<DateTimeNumericFieldElement> field = DateTimeMillisecondFieldElement::create(document, m_editElement, m_millisecondRange, step);
+ RefPtrWillBeRawPtr<DateTimeNumericFieldElement> field = DateTimeMillisecondFieldElement::create(document, m_editElement, m_millisecondRange, step);
m_editElement.addField(field);
if (shouldMillisecondFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -313,7 +314,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
std::swap(yearParams.minIsSpecified, yearParams.maxIsSpecified);
}
yearParams.placeholder = m_parameters.placeholderForYear;
- RefPtr<DateTimeFieldElement> field = DateTimeYearFieldElement::create(document, m_editElement, yearParams);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeYearFieldElement::create(document, m_editElement, yearParams);
m_editElement.addField(field);
if (shouldYearFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -401,8 +402,8 @@ void DateTimeEditBuilder::visitLiteral(const String& text)
{
DEFINE_STATIC_LOCAL(AtomicString, textPseudoId, ("-webkit-datetime-edit-text", AtomicString::ConstructFromLiteral));
ASSERT(text.length());
- RefPtr<HTMLDivElement> element = HTMLDivElement::create(m_editElement.document());
- element->setPseudo(textPseudoId);
+ RefPtrWillBeRawPtr<HTMLDivElement> element = HTMLDivElement::create(m_editElement.document());
+ element->setShadowPseudoId(textPseudoId);
if (m_parameters.locale.isRTL() && text.length()) {
Direction dir = direction(text[0]);
if (dir == SegmentSeparator || dir == WhiteSpaceNeutral || dir == OtherNeutral)
@@ -448,8 +449,19 @@ DateTimeEditElement::DateTimeEditElement(Document& document, EditControlOwner& e
DateTimeEditElement::~DateTimeEditElement()
{
+#if !ENABLE(OILPAN)
for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex)
m_fields[fieldIndex]->removeEventHandler();
+#endif
+}
+
+void DateTimeEditElement::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_fields);
+#endif
+ visitor->trace(m_editControlOwner);
+ HTMLDivElement::trace(visitor);
}
inline Element* DateTimeEditElement::fieldsWrapperElement() const
@@ -458,7 +470,7 @@ inline Element* DateTimeEditElement::fieldsWrapperElement() const
return toElement(firstChild());
}
-void DateTimeEditElement::addField(PassRefPtr<DateTimeFieldElement> field)
+void DateTimeEditElement::addField(PassRefPtrWillBeRawPtr<DateTimeFieldElement> field)
{
if (m_fields.size() == m_fields.capacity())
return;
@@ -481,10 +493,10 @@ void DateTimeEditElement::blurByOwner()
field->blur();
}
-PassRefPtr<DateTimeEditElement> DateTimeEditElement::create(Document& document, EditControlOwner& editControlOwner)
+PassRefPtrWillBeRawPtr<DateTimeEditElement> DateTimeEditElement::create(Document& document, EditControlOwner& editControlOwner)
{
- RefPtr<DateTimeEditElement> container = adoptRef(new DateTimeEditElement(document, editControlOwner));
- container->setPseudo(AtomicString("-webkit-datetime-edit", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<DateTimeEditElement> container = adoptRefWillBeNoop(new DateTimeEditElement(document, editControlOwner));
+ container->setShadowPseudoId(AtomicString("-webkit-datetime-edit", AtomicString::ConstructFromLiteral));
container->setAttribute(idAttr, ShadowElementNames::dateTimeEdit());
return container.release();
}
@@ -534,7 +546,7 @@ void DateTimeEditElement::disabledStateChanged()
DateTimeFieldElement* DateTimeEditElement::fieldAt(size_t fieldIndex) const
{
- return fieldIndex < m_fields.size() ? m_fields[fieldIndex] : 0;
+ return fieldIndex < m_fields.size() ? m_fields[fieldIndex].get() : 0;
}
size_t DateTimeEditElement::fieldIndexOf(const DateTimeFieldElement& field) const
@@ -651,8 +663,8 @@ void DateTimeEditElement::layout(const LayoutParameters& layoutParameters, const
{
DEFINE_STATIC_LOCAL(AtomicString, fieldsWrapperPseudoId, ("-webkit-datetime-edit-fields-wrapper", AtomicString::ConstructFromLiteral));
if (!firstChild()) {
- RefPtr<HTMLDivElement> element = HTMLDivElement::create(document());
- element->setPseudo(fieldsWrapperPseudoId);
+ RefPtrWillBeRawPtr<HTMLDivElement> element = HTMLDivElement::create(document());
+ element->setShadowPseudoId(fieldsWrapperPseudoId);
appendChild(element.get());
}
Element* fieldsWrapper = fieldsWrapperElement();
@@ -685,7 +697,7 @@ void DateTimeEditElement::layout(const LayoutParameters& layoutParameters, const
if (childNode == lastChildToBeRemoved)
break;
}
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
}
@@ -694,6 +706,12 @@ AtomicString DateTimeEditElement::localeIdentifier() const
return m_editControlOwner ? m_editControlOwner->localeIdentifier() : nullAtom;
}
+void DateTimeEditElement::fieldDidChangeValueByKeyboard()
+{
+ if (m_editControlOwner)
+ m_editControlOwner->editControlDidChangeValueByKeyboard();
+}
+
void DateTimeEditElement::readOnlyStateChanged()
{
updateUIState();
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h
index 87226cb136b..8621afdad8e 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h
@@ -45,11 +45,12 @@ class StepRange;
// - Hour, Minute, Second, Millisecond, AM/PM
class DateTimeEditElement FINAL : public HTMLDivElement, public DateTimeFieldElement::FieldOwner {
WTF_MAKE_NONCOPYABLE(DateTimeEditElement);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DateTimeEditElement);
public:
// EditControlOwner implementer must call removeEditControlOwner when
// it doesn't handle event, e.g. at destruction.
- class EditControlOwner {
+ class EditControlOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~EditControlOwner();
virtual void didBlurFromControl() = 0;
@@ -59,6 +60,7 @@ public:
virtual bool isEditControlOwnerDisabled() const = 0;
virtual bool isEditControlOwnerReadOnly() const = 0;
virtual AtomicString localeIdentifier() const = 0;
+ virtual void editControlDidChangeValueByKeyboard() = 0;
};
struct LayoutParameters {
@@ -79,10 +81,12 @@ public:
}
};
- static PassRefPtr<DateTimeEditElement> create(Document&, EditControlOwner&);
+ static PassRefPtrWillBeRawPtr<DateTimeEditElement> create(Document&, EditControlOwner&);
virtual ~DateTimeEditElement();
- void addField(PassRefPtr<DateTimeFieldElement>);
+ virtual void trace(Visitor*) OVERRIDE;
+
+ void addField(PassRefPtrWillBeRawPtr<DateTimeFieldElement>);
bool anyEditableFieldsHaveValues() const;
void blurByOwner();
virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -94,7 +98,7 @@ public:
void focusByOwner(Element* oldFocusedElement = 0);
bool hasFocusedField();
void readOnlyStateChanged();
- void removeEditControlOwner() { m_editControlOwner = 0; }
+ void removeEditControlOwner() { m_editControlOwner = nullptr; }
void resetFields();
void setEmptyValue(const LayoutParameters&, const DateComponents& dateForReadOnlyField);
void setValueAsDate(const LayoutParameters&, const DateComponents&);
@@ -136,17 +140,18 @@ private:
virtual bool isDateTimeEditElement() const OVERRIDE;
// DateTimeFieldElement::FieldOwner functions.
- virtual void didBlurFromField() OVERRIDE FINAL;
- virtual void didFocusOnField() OVERRIDE FINAL;
- virtual void fieldValueChanged() OVERRIDE FINAL;
- virtual bool focusOnNextField(const DateTimeFieldElement&) OVERRIDE FINAL;
- virtual bool focusOnPreviousField(const DateTimeFieldElement&) OVERRIDE FINAL;
- virtual bool isFieldOwnerDisabled() const OVERRIDE FINAL;
- virtual bool isFieldOwnerReadOnly() const OVERRIDE FINAL;
- virtual AtomicString localeIdentifier() const OVERRIDE FINAL;
-
- Vector<DateTimeFieldElement*, maximumNumberOfFields> m_fields;
- EditControlOwner* m_editControlOwner;
+ virtual void didBlurFromField() OVERRIDE;
+ virtual void didFocusOnField() OVERRIDE;
+ virtual void fieldValueChanged() OVERRIDE;
+ virtual bool focusOnNextField(const DateTimeFieldElement&) OVERRIDE;
+ virtual bool focusOnPreviousField(const DateTimeFieldElement&) OVERRIDE;
+ virtual bool isFieldOwnerDisabled() const OVERRIDE;
+ virtual bool isFieldOwnerReadOnly() const OVERRIDE;
+ virtual AtomicString localeIdentifier() const OVERRIDE;
+ virtual void fieldDidChangeValueByKeyboard() OVERRIDE;
+
+ WillBeHeapVector<RawPtrWillBeMember<DateTimeFieldElement>, maximumNumberOfFields> m_fields;
+ RawPtrWillBeMember<EditControlOwner> m_editControlOwner;
};
DEFINE_TYPE_CASTS(DateTimeEditElement, Element, element, element->isDateTimeEditElement(), element.isDateTimeEditElement());
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp
index 31cdb06f9c4..e96cc7a4fb5 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp
@@ -27,7 +27,8 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/shadow/DateTimeFieldElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/events/KeyboardEvent.h"
#include "platform/text/PlatformLocale.h"
@@ -52,22 +53,27 @@ DateTimeFieldElement::DateTimeFieldElement(Document& document, FieldOwner& field
{
}
-void DateTimeFieldElement::defaultEventHandler(Event* event)
+void DateTimeFieldElement::trace(Visitor* visitor)
{
- if (event->type() == EventTypeNames::blur)
- didBlur();
-
- if (event->type() == EventTypeNames::focus)
- didFocus();
+ visitor->trace(m_fieldOwner);
+ HTMLSpanElement::trace(visitor);
+}
+void DateTimeFieldElement::defaultEventHandler(Event* event)
+{
if (event->isKeyboardEvent()) {
KeyboardEvent* keyboardEvent = toKeyboardEvent(event);
if (!isDisabled() && !isFieldOwnerDisabled() && !isFieldOwnerReadOnly()) {
handleKeyboardEvent(keyboardEvent);
- if (keyboardEvent->defaultHandled())
+ if (keyboardEvent->defaultHandled()) {
+ if (m_fieldOwner)
+ m_fieldOwner->fieldDidChangeValueByKeyboard();
return;
+ }
}
defaultKeyboardEventHandler(keyboardEvent);
+ if (m_fieldOwner)
+ m_fieldOwner->fieldDidChangeValueByKeyboard();
if (keyboardEvent->defaultHandled())
return;
}
@@ -129,16 +135,11 @@ void DateTimeFieldElement::defaultKeyboardEventHandler(KeyboardEvent* keyboardEv
}
}
-void DateTimeFieldElement::didBlur()
-{
- if (m_fieldOwner)
- m_fieldOwner->didBlurFromField();
-}
-
-void DateTimeFieldElement::didFocus()
+void DateTimeFieldElement::setFocus(bool value)
{
if (m_fieldOwner)
- m_fieldOwner->didFocusOnField();
+ value ? m_fieldOwner->didFocusOnField() : m_fieldOwner->didBlurFromField();
+ ContainerNode::setFocus(value);
}
void DateTimeFieldElement::focusOnNextField()
@@ -152,12 +153,12 @@ void DateTimeFieldElement::initialize(const AtomicString& pseudo, const String&
{
// On accessibility, DateTimeFieldElement acts like spin button.
setAttribute(roleAttr, AtomicString("spinbutton", AtomicString::ConstructFromLiteral));
- setAttribute(aria_valuetextAttr, emptyValueAXText());
- setAttribute(aria_valueminAttr, String::number(axMinimum));
- setAttribute(aria_valuemaxAttr, String::number(axMaximum));
+ setAttribute(aria_valuetextAttr, AtomicString(emptyValueAXText()));
+ setAttribute(aria_valueminAttr, AtomicString::number(axMinimum));
+ setAttribute(aria_valuemaxAttr, AtomicString::number(axMaximum));
- setAttribute(aria_helpAttr, axHelpText);
- setPseudo(pseudo);
+ setAttribute(aria_helpAttr, AtomicString(axHelpText));
+ setShadowPseudoId(pseudo);
appendChild(Text::create(document(), visibleValue()));
}
@@ -201,7 +202,7 @@ void DateTimeFieldElement::setDisabled()
{
// Set HTML attribute disabled to change apperance.
setBooleanAttribute(disabledAttr, true);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
bool DateTimeFieldElement::supportsFocus() const
@@ -220,10 +221,10 @@ void DateTimeFieldElement::updateVisibleValue(EventBehavior eventBehavior)
textNode->replaceWholeText(newVisibleValue);
if (hasValue()) {
- setAttribute(aria_valuetextAttr, newVisibleValue);
- setAttribute(aria_valuenowAttr, String::number(valueForARIAValueNow()));
+ setAttribute(aria_valuetextAttr, AtomicString(newVisibleValue));
+ setAttribute(aria_valuenowAttr, AtomicString::number(valueForARIAValueNow()));
} else {
- setAttribute(aria_valuetextAttr, emptyValueAXText());
+ setAttribute(aria_valuetextAttr, AtomicString(emptyValueAXText()));
removeAttribute(aria_valuenowAttr);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h
index a2e42a9599b..1fe32594769 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h
@@ -48,7 +48,7 @@ public:
// FieldOwner implementer must call removeEventHandler when
// it doesn't handle event, e.g. at destruction.
- class FieldOwner {
+ class FieldOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~FieldOwner();
virtual void didBlurFromField() = 0;
@@ -59,6 +59,7 @@ public:
virtual bool isFieldOwnerDisabled() const = 0;
virtual bool isFieldOwnerReadOnly() const = 0;
virtual AtomicString localeIdentifier() const = 0;
+ virtual void fieldDidChangeValueByKeyboard() = 0;
};
virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -66,7 +67,7 @@ public:
bool isDisabled() const;
virtual float maximumWidth(const Font&);
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) = 0;
- void removeEventHandler() { m_fieldOwner = 0; }
+ void removeEventHandler() { m_fieldOwner = nullptr; }
void setDisabled();
virtual void setEmptyValue(EventBehavior = DispatchNoEvent) = 0;
virtual void setValueAsDate(const DateComponents&) = 0;
@@ -76,11 +77,10 @@ public:
virtual void stepUp() = 0;
virtual String value() const = 0;
virtual String visibleValue() const = 0;
+ virtual void trace(Visitor*) OVERRIDE;
protected:
DateTimeFieldElement(Document&, FieldOwner&);
- virtual void didBlur();
- virtual void didFocus();
void focusOnNextField();
virtual void handleKeyboardEvent(KeyboardEvent*) = 0;
void initialize(const AtomicString& pseudo, const String& axHelpText, int axMinimum, int axMaximum);
@@ -90,14 +90,17 @@ protected:
virtual int valueAsInteger() const = 0;
virtual int valueForARIAValueNow() const;
+ // Node functions.
+ virtual void setFocus(bool) OVERRIDE;
+
private:
void defaultKeyboardEventHandler(KeyboardEvent*);
- virtual bool isDateTimeFieldElement() const OVERRIDE;
+ virtual bool isDateTimeFieldElement() const OVERRIDE FINAL;
bool isFieldOwnerDisabled() const;
bool isFieldOwnerReadOnly() const;
virtual bool supportsFocus() const OVERRIDE FINAL;
- FieldOwner* m_fieldOwner;
+ RawPtrWillBeMember<FieldOwner> m_fieldOwner;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp
index 5353c04ff2e..9479d9682ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp
@@ -47,10 +47,10 @@ DateTimeAMPMFieldElement::DateTimeAMPMFieldElement(Document& document, FieldOwne
{
}
-PassRefPtr<DateTimeAMPMFieldElement> DateTimeAMPMFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& ampmLabels)
+PassRefPtrWillBeRawPtr<DateTimeAMPMFieldElement> DateTimeAMPMFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& ampmLabels)
{
DEFINE_STATIC_LOCAL(AtomicString, ampmPsuedoId, ("-webkit-datetime-edit-ampm-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeAMPMFieldElement> field = adoptRef(new DateTimeAMPMFieldElement(document, fieldOwner, ampmLabels));
+ RefPtrWillBeRawPtr<DateTimeAMPMFieldElement> field = adoptRefWillBeNoop(new DateTimeAMPMFieldElement(document, fieldOwner, ampmLabels));
field->initialize(ampmPsuedoId, queryString(WebLocalizedString::AXAMPMFieldText));
return field.release();
}
@@ -83,10 +83,10 @@ DateTimeDayFieldElement::DateTimeDayFieldElement(Document& document, FieldOwner&
{
}
-PassRefPtr<DateTimeDayFieldElement> DateTimeDayFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
+PassRefPtrWillBeRawPtr<DateTimeDayFieldElement> DateTimeDayFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
{
DEFINE_STATIC_LOCAL(AtomicString, dayPsuedoId, ("-webkit-datetime-edit-day-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeDayFieldElement> field = adoptRef(new DateTimeDayFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
+ RefPtrWillBeRawPtr<DateTimeDayFieldElement> field = adoptRefWillBeNoop(new DateTimeDayFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
field->initialize(dayPsuedoId, queryString(WebLocalizedString::AXDayOfMonthFieldText));
return field.release();
}
@@ -159,7 +159,7 @@ DateTimeHour11FieldElement::DateTimeHour11FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour11FieldElement> DateTimeHour11FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour11FieldElement> DateTimeHour11FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
@@ -172,7 +172,7 @@ PassRefPtr<DateTimeHour11FieldElement> DateTimeHour11FieldElement::create(Docume
range.maximum = hour23Range.maximum - 12;
}
- RefPtr<DateTimeHour11FieldElement> field = adoptRef(new DateTimeHour11FieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeHour11FieldElement> field = adoptRefWillBeNoop(new DateTimeHour11FieldElement(document, fieldOwner, range, step));
field->initialize();
return field.release();
}
@@ -200,7 +200,7 @@ DateTimeHour12FieldElement::DateTimeHour12FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour12FieldElement> DateTimeHour12FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour12FieldElement> DateTimeHour12FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
@@ -220,7 +220,7 @@ PassRefPtr<DateTimeHour12FieldElement> DateTimeHour12FieldElement::create(Docume
range.minimum = 1;
range.maximum = 12;
}
- RefPtr<DateTimeHour12FieldElement> field = adoptRef(new DateTimeHour12FieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeHour12FieldElement> field = adoptRefWillBeNoop(new DateTimeHour12FieldElement(document, fieldOwner, range, step));
field->initialize();
return field.release();
}
@@ -243,12 +243,12 @@ DateTimeHour23FieldElement::DateTimeHour23FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour23FieldElement> DateTimeHour23FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour23FieldElement> DateTimeHour23FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
ASSERT(hour23Range.minimum <= hour23Range.maximum);
- RefPtr<DateTimeHour23FieldElement> field = adoptRef(new DateTimeHour23FieldElement(document, fieldOwner, hour23Range, step));
+ RefPtrWillBeRawPtr<DateTimeHour23FieldElement> field = adoptRefWillBeNoop(new DateTimeHour23FieldElement(document, fieldOwner, hour23Range, step));
field->initialize();
return field.release();
}
@@ -279,7 +279,7 @@ DateTimeHour24FieldElement::DateTimeHour24FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour24FieldElement> DateTimeHour24FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour24FieldElement> DateTimeHour24FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
@@ -290,7 +290,7 @@ PassRefPtr<DateTimeHour24FieldElement> DateTimeHour24FieldElement::create(Docume
range.maximum = 24;
}
- RefPtr<DateTimeHour24FieldElement> field = adoptRef(new DateTimeHour24FieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeHour24FieldElement> field = adoptRefWillBeNoop(new DateTimeHour24FieldElement(document, fieldOwner, range, step));
field->initialize();
return field.release();
}
@@ -326,10 +326,10 @@ DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document& docum
{
}
-PassRefPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
{
DEFINE_STATIC_LOCAL(AtomicString, millisecondPsuedoId, ("-webkit-datetime-edit-millisecond-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMillisecondFieldElement> field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeMillisecondFieldElement> field = adoptRefWillBeNoop(new DateTimeMillisecondFieldElement(document, fieldOwner, range, step));
field->initialize(millisecondPsuedoId, queryString(WebLocalizedString::AXMillisecondFieldText));
return field.release();
}
@@ -367,10 +367,10 @@ DateTimeMinuteFieldElement::DateTimeMinuteFieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeMinuteFieldElement> DateTimeMinuteFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeMinuteFieldElement> DateTimeMinuteFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
{
DEFINE_STATIC_LOCAL(AtomicString, minutePsuedoId, ("-webkit-datetime-edit-minute-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMinuteFieldElement> field = adoptRef(new DateTimeMinuteFieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeMinuteFieldElement> field = adoptRefWillBeNoop(new DateTimeMinuteFieldElement(document, fieldOwner, range, step));
field->initialize(minutePsuedoId, queryString(WebLocalizedString::AXMinuteFieldText));
return field.release();
}
@@ -408,10 +408,10 @@ DateTimeMonthFieldElement::DateTimeMonthFieldElement(Document& document, FieldOw
{
}
-PassRefPtr<DateTimeMonthFieldElement> DateTimeMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
+PassRefPtrWillBeRawPtr<DateTimeMonthFieldElement> DateTimeMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
{
DEFINE_STATIC_LOCAL(AtomicString, monthPsuedoId, ("-webkit-datetime-edit-month-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMonthFieldElement> field = adoptRef(new DateTimeMonthFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
+ RefPtrWillBeRawPtr<DateTimeMonthFieldElement> field = adoptRefWillBeNoop(new DateTimeMonthFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
field->initialize(monthPsuedoId, queryString(WebLocalizedString::AXMonthFieldText));
return field.release();
}
@@ -449,10 +449,10 @@ DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeSecondFieldElement> DateTimeSecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeSecondFieldElement> DateTimeSecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
{
DEFINE_STATIC_LOCAL(AtomicString, secondPsuedoId, ("-webkit-datetime-edit-second-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeSecondFieldElement> field = adoptRef(new DateTimeSecondFieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeSecondFieldElement> field = adoptRefWillBeNoop(new DateTimeSecondFieldElement(document, fieldOwner, range, step));
field->initialize(secondPsuedoId, queryString(WebLocalizedString::AXSecondFieldText));
return field.release();
}
@@ -490,10 +490,10 @@ DateTimeSymbolicMonthFieldElement::DateTimeSymbolicMonthFieldElement(Document& d
{
}
-PassRefPtr<DateTimeSymbolicMonthFieldElement> DateTimeSymbolicMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& labels, int minimum, int maximum)
+PassRefPtrWillBeRawPtr<DateTimeSymbolicMonthFieldElement> DateTimeSymbolicMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& labels, int minimum, int maximum)
{
DEFINE_STATIC_LOCAL(AtomicString, monthPsuedoId, ("-webkit-datetime-edit-month-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeSymbolicMonthFieldElement> field = adoptRef(new DateTimeSymbolicMonthFieldElement(document, fieldOwner, labels, minimum, maximum));
+ RefPtrWillBeRawPtr<DateTimeSymbolicMonthFieldElement> field = adoptRefWillBeNoop(new DateTimeSymbolicMonthFieldElement(document, fieldOwner, labels, minimum, maximum));
field->initialize(monthPsuedoId, queryString(WebLocalizedString::AXMonthFieldText));
return field.release();
}
@@ -534,10 +534,10 @@ DateTimeWeekFieldElement::DateTimeWeekFieldElement(Document& document, FieldOwne
{
}
-PassRefPtr<DateTimeWeekFieldElement> DateTimeWeekFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range)
+PassRefPtrWillBeRawPtr<DateTimeWeekFieldElement> DateTimeWeekFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range)
{
DEFINE_STATIC_LOCAL(AtomicString, weekPsuedoId, ("-webkit-datetime-edit-week-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeWeekFieldElement> field = adoptRef(new DateTimeWeekFieldElement(document, fieldOwner, range));
+ RefPtrWillBeRawPtr<DateTimeWeekFieldElement> field = adoptRefWillBeNoop(new DateTimeWeekFieldElement(document, fieldOwner, range));
field->initialize(weekPsuedoId, queryString(WebLocalizedString::AXWeekOfYearFieldText));
return field.release();
}
@@ -579,10 +579,10 @@ DateTimeYearFieldElement::DateTimeYearFieldElement(Document& document, FieldOwne
ASSERT(parameters.maximumYear <= DateComponents::maximumYear());
}
-PassRefPtr<DateTimeYearFieldElement> DateTimeYearFieldElement::create(Document& document, FieldOwner& fieldOwner, const DateTimeYearFieldElement::Parameters& parameters)
+PassRefPtrWillBeRawPtr<DateTimeYearFieldElement> DateTimeYearFieldElement::create(Document& document, FieldOwner& fieldOwner, const DateTimeYearFieldElement::Parameters& parameters)
{
DEFINE_STATIC_LOCAL(AtomicString, yearPsuedoId, ("-webkit-datetime-edit-year-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeYearFieldElement> field = adoptRef(new DateTimeYearFieldElement(document, fieldOwner, parameters));
+ RefPtrWillBeRawPtr<DateTimeYearFieldElement> field = adoptRefWillBeNoop(new DateTimeYearFieldElement(document, fieldOwner, parameters));
field->initialize(yearPsuedoId, queryString(WebLocalizedString::AXYearFieldText));
return field.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h
index fb8ef52b22e..19050dbf6dc 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h
@@ -36,30 +36,30 @@ class DateTimeAMPMFieldElement FINAL : public DateTimeSymbolicFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeAMPMFieldElement);
public:
- static PassRefPtr<DateTimeAMPMFieldElement> create(Document&, FieldOwner&, const Vector<String>&);
+ static PassRefPtrWillBeRawPtr<DateTimeAMPMFieldElement> create(Document&, FieldOwner&, const Vector<String>&);
private:
DateTimeAMPMFieldElement(Document&, FieldOwner&, const Vector<String>&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeDayFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeDayFieldElement);
public:
- static PassRefPtr<DateTimeDayFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
+ static PassRefPtrWillBeRawPtr<DateTimeDayFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
private:
DateTimeDayFieldElement(Document&, FieldOwner&, const String& placeholder, const Range&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeHourFieldElementBase : public DateTimeNumericFieldElement {
@@ -71,154 +71,154 @@ protected:
private:
// DateTimeFieldElement functions.
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeHour11FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour11FieldElement);
public:
- static PassRefPtr<DateTimeHour11FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour11FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour11FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeHour12FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour12FieldElement);
public:
- static PassRefPtr<DateTimeHour12FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour12FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour12FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeHour23FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour23FieldElement);
public:
- static PassRefPtr<DateTimeHour23FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour23FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour23FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeHour24FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour24FieldElement);
public:
- static PassRefPtr<DateTimeHour24FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour24FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour24FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeMillisecondFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMillisecondFieldElement);
public:
- static PassRefPtr<DateTimeMillisecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeMillisecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeMillisecondFieldElement(Document&, FieldOwner&, const Range&, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeMinuteFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMinuteFieldElement);
public:
- static PassRefPtr<DateTimeMinuteFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeMinuteFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeMinuteFieldElement(Document&, FieldOwner&, const Range&, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeMonthFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMonthFieldElement);
public:
- static PassRefPtr<DateTimeMonthFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
+ static PassRefPtrWillBeRawPtr<DateTimeMonthFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
private:
DateTimeMonthFieldElement(Document&, FieldOwner&, const String& placeholder, const Range&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeSecondFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeSecondFieldElement);
public:
- static PassRefPtr<DateTimeSecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeSecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeSecondFieldElement(Document&, FieldOwner&, const Range&, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeSymbolicMonthFieldElement FINAL : public DateTimeSymbolicFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeSymbolicMonthFieldElement);
public:
- static PassRefPtr<DateTimeSymbolicMonthFieldElement> create(Document&, FieldOwner&, const Vector<String>&, int minimum, int maximum);
+ static PassRefPtrWillBeRawPtr<DateTimeSymbolicMonthFieldElement> create(Document&, FieldOwner&, const Vector<String>&, int minimum, int maximum);
private:
DateTimeSymbolicMonthFieldElement(Document&, FieldOwner&, const Vector<String>&, int minimum, int maximum);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeWeekFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeWeekFieldElement);
public:
- static PassRefPtr<DateTimeWeekFieldElement> create(Document&, FieldOwner&, const Range&);
+ static PassRefPtrWillBeRawPtr<DateTimeWeekFieldElement> create(Document&, FieldOwner&, const Range&);
private:
DateTimeWeekFieldElement(Document&, FieldOwner&, const Range&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeYearFieldElement FINAL : public DateTimeNumericFieldElement {
@@ -241,19 +241,19 @@ public:
}
};
- static PassRefPtr<DateTimeYearFieldElement> create(Document&, FieldOwner&, const Parameters&);
+ static PassRefPtrWillBeRawPtr<DateTimeYearFieldElement> create(Document&, FieldOwner&, const Parameters&);
private:
DateTimeYearFieldElement(Document&, FieldOwner&, const Parameters&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
// DateTimeNumericFieldElement functions.
- virtual int defaultValueForStepDown() const OVERRIDE FINAL;
- virtual int defaultValueForStepUp() const OVERRIDE FINAL;
+ virtual int defaultValueForStepDown() const OVERRIDE;
+ virtual int defaultValueForStepUp() const OVERRIDE;
bool m_minIsSpecified;
bool m_maxIsSpecified;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp
index 537416f7402..64b3e46b90c 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp
@@ -27,8 +27,8 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/shadow/DateTimeNumericFieldElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/events/KeyboardEvent.h"
#include "platform/fonts/Font.h"
#include "platform/text/PlatformLocale.h"
@@ -91,13 +91,15 @@ int DateTimeNumericFieldElement::defaultValueForStepUp() const
return m_range.minimum;
}
-void DateTimeNumericFieldElement::didBlur()
+void DateTimeNumericFieldElement::setFocus(bool value)
{
- int value = typeAheadValue();
- m_typeAheadBuffer.clear();
- if (value >= 0)
- setValueAsInteger(value, DispatchEvent);
- DateTimeFieldElement::didBlur();
+ if (!value) {
+ int value = typeAheadValue();
+ m_typeAheadBuffer.clear();
+ if (value >= 0)
+ setValueAsInteger(value, DispatchEvent);
+ }
+ DateTimeFieldElement::setFocus(value);
}
String DateTimeNumericFieldElement::formatValue(int value) const
@@ -122,6 +124,13 @@ void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEve
if (digit < 0 || digit > 9)
return;
+ unsigned maximumLength = DateTimeNumericFieldElement::formatValue(m_range.maximum).length();
+ if (m_typeAheadBuffer.length() >= maximumLength) {
+ String current = m_typeAheadBuffer.toString();
+ m_typeAheadBuffer.clear();
+ unsigned desiredLength = maximumLength - 1;
+ m_typeAheadBuffer.append(current, current.length() - desiredLength, desiredLength);
+ }
m_typeAheadBuffer.append(number);
int newValue = typeAheadValue();
if (newValue >= m_hardLimits.minimum)
@@ -131,7 +140,7 @@ void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEve
updateVisibleValue(DispatchEvent);
}
- if (m_typeAheadBuffer.length() >= DateTimeNumericFieldElement::formatValue(m_range.maximum).length() || newValue * 10 > m_range.maximum)
+ if (m_typeAheadBuffer.length() >= maximumLength || newValue * 10 > m_range.maximum)
focusOnNextField();
keyboardEvent->setDefaultHandled();
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h
index 9b96fb54e3b..9a6272f8f01 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h
@@ -80,13 +80,15 @@ protected:
private:
// DateTimeFieldElement functions.
- virtual void didBlur() OVERRIDE FINAL;
virtual void handleKeyboardEvent(KeyboardEvent*) OVERRIDE FINAL;
virtual float maximumWidth(const Font&) OVERRIDE;
virtual void stepDown() OVERRIDE FINAL;
virtual void stepUp() OVERRIDE FINAL;
virtual String value() const OVERRIDE FINAL;
+ // Node functions.
+ virtual void setFocus(bool) OVERRIDE FINAL;
+
String formatValue(int) const;
int roundUp(int) const;
int roundDown(int) const;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp
index f3f2adb3b8e..3da57cd08ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/html/shadow/DetailsMarkerControl.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLSummaryElement.h"
#include "core/rendering/RenderDetailsMarker.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h
index 118063ef090..62fe336a698 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h
@@ -40,20 +40,20 @@ class HTMLSummaryElement;
class DetailsMarkerControl FINAL : public HTMLDivElement {
public:
- DetailsMarkerControl(Document&);
- static PassRefPtr<DetailsMarkerControl> create(Document&);
+ explicit DetailsMarkerControl(Document&);
+ static PassRefPtrWillBeRawPtr<DetailsMarkerControl> create(Document&);
private:
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
HTMLSummaryElement* summaryElement();
};
-inline PassRefPtr<DetailsMarkerControl> DetailsMarkerControl::create(Document& document)
+inline PassRefPtrWillBeRawPtr<DetailsMarkerControl> DetailsMarkerControl::create(Document& document)
{
- RefPtr<DetailsMarkerControl> element = adoptRef(new DetailsMarkerControl(document));
- element->setPseudo(AtomicString("-webkit-details-marker", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<DetailsMarkerControl> element = adoptRefWillBeNoop(new DetailsMarkerControl(document));
+ element->setShadowPseudoId(AtomicString("-webkit-details-marker", AtomicString::ConstructFromLiteral));
return element.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h
deleted file mode 100644
index b8f0f4fdd58..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 HTMLContentElement_h
-#define HTMLContentElement_h
-
-#include "core/css/CSSSelectorList.h"
-#include "core/dom/shadow/InsertionPoint.h"
-
-namespace WebCore {
-
-class HTMLContentElement FINAL : public InsertionPoint {
-public:
- static PassRefPtr<HTMLContentElement> create(Document&);
-
- virtual ~HTMLContentElement();
-
- virtual bool canAffectSelector() const OVERRIDE { return true; }
-
- bool canSelectNode(const Vector<Node*, 32>& siblings, int nth) const;
-
- const CSSSelectorList& selectorList() const;
- bool isSelectValid() const;
-
-private:
- explicit HTMLContentElement(Document&);
-
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
-
- bool validateSelect() const;
- void parseSelect();
-
- bool matchSelector(const Vector<Node*, 32>& siblings, int nth) const;
-
- bool m_shouldParseSelect;
- bool m_isValidSelector;
- AtomicString m_select;
- CSSSelectorList m_selectorList;
-};
-
-inline const CSSSelectorList& HTMLContentElement::selectorList() const
-{
- if (m_shouldParseSelect)
- const_cast<HTMLContentElement*>(this)->parseSelect();
- return m_selectorList;
-}
-
-inline bool HTMLContentElement::isSelectValid() const
-{
- if (m_shouldParseSelect)
- const_cast<HTMLContentElement*>(this)->parseSelect();
- return m_isValidSelector;
-}
-
-inline bool HTMLContentElement::canSelectNode(const Vector<Node*, 32>& siblings, int nth) const
-{
- if (m_select.isNull() || m_select.isEmpty())
- return true;
- if (!isSelectValid())
- return false;
- if (!siblings[nth]->isElementNode())
- return false;
- return matchSelector(siblings, nth);
-}
-
-inline bool isHTMLContentElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::contentTag);
-}
-
-inline bool isHTMLContentElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::contentTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLContentElement, hasTagName(HTMLNames::contentTag));
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
index dc7f986e04e..989244d1bf8 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
@@ -31,11 +31,13 @@
#include "core/html/shadow/MediaControlElementTypes.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
#include "core/events/MouseEvent.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/shadow/MediaControls.h"
namespace WebCore {
@@ -50,7 +52,7 @@ HTMLMediaElement* toParentMediaElement(Node* node)
Node* mediaNode = node->shadowHost();
if (!mediaNode)
mediaNode = node;
- if (!mediaNode || !mediaNode->isElementNode() || !toElement(mediaNode)->isMediaElement())
+ if (!isHTMLMediaElement(mediaNode))
return 0;
return toHTMLMediaElement(mediaNode);
@@ -60,18 +62,23 @@ MediaControlElementType mediaControlElementType(Node* node)
{
ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
HTMLElement* element = toHTMLElement(node);
- if (element->hasTagName(inputTag))
+ if (isHTMLInputElement(*element))
return static_cast<MediaControlInputElement*>(element)->displayType();
return static_cast<MediaControlDivElement*>(element)->displayType();
}
-MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
- : m_mediaController(0)
+MediaControlElement::MediaControlElement(MediaControls& mediaControls, MediaControlElementType displayType, HTMLElement* element)
+ : m_mediaControls(mediaControls)
, m_displayType(displayType)
, m_element(element)
{
}
+HTMLMediaElement& MediaControlElement::mediaElement() const
+{
+ return mediaControls().mediaElement();
+}
+
void MediaControlElement::hide()
{
m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
@@ -82,14 +89,6 @@ void MediaControlElement::show()
m_element->removeInlineStyleProperty(CSSPropertyDisplay);
}
-bool MediaControlElement::isShowing() const
-{
- const StylePropertySet* propertySet = m_element->inlineStyle();
- // Following the code from show() and hide() above, we only have
- // to check for the presense of inline display.
- return (!propertySet || !propertySet->getPropertyCSSValue(CSSPropertyDisplay));
-}
-
void MediaControlElement::setDisplayType(MediaControlElementType displayType)
{
if (displayType == m_displayType)
@@ -97,22 +96,22 @@ void MediaControlElement::setDisplayType(MediaControlElementType displayType)
m_displayType = displayType;
if (RenderObject* object = m_element->renderer())
- object->repaint();
+ object->paintInvalidationForWholeRenderer();
}
// ----------------------------
-MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType)
- : HTMLDivElement(document)
- , MediaControlElement(displayType, this)
+MediaControlDivElement::MediaControlDivElement(MediaControls& mediaControls, MediaControlElementType displayType)
+ : HTMLDivElement(mediaControls.document())
+ , MediaControlElement(mediaControls, displayType, this)
{
}
// ----------------------------
-MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType)
- : HTMLInputElement(document, 0, false)
- , MediaControlElement(displayType, this)
+MediaControlInputElement::MediaControlInputElement(MediaControls& mediaControls, MediaControlElementType displayType)
+ : HTMLInputElement(mediaControls.document(), 0, false)
+ , MediaControlElement(mediaControls, displayType, this)
{
}
@@ -123,8 +122,8 @@ bool MediaControlInputElement::isMouseFocusable() const
// ----------------------------
-MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType)
- : MediaControlDivElement(document, displayType)
+MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(MediaControls& mediaControls, MediaControlElementType displayType)
+ : MediaControlDivElement(mediaControls, displayType)
, m_currentValue(0)
{
}
@@ -134,87 +133,4 @@ void MediaControlTimeDisplayElement::setCurrentValue(double time)
m_currentValue = time;
}
-// ----------------------------
-
-MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType)
- : MediaControlInputElement(document, displayType)
-{
-}
-
-void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
-{
- if (event->type() == EventTypeNames::click) {
- mediaController()->setMuted(!mediaController()->muted());
- event->setDefaultHandled();
- }
-
- HTMLInputElement::defaultEventHandler(event);
-}
-
-void MediaControlMuteButtonElement::changedMute()
-{
- updateDisplayType();
-}
-
-void MediaControlMuteButtonElement::updateDisplayType()
-{
- setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton);
-}
-
-// ----------------------------
-
-MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
- : MediaControlInputElement(document, MediaVolumeSlider)
- , m_clearMutedOnUserInteraction(false)
-{
-}
-
-void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
-{
- // Left button is 0. Rejects mouse events not from left button.
- if (event->isMouseEvent() && toMouseEvent(event)->button())
- return;
-
- if (!inDocument() || !document().isActive())
- return;
-
- MediaControlInputElement::defaultEventHandler(event);
-
- if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
- return;
-
- double volume = value().toDouble();
- if (volume != mediaController()->volume())
- mediaController()->setVolume(volume, ASSERT_NO_EXCEPTION);
- if (m_clearMutedOnUserInteraction)
- mediaController()->setMuted(false);
-}
-
-bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
-{
- if (!inDocument() || !document().isActive())
- return false;
-
- return MediaControlInputElement::willRespondToMouseMoveEvents();
-}
-
-bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
-{
- if (!inDocument() || !document().isActive())
- return false;
-
- return MediaControlInputElement::willRespondToMouseClickEvents();
-}
-
-void MediaControlVolumeSliderElement::setVolume(double volume)
-{
- if (value().toDouble() != volume)
- setValue(String::number(volume));
-}
-
-void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
-{
- m_clearMutedOnUserInteraction = clearMute;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
index 6293e6dac09..6213debb7b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
@@ -32,23 +32,19 @@
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLMediaElement.h"
-#include "core/html/MediaControllerInterface.h"
#include "core/rendering/RenderBlock.h"
namespace WebCore {
-// Must match WebKitSystemInterface.h
+class HTMLMediaElement;
+class MediaControls;
+
enum MediaControlElementType {
MediaEnterFullscreenButton = 0,
MediaMuteButton,
MediaPlayButton,
- MediaSeekBackButton,
- MediaSeekForwardButton,
MediaSlider,
MediaSliderThumb,
- MediaRewindButton,
- MediaReturnToRealtimeButton,
MediaShowClosedCaptionsButton,
MediaHideClosedCaptionsButton,
MediaUnMuteButton,
@@ -63,7 +59,6 @@ enum MediaControlElementType {
MediaVolumeSliderThumb,
MediaFullScreenVolumeSlider,
MediaFullScreenVolumeSliderThumb,
- MediaVolumeSliderMuteButton,
MediaTextTrackDisplayContainer,
MediaTextTrackDisplay,
MediaExitFullscreenButton,
@@ -77,27 +72,23 @@ MediaControlElementType mediaControlElementType(Node*);
// ----------------------------
-class MediaControlElement {
+class MediaControlElement : public WillBeGarbageCollectedMixin {
public:
- virtual void hide();
- virtual void show();
- virtual bool isShowing() const;
-
- virtual MediaControlElementType displayType() { return m_displayType; }
- virtual const AtomicString& pseudo() const = 0;
+ void hide();
+ void show();
- virtual void setMediaController(MediaControllerInterface* controller) { m_mediaController = controller; }
- virtual MediaControllerInterface* mediaController() const { return m_mediaController; }
+ MediaControlElementType displayType() { return m_displayType; }
protected:
- explicit MediaControlElement(MediaControlElementType, HTMLElement*);
- ~MediaControlElement() { }
+ MediaControlElement(MediaControls&, MediaControlElementType, HTMLElement*);
- virtual void setDisplayType(MediaControlElementType);
- virtual bool isMediaControlElement() const { return true; }
+ MediaControls& mediaControls() const { return m_mediaControls; }
+ HTMLMediaElement& mediaElement() const;
+
+ void setDisplayType(MediaControlElementType);
private:
- MediaControllerInterface* m_mediaController;
+ MediaControls& m_mediaControls;
MediaControlElementType m_displayType;
HTMLElement* m_element;
};
@@ -105,17 +96,21 @@ private:
// ----------------------------
class MediaControlDivElement : public HTMLDivElement, public MediaControlElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaControlDivElement);
+
protected:
- virtual bool isMediaControlElement() const OVERRIDE { return MediaControlElement::isMediaControlElement(); }
- explicit MediaControlDivElement(Document&, MediaControlElementType);
+ virtual bool isMediaControlElement() const OVERRIDE FINAL { return true; }
+ MediaControlDivElement(MediaControls&, MediaControlElementType);
};
// ----------------------------
class MediaControlInputElement : public HTMLInputElement, public MediaControlElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaControlInputElement);
+
protected:
- virtual bool isMediaControlElement() const OVERRIDE { return MediaControlElement::isMediaControlElement(); }
- explicit MediaControlInputElement(Document&, MediaControlElementType);
+ virtual bool isMediaControlElement() const OVERRIDE FINAL { return true; }
+ MediaControlInputElement(MediaControls&, MediaControlElementType);
private:
virtual void updateDisplayType() { }
@@ -130,47 +125,12 @@ public:
double currentValue() const { return m_currentValue; }
protected:
- explicit MediaControlTimeDisplayElement(Document&, MediaControlElementType);
+ MediaControlTimeDisplayElement(MediaControls&, MediaControlElementType);
private:
double m_currentValue;
};
-// ----------------------------
-
-class MediaControlMuteButtonElement : public MediaControlInputElement {
-public:
- void changedMute();
-
- virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
-
-protected:
- explicit MediaControlMuteButtonElement(Document&, MediaControlElementType);
-
- virtual void defaultEventHandler(Event*) OVERRIDE;
-
-private:
- virtual void updateDisplayType() OVERRIDE;
-};
-
-// ----------------------------
-
-class MediaControlVolumeSliderElement : public MediaControlInputElement {
-public:
- virtual bool willRespondToMouseMoveEvents() OVERRIDE;
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
- void setVolume(double);
- void setClearMutedOnUserInteraction(bool);
-
-protected:
- explicit MediaControlVolumeSliderElement(Document&);
-
- virtual void defaultEventHandler(Event*) OVERRIDE;
-
-private:
- bool m_clearMutedOnUserInteraction;
-};
-
} // namespace WebCore
#endif // MediaControlElementTypes_h
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
index 9c3aee249b1..674675fbff9 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
@@ -30,24 +30,23 @@
#include "config.h"
#include "core/html/shadow/MediaControlElements.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/DOMTokenList.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLVideoElement.h"
+#include "core/html/MediaController.h"
#include "core/html/shadow/MediaControls.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/vtt/VTTRegionList.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderMediaControlElements.h"
#include "core/rendering/RenderSlider.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderVideo.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -56,76 +55,39 @@ using namespace HTMLNames;
static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId();
static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId();
+// If you change any of the following fade durations, then also update the
+// corresponding values in LayoutTests/media/media-controls.js.
static const double fadeInDuration = 0.1;
static const double fadeOutDuration = 0.3;
-MediaControlPanelElement::MediaControlPanelElement(Document& document)
- : MediaControlDivElement(document, MediaControlsPanel)
- , m_canBeDragged(false)
- , m_isBeingDragged(false)
+MediaControlPanelElement::MediaControlPanelElement(MediaControls& mediaControls)
+ : MediaControlDivElement(mediaControls, MediaControlsPanel)
, m_isDisplayed(false)
, m_opaque(true)
, m_transitionTimer(this, &MediaControlPanelElement::transitionTimerFired)
{
}
-PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlPanelElement> MediaControlPanelElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlPanelElement(document));
+ return adoptRefWillBeNoop(new MediaControlPanelElement(mediaControls));
}
-const AtomicString& MediaControlPanelElement::pseudo() const
+const AtomicString& MediaControlPanelElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral));
return id;
}
-void MediaControlPanelElement::startDrag(const LayoutPoint& eventLocation)
-{
- if (!m_canBeDragged)
- return;
-
- if (m_isBeingDragged)
- return;
-
- RenderObject* renderer = this->renderer();
- if (!renderer || !renderer->isBox())
- return;
-
- Frame* frame = document().frame();
- if (!frame)
- return;
-
- m_lastDragEventLocation = eventLocation;
-
- frame->eventHandler().setCapturingMouseEventsNode(this);
-
- m_isBeingDragged = true;
-}
-
-void MediaControlPanelElement::continueDrag(const LayoutPoint& eventLocation)
-{
- if (!m_isBeingDragged)
- return;
-
- LayoutSize distanceDragged = eventLocation - m_lastDragEventLocation;
- m_cumulativeDragOffset.move(distanceDragged);
- m_lastDragEventLocation = eventLocation;
- setPosition(m_cumulativeDragOffset);
-}
-
-void MediaControlPanelElement::endDrag()
+void MediaControlPanelElement::defaultEventHandler(Event* event)
{
- if (!m_isBeingDragged)
- return;
-
- m_isBeingDragged = false;
-
- Frame* frame = document().frame();
- if (!frame)
+ // Suppress the media element activation behavior (toggle play/pause) when
+ // any part of the control panel is clicked.
+ if (event->type() == EventTypeNames::click) {
+ event->setDefaultHandled();
return;
-
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ }
+ HTMLDivElement::defaultEventHandler(event);
}
void MediaControlPanelElement::startTimer()
@@ -136,7 +98,7 @@ void MediaControlPanelElement::startTimer()
// such that captions are correctly displayed at the bottom of the video
// at the end of the fadeout transition.
// FIXME: Racing a transition with a setTimeout like this is wrong.
- m_transitionTimer.startOneShot(fadeOutDuration);
+ m_transitionTimer.startOneShot(fadeOutDuration, FROM_HERE);
}
void MediaControlPanelElement::stopTimer()
@@ -153,34 +115,6 @@ void MediaControlPanelElement::transitionTimerFired(Timer<MediaControlPanelEleme
stopTimer();
}
-void MediaControlPanelElement::setPosition(const LayoutPoint& position)
-{
- double left = position.x();
- double top = position.y();
-
- // Set the left and top to control the panel's position; this depends on it being absolute positioned.
- // Set the margin to zero since the position passed in will already include the effect of the margin.
- setInlineStyleProperty(CSSPropertyLeft, left, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyTop, top, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyMarginLeft, 0.0, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyMarginTop, 0.0, CSSPrimitiveValue::CSS_PX);
-
- classList()->add("dragged", IGNORE_EXCEPTION);
-}
-
-void MediaControlPanelElement::resetPosition()
-{
- removeInlineStyleProperty(CSSPropertyLeft);
- removeInlineStyleProperty(CSSPropertyTop);
- removeInlineStyleProperty(CSSPropertyMarginLeft);
- removeInlineStyleProperty(CSSPropertyMarginTop);
-
- classList()->remove("dragged", IGNORE_EXCEPTION);
-
- m_cumulativeDragOffset.setX(0);
- m_cumulativeDragOffset.setY(0);
-}
-
void MediaControlPanelElement::makeOpaque()
{
if (m_opaque)
@@ -209,36 +143,6 @@ void MediaControlPanelElement::makeTransparent()
startTimer();
}
-void MediaControlPanelElement::defaultEventHandler(Event* event)
-{
- MediaControlDivElement::defaultEventHandler(event);
-
- if (event->isMouseEvent()) {
- LayoutPoint location = toMouseEvent(event)->absoluteLocation();
- if (event->type() == EventTypeNames::mousedown && event->target() == this) {
- startDrag(location);
- event->setDefaultHandled();
- } else if (event->type() == EventTypeNames::mousemove && m_isBeingDragged)
- continueDrag(location);
- else if (event->type() == EventTypeNames::mouseup && m_isBeingDragged) {
- continueDrag(location);
- endDrag();
- event->setDefaultHandled();
- }
- }
-}
-
-void MediaControlPanelElement::setCanBeDragged(bool canBeDragged)
-{
- if (m_canBeDragged == canBeDragged)
- return;
-
- m_canBeDragged = canBeDragged;
-
- if (!canBeDragged)
- endDrag();
-}
-
void MediaControlPanelElement::setIsDisplayed(bool isDisplayed)
{
m_isDisplayed = isDisplayed;
@@ -246,18 +150,18 @@ void MediaControlPanelElement::setIsDisplayed(bool isDisplayed)
// ----------------------------
-MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(Document& document)
+MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(MediaControls& mediaControls)
// Mapping onto same MediaControlElementType as panel element, since it has similar properties.
- : MediaControlDivElement(document, MediaControlsPanel)
+ : MediaControlDivElement(mediaControls, MediaControlsPanel)
{
}
-PassRefPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlPanelEnclosureElement(document));
+ return adoptRefWillBeNoop(new MediaControlPanelEnclosureElement(mediaControls));
}
-const AtomicString& MediaControlPanelEnclosureElement::pseudo() const
+const AtomicString& MediaControlPanelEnclosureElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral));
return id;
@@ -265,18 +169,18 @@ const AtomicString& MediaControlPanelEnclosureElement::pseudo() const
// ----------------------------
-MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(Document& document)
+MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(MediaControls& mediaControls)
// Mapping onto same MediaControlElementType as panel element, since it has similar properties.
- : MediaControlDivElement(document, MediaControlsPanel)
+ : MediaControlDivElement(mediaControls, MediaControlsPanel)
{
}
-PassRefPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlOverlayEnclosureElement(document));
+ return adoptRefWillBeNoop(new MediaControlOverlayEnclosureElement(mediaControls));
}
-const AtomicString& MediaControlOverlayEnclosureElement::pseudo() const
+const AtomicString& MediaControlOverlayEnclosureElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral));
return id;
@@ -284,67 +188,50 @@ const AtomicString& MediaControlOverlayEnclosureElement::pseudo() const
// ----------------------------
-MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(Document& document, MediaControls* controls)
- : MediaControlMuteButtonElement(document, MediaMuteButton)
- , m_controls(controls)
+MediaControlMuteButtonElement::MediaControlMuteButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaMuteButton)
{
}
-PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtrWillBeRawPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(MediaControls& mediaControls)
{
- ASSERT(controls);
-
- RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls));
+ RefPtrWillBeRawPtr<MediaControlMuteButtonElement> button = adoptRefWillBeNoop(new MediaControlMuteButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
return button.release();
}
-void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
+void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
{
- if (event->type() == EventTypeNames::mouseover)
- m_controls->showVolumeSlider();
-
- MediaControlMuteButtonElement::defaultEventHandler(event);
-}
-
-const AtomicString& MediaControlPanelMuteButtonElement::pseudo() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
- return id;
-}
-
-// ----------------------------
+ if (event->type() == EventTypeNames::click) {
+ mediaElement().setMuted(!mediaElement().muted());
+ event->setDefaultHandled();
+ }
-MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(Document& document)
- : MediaControlMuteButtonElement(document, MediaMuteButton)
-{
+ HTMLInputElement::defaultEventHandler(event);
}
-PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document)
+void MediaControlMuteButtonElement::updateDisplayType()
{
- RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(document));
- button->ensureUserAgentShadowRoot();
- button->setType("button");
- return button.release();
+ setDisplayType(mediaElement().muted() ? MediaUnMuteButton : MediaMuteButton);
}
-const AtomicString& MediaControlVolumeSliderMuteButtonElement::pseudo() const
+const AtomicString& MediaControlMuteButtonElement::shadowPseudoId() const
{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
return id;
}
// ----------------------------
-MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document& document)
- : MediaControlInputElement(document, MediaPlayButton)
+MediaControlPlayButtonElement::MediaControlPlayButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaPlayButton)
{
}
-PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(document));
+ RefPtrWillBeRawPtr<MediaControlPlayButtonElement> button = adoptRefWillBeNoop(new MediaControlPlayButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
return button.release();
@@ -353,10 +240,7 @@ PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(
void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::click) {
- if (mediaController()->canPlay())
- mediaController()->play();
- else
- mediaController()->pause();
+ mediaElement().togglePlayState();
updateDisplayType();
event->setDefaultHandled();
}
@@ -365,10 +249,10 @@ void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
void MediaControlPlayButtonElement::updateDisplayType()
{
- setDisplayType(mediaController()->canPlay() ? MediaPlayButton : MediaPauseButton);
+ setDisplayType(mediaElement().togglePlayStateWillPlay() ? MediaPlayButton : MediaPauseButton);
}
-const AtomicString& MediaControlPlayButtonElement::pseudo() const
+const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral));
return id;
@@ -376,14 +260,14 @@ const AtomicString& MediaControlPlayButtonElement::pseudo() const
// ----------------------------
-MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(Document& document)
- : MediaControlInputElement(document, MediaOverlayPlayButton)
+MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaOverlayPlayButton)
{
}
-PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(document));
+ RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> button = adoptRefWillBeNoop(new MediaControlOverlayPlayButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
return button.release();
@@ -391,23 +275,22 @@ PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonEl
void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event* event)
{
- if (event->type() == EventTypeNames::click && mediaController()->canPlay()) {
- mediaController()->play();
+ if (event->type() == EventTypeNames::click && mediaElement().togglePlayStateWillPlay()) {
+ mediaElement().togglePlayState();
updateDisplayType();
event->setDefaultHandled();
}
- HTMLInputElement::defaultEventHandler(event);
}
void MediaControlOverlayPlayButtonElement::updateDisplayType()
{
- if (mediaController()->canPlay()) {
+ if (mediaElement().togglePlayStateWillPlay()) {
show();
} else
hide();
}
-const AtomicString& MediaControlOverlayPlayButtonElement::pseudo() const
+const AtomicString& MediaControlOverlayPlayButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral));
return id;
@@ -416,16 +299,14 @@ const AtomicString& MediaControlOverlayPlayButtonElement::pseudo() const
// ----------------------------
-MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document& document, MediaControls*)
- : MediaControlInputElement(document, MediaShowClosedCaptionsButton)
+MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaShowClosedCaptionsButton)
{
}
-PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(MediaControls& mediaControls)
{
- ASSERT(controls);
-
- RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls));
+ RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRefWillBeNoop(new MediaControlToggleClosedCaptionsButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
@@ -434,7 +315,7 @@ PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClos
void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
{
- bool captionsVisible = mediaController()->closedCaptionsVisible();
+ bool captionsVisible = mediaElement().closedCaptionsVisible();
setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
setChecked(captionsVisible);
}
@@ -442,8 +323,8 @@ void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::click) {
- mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible());
- setChecked(mediaController()->closedCaptionsVisible());
+ mediaElement().setClosedCaptionsVisible(!mediaElement().closedCaptionsVisible());
+ setChecked(mediaElement().closedCaptionsVisible());
updateDisplayType();
event->setDefaultHandled();
}
@@ -451,7 +332,7 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e
HTMLInputElement::defaultEventHandler(event);
}
-const AtomicString& MediaControlToggleClosedCaptionsButtonElement::pseudo() const
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
return id;
@@ -459,17 +340,14 @@ const AtomicString& MediaControlToggleClosedCaptionsButtonElement::pseudo() cons
// ----------------------------
-MediaControlTimelineElement::MediaControlTimelineElement(Document& document, MediaControls* controls)
- : MediaControlInputElement(document, MediaSlider)
- , m_controls(controls)
+MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaSlider)
{
}
-PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls)
+PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(MediaControls& mediaControls)
{
- ASSERT(controls);
-
- RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(document, controls));
+ RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoop(new MediaControlTimelineElement(mediaControls));
timeline->ensureUserAgentShadowRoot();
timeline->setType("range");
timeline->setAttribute(stepAttr, "any");
@@ -478,18 +356,17 @@ PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Docu
void MediaControlTimelineElement::defaultEventHandler(Event* event)
{
- // Left button is 0. Rejects mouse events not from left button.
- if (event->isMouseEvent() && toMouseEvent(event)->button())
+ if (event->isMouseEvent() && toMouseEvent(event)->button() != LeftButton)
return;
if (!inDocument() || !document().isActive())
return;
if (event->type() == EventTypeNames::mousedown)
- mediaController()->beginScrubbing();
+ mediaControls().beginScrubbing();
if (event->type() == EventTypeNames::mouseup)
- mediaController()->endScrubbing();
+ mediaControls().endScrubbing();
MediaControlInputElement::defaultEventHandler(event);
@@ -497,12 +374,18 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
return;
double time = value().toDouble();
- if (event->type() == EventTypeNames::input && time != mediaController()->currentTime())
- mediaController()->setCurrentTime(time, IGNORE_EXCEPTION);
+ if (event->type() == EventTypeNames::input) {
+ // FIXME: This will need to take the timeline offset into consideration
+ // once that concept is supported, see https://crbug.com/312699
+ if (mediaElement().controller())
+ mediaElement().controller()->setCurrentTime(time, IGNORE_EXCEPTION);
+ else
+ mediaElement().setCurrentTime(time, IGNORE_EXCEPTION);
+ }
RenderSlider* slider = toRenderSlider(renderer());
if (slider && slider->inDragMode())
- m_controls->updateCurrentTimeDisplay();
+ mediaControls().updateCurrentTimeDisplay();
}
bool MediaControlTimelineElement::willRespondToMouseClickEvents()
@@ -521,7 +404,7 @@ void MediaControlTimelineElement::setDuration(double duration)
}
-const AtomicString& MediaControlTimelineElement::pseudo() const
+const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral));
return id;
@@ -529,14 +412,14 @@ const AtomicString& MediaControlTimelineElement::pseudo() const
// ----------------------------
-MediaControlPanelVolumeSliderElement::MediaControlPanelVolumeSliderElement(Document& document)
- : MediaControlVolumeSliderElement(document)
+MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaVolumeSlider)
{
}
-PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlPanelVolumeSliderElement> slider = adoptRef(new MediaControlPanelVolumeSliderElement(document));
+ RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = adoptRefWillBeNoop(new MediaControlVolumeSliderElement(mediaControls));
slider->ensureUserAgentShadowRoot();
slider->setType("range");
slider->setAttribute(stepAttr, "any");
@@ -544,7 +427,47 @@ PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderEl
return slider.release();
}
-const AtomicString& MediaControlPanelVolumeSliderElement::pseudo() const
+void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
+{
+ if (event->isMouseEvent() && toMouseEvent(event)->button() != LeftButton)
+ return;
+
+ if (!inDocument() || !document().isActive())
+ return;
+
+ MediaControlInputElement::defaultEventHandler(event);
+
+ if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
+ return;
+
+ double volume = value().toDouble();
+ mediaElement().setVolume(volume, ASSERT_NO_EXCEPTION);
+ mediaElement().setMuted(false);
+}
+
+bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
+{
+ if (!inDocument() || !document().isActive())
+ return false;
+
+ return MediaControlInputElement::willRespondToMouseMoveEvents();
+}
+
+bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
+{
+ if (!inDocument() || !document().isActive())
+ return false;
+
+ return MediaControlInputElement::willRespondToMouseClickEvents();
+}
+
+void MediaControlVolumeSliderElement::setVolume(double volume)
+{
+ if (value().toDouble() != volume)
+ setValue(String::number(volume));
+}
+
+const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral));
return id;
@@ -552,14 +475,14 @@ const AtomicString& MediaControlPanelVolumeSliderElement::pseudo() const
// ----------------------------
-MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document& document)
- : MediaControlInputElement(document, MediaEnterFullscreenButton)
+MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaEnterFullscreenButton)
{
}
-PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(document));
+ RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> button = adoptRefWillBeNoop(new MediaControlFullscreenButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
@@ -569,24 +492,16 @@ PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElem
void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::click) {
- // Only use the new full screen API if the fullScreenEnabled setting has
- // been explicitly enabled. Otherwise, use the old fullscreen API. This
- // allows apps which embed a WebView to retain the existing full screen
- // video implementation without requiring them to implement their own full
- // screen behavior.
- if (document().settings() && document().settings()->fullScreenEnabled()) {
- if (FullscreenElementStack::isActiveFullScreenElement(toParentMediaElement(this)))
- FullscreenElementStack::from(&document())->webkitCancelFullScreen();
- else
- FullscreenElementStack::from(&document())->requestFullScreenForElement(toParentMediaElement(this), 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
- } else
- mediaController()->enterFullscreen();
+ if (FullscreenElementStack::isActiveFullScreenElement(&mediaElement()))
+ FullscreenElementStack::from(document()).webkitCancelFullScreen();
+ else
+ FullscreenElementStack::from(document()).requestFullScreenForElement(&mediaElement(), 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
event->setDefaultHandled();
}
HTMLInputElement::defaultEventHandler(event);
}
-const AtomicString& MediaControlFullscreenButtonElement::pseudo() const
+const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral));
return id;
@@ -599,14 +514,14 @@ void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen)
// ----------------------------
-MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(Document& document)
- : MediaControlTimeDisplayElement(document, MediaTimeRemainingDisplay)
+MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(MediaControls& mediaControls)
+ : MediaControlTimeDisplayElement(mediaControls, MediaTimeRemainingDisplay)
{
}
-PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlTimeRemainingDisplayElement(document));
+ return adoptRefWillBeNoop(new MediaControlTimeRemainingDisplayElement(mediaControls));
}
static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId()
@@ -615,21 +530,21 @@ static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseud
return id;
}
-const AtomicString& MediaControlTimeRemainingDisplayElement::pseudo() const
+const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const
{
return getMediaControlTimeRemainingDisplayElementShadowPseudoId();
}
// ----------------------------
-MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(Document& document)
- : MediaControlTimeDisplayElement(document, MediaCurrentTimeDisplay)
+MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(MediaControls& mediaControls)
+ : MediaControlTimeDisplayElement(mediaControls, MediaCurrentTimeDisplay)
{
}
-PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlCurrentTimeDisplayElement(document));
+ return adoptRefWillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls));
}
static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId()
@@ -638,22 +553,22 @@ static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoI
return id;
}
-const AtomicString& MediaControlCurrentTimeDisplayElement::pseudo() const
+const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const
{
return getMediaControlCurrentTimeDisplayElementShadowPseudoId();
}
// ----------------------------
-MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document)
- : MediaControlDivElement(document, MediaTextTrackDisplayContainer)
+MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(MediaControls& mediaControls)
+ : MediaControlDivElement(mediaControls, MediaTextTrackDisplayContainer)
, m_fontSize(0)
{
}
-PassRefPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlTextTrackContainerElement> element = adoptRef(new MediaControlTextTrackContainerElement(document));
+ RefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> element = adoptRefWillBeNoop(new MediaControlTextTrackContainerElement(mediaControls));
element->hide();
return element.release();
}
@@ -669,30 +584,28 @@ const AtomicString& MediaControlTextTrackContainerElement::textTrackContainerEle
return id;
}
-const AtomicString& MediaControlTextTrackContainerElement::pseudo() const
+const AtomicString& MediaControlTextTrackContainerElement::shadowPseudoId() const
{
return textTrackContainerElementShadowPseudoId();
}
void MediaControlTextTrackContainerElement::updateDisplay()
{
- if (!mediaController()->closedCaptionsVisible()) {
+ if (!mediaElement().closedCaptionsVisible()) {
removeChildren();
return;
}
- HTMLMediaElement* mediaElement = toParentMediaElement(this);
// 1. If the media element is an audio element, or is another playback
// mechanism with no rendering area, abort these steps. There is nothing to
// render.
- if (!mediaElement || !mediaElement->isVideo())
+ if (isHTMLAudioElement(mediaElement()))
return;
// 2. Let video be the media element or other playback mechanism.
- HTMLVideoElement* video = toHTMLVideoElement(mediaElement);
+ HTMLVideoElement& video = toHTMLVideoElement(mediaElement());
// 3. Let output be an empty list of absolutely positioned CSS block boxes.
- Vector<RefPtr<HTMLDivElement> > output;
// 4. If the user agent is exposing a user interface for video, add to
// output one or more completely transparent positioned CSS block boxes that
@@ -713,7 +626,7 @@ void MediaControlTextTrackContainerElement::updateDisplay()
// 7. Let cues be an empty list of text track cues.
// 8. For each track track in tracks, append to cues all the cues from
// track's list of cues that have their text track cue active flag set.
- CueList activeCues = video->currentlyActiveCues();
+ CueList activeCues = video.currentlyActiveCues();
// 9. If reset is false, then, for each text track cue cue in cues: if cue's
// text track cue display state has a set of CSS boxes, then add those boxes
@@ -737,28 +650,24 @@ void MediaControlTextTrackContainerElement::updateDisplay()
}
// 11. Return output.
- if (hasChildNodes())
+ if (hasChildren())
show();
else
hide();
}
-void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate)
+void MediaControlTextTrackContainerElement::updateSizes()
{
- HTMLMediaElement* mediaElement = toParentMediaElement(this);
- if (!mediaElement)
- return;
-
if (!document().isActive())
return;
IntRect videoBox;
- if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo())
+ if (!mediaElement().renderer() || !mediaElement().renderer()->isVideo())
return;
- videoBox = toRenderVideo(mediaElement->renderer())->videoBox();
+ videoBox = toRenderVideo(mediaElement().renderer())->videoBox();
- if (!forceUpdate && m_videoDisplaySize == videoBox)
+ if (m_videoDisplaySize == videoBox)
return;
m_videoDisplaySize = videoBox;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h
index 3d631dbb9b9..06c03206b75 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h
@@ -38,40 +38,25 @@ namespace WebCore {
class MediaControlPanelElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlPanelElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlPanelElement> create(MediaControls&);
- void setCanBeDragged(bool);
void setIsDisplayed(bool);
- void resetPosition();
void makeOpaque();
void makeTransparent();
- virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
- virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
-
private:
- explicit MediaControlPanelElement(Document&);
+ explicit MediaControlPanelElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
- void startDrag(const LayoutPoint& eventLocation);
- void continueDrag(const LayoutPoint& eventLocation);
- void endDrag();
-
void startTimer();
void stopTimer();
void transitionTimerFired(Timer<MediaControlPanelElement>*);
- void setPosition(const LayoutPoint&);
-
- bool m_canBeDragged;
- bool m_isBeingDragged;
bool m_isDisplayed;
bool m_opaque;
- LayoutPoint m_lastDragEventLocation;
- LayoutPoint m_cumulativeDragOffset;
Timer<MediaControlPanelElement> m_transitionTimer;
};
@@ -80,66 +65,53 @@ private:
class MediaControlPanelEnclosureElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlPanelEnclosureElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> create(MediaControls&);
private:
- explicit MediaControlPanelEnclosureElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlPanelEnclosureElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
class MediaControlOverlayEnclosureElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlOverlayEnclosureElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> create(MediaControls&);
private:
- explicit MediaControlOverlayEnclosureElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlOverlayEnclosureElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
-class MediaControlPanelMuteButtonElement FINAL : public MediaControlMuteButtonElement {
+class MediaControlMuteButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlPanelMuteButtonElement> create(Document&, MediaControls*);
+ static PassRefPtrWillBeRawPtr<MediaControlMuteButtonElement> create(MediaControls&);
- virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+ virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
+ virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlPanelMuteButtonElement(Document&, MediaControls*);
+ explicit MediaControlMuteButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
-
- MediaControls* m_controls;
-};
-
-// ----------------------------
-
-class MediaControlVolumeSliderMuteButtonElement FINAL : public MediaControlMuteButtonElement {
-public:
- static PassRefPtr<MediaControlVolumeSliderMuteButtonElement> create(Document&);
-
-private:
- explicit MediaControlVolumeSliderMuteButtonElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
};
-
// ----------------------------
class MediaControlPlayButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlPlayButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlPlayButtonElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlPlayButtonElement(Document&);
+ explicit MediaControlPlayButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
@@ -147,14 +119,14 @@ private:
class MediaControlOverlayPlayButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlOverlayPlayButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> create(MediaControls&);
virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlOverlayPlayButtonElement(Document&);
+ explicit MediaControlOverlayPlayButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
@@ -162,16 +134,16 @@ private:
class MediaControlToggleClosedCaptionsButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(Document&, MediaControls*);
+ static PassRefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlToggleClosedCaptionsButtonElement(Document&, MediaControls*);
+ explicit MediaControlToggleClosedCaptionsButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
@@ -179,87 +151,93 @@ private:
class MediaControlTimelineElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlTimelineElement> create(Document&, MediaControls*);
+ static PassRefPtrWillBeRawPtr<MediaControlTimelineElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ // FIXME: An "earliest possible position" will be needed once that concept
+ // is supported by HTMLMediaElement, see https://crbug.com/137275
void setPosition(double);
void setDuration(double);
private:
- explicit MediaControlTimelineElement(Document&, MediaControls*);
+ explicit MediaControlTimelineElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
-
- MediaControls* m_controls;
};
// ----------------------------
class MediaControlFullscreenButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlFullscreenButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
- virtual void setIsFullscreen(bool);
+ void setIsFullscreen(bool);
private:
- explicit MediaControlFullscreenButtonElement(Document&);
+ explicit MediaControlFullscreenButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
// ----------------------------
-class MediaControlPanelVolumeSliderElement FINAL : public MediaControlVolumeSliderElement {
+class MediaControlVolumeSliderElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlPanelVolumeSliderElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlVolumeSliderElement> create(MediaControls&);
+
+ virtual bool willRespondToMouseMoveEvents() OVERRIDE;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ void setVolume(double);
private:
- explicit MediaControlPanelVolumeSliderElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlVolumeSliderElement(MediaControls&);
+
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
+ virtual void defaultEventHandler(Event*) OVERRIDE;
};
// ----------------------------
class MediaControlTimeRemainingDisplayElement FINAL : public MediaControlTimeDisplayElement {
public:
- static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> create(MediaControls&);
private:
- explicit MediaControlTimeRemainingDisplayElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlTimeRemainingDisplayElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
class MediaControlCurrentTimeDisplayElement FINAL : public MediaControlTimeDisplayElement {
public:
- static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> create(MediaControls&);
private:
- explicit MediaControlCurrentTimeDisplayElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlCurrentTimeDisplayElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
class MediaControlTextTrackContainerElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlTextTrackContainerElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> create(MediaControls&);
void updateDisplay();
- void updateSizes(bool forceUpdate = false);
+ void updateSizes();
static const AtomicString& textTrackContainerElementShadowPseudoId();
private:
- explicit MediaControlTextTrackContainerElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlTextTrackContainerElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
IntRect m_videoDisplaySize;
float m_fontSize;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
index 0e2fa811fba..a82cf61a972 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -28,118 +28,162 @@
#include "core/html/shadow/MediaControls.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/events/MouseEvent.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/MediaController.h"
+#include "core/rendering/RenderTheme.h"
namespace WebCore {
-static const double timeWithoutMouseMovementBeforeHidingFullscreenControls = 3;
-
-MediaControls::MediaControls(Document& document)
- : HTMLDivElement(document)
- , m_mediaController(0)
- , m_panel(0)
- , m_textDisplayContainer(0)
- , m_playButton(0)
- , m_currentTimeDisplay(0)
- , m_timeline(0)
- , m_panelMuteButton(0)
- , m_volumeSlider(0)
- , m_toggleClosedCaptionsButton(0)
- , m_fullScreenButton(0)
- , m_hideFullscreenControlsTimer(this, &MediaControls::hideFullscreenControlsTimerFired)
- , m_isFullscreen(false)
+// If you change this value, then also update the corresponding value in
+// LayoutTests/media/media-controls.js.
+static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3;
+
+MediaControls::MediaControls(HTMLMediaElement& mediaElement)
+ : HTMLDivElement(mediaElement.document())
+ , m_mediaElement(&mediaElement)
+ , m_panel(nullptr)
+ , m_textDisplayContainer(nullptr)
+ , m_overlayPlayButton(nullptr)
+ , m_overlayEnclosure(nullptr)
+ , m_playButton(nullptr)
+ , m_currentTimeDisplay(nullptr)
+ , m_timeline(nullptr)
+ , m_muteButton(nullptr)
+ , m_volumeSlider(nullptr)
+ , m_toggleClosedCaptionsButton(nullptr)
+ , m_fullScreenButton(nullptr)
+ , m_durationDisplay(nullptr)
+ , m_enclosure(nullptr)
+ , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired)
, m_isMouseOverControls(false)
+ , m_isPausedForScrubbing(false)
{
}
-void MediaControls::setMediaController(MediaControllerInterface* controller)
+PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& mediaElement)
{
- if (m_mediaController == controller)
- return;
- m_mediaController = controller;
+ RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaControls(mediaElement));
- if (m_panel)
- m_panel->setMediaController(controller);
- if (m_textDisplayContainer)
- m_textDisplayContainer->setMediaController(controller);
- if (m_playButton)
- m_playButton->setMediaController(controller);
- if (m_currentTimeDisplay)
- m_currentTimeDisplay->setMediaController(controller);
- if (m_timeline)
- m_timeline->setMediaController(controller);
- if (m_panelMuteButton)
- m_panelMuteButton->setMediaController(controller);
- if (m_volumeSlider)
- m_volumeSlider->setMediaController(controller);
- if (m_toggleClosedCaptionsButton)
- m_toggleClosedCaptionsButton->setMediaController(controller);
- if (m_fullScreenButton)
- m_fullScreenButton->setMediaController(controller);
+ if (controls->initializeControls())
+ return controls.release();
+
+ return nullptr;
}
-void MediaControls::reset()
+bool MediaControls::initializeControls()
{
- Page* page = document().page();
- if (!page)
- return;
+ TrackExceptionState exceptionState;
- m_playButton->updateDisplayType();
+ if (document().settings() && document().settings()->mediaControlsOverlayPlayButtonEnabled()) {
+ RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(*this);
+ RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(*this);
+ m_overlayPlayButton = overlayPlayButton.get();
+ overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
- updateCurrentTimeDisplay();
-
- double duration = m_mediaController->duration();
- if (std::isfinite(duration) || RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
- m_timeline->setDuration(duration);
- m_timeline->setPosition(m_mediaController->currentTime());
+ m_overlayEnclosure = overlayEnclosure.get();
+ appendChild(overlayEnclosure.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
}
- if (m_mediaController->hasAudio() || RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
- m_panelMuteButton->show();
- else
- m_panelMuteButton->hide();
-
- if (m_volumeSlider) {
- if (!m_mediaController->hasAudio())
- m_volumeSlider->hide();
- else {
- m_volumeSlider->show();
- m_volumeSlider->setVolume(m_mediaController->volume());
- }
- }
+ // Create an enclosing element for the panel so we can visually offset the controls correctly.
+ RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(*this);
- refreshClosedCaptionsButtonVisibility();
+ RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(*this);
- if (m_fullScreenButton) {
- if (m_mediaController->supportsFullscreen() && m_mediaController->hasVideo())
- m_fullScreenButton->show();
- else
- m_fullScreenButton->hide();
- }
+ RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(*this);
+ m_playButton = playButton.get();
+ panel->appendChild(playButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
- makeOpaque();
+ RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(*this);
+ m_timeline = timeline.get();
+ panel->appendChild(timeline.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
+ m_currentTimeDisplay = currentTimeDisplay.get();
+ m_currentTimeDisplay->hide();
+ panel->appendChild(currentTimeDisplay.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
+ m_durationDisplay = durationDisplay.get();
+ panel->appendChild(durationDisplay.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlMuteButtonElement::create(*this);
+ m_muteButton = muteButton.get();
+ panel->appendChild(muteButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(*this);
+ m_volumeSlider = slider.get();
+ panel->appendChild(slider.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
+ m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
+ panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(*this);
+ m_fullScreenButton = fullscreenButton.get();
+ panel->appendChild(fullscreenButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ m_panel = panel.get();
+ enclosure->appendChild(panel.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ m_enclosure = enclosure.get();
+ appendChild(enclosure.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ return true;
}
-void MediaControls::reportedError()
+void MediaControls::reset()
{
- Page* page = document().page();
- if (!page)
- return;
+ double duration = mediaElement().duration();
+ m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
+ m_durationDisplay->setCurrentValue(duration);
+
+ updatePlayState();
+
+ updateCurrentTimeDisplay();
- if (!RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart)) {
- m_panelMuteButton->hide();
+ m_timeline->setDuration(duration);
+ m_timeline->setPosition(mediaElement().currentTime());
+
+ if (!mediaElement().hasAudio())
m_volumeSlider->hide();
- }
+ else
+ m_volumeSlider->show();
+ updateVolume();
- if (m_toggleClosedCaptionsButton && !RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
- m_toggleClosedCaptionsButton->hide();
+ refreshClosedCaptionsButtonVisibility();
- if (m_fullScreenButton && !RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaEnterFullscreenButtonPart))
+ if (mediaElement().hasVideo())
+ m_fullScreenButton->show();
+ else
m_fullScreenButton->hide();
-}
-void MediaControls::loadedMetadata()
-{
- reset();
+ makeOpaque();
}
void MediaControls::show()
@@ -149,6 +193,12 @@ void MediaControls::show()
m_panel->show();
}
+void MediaControls::mediaElementFocused()
+{
+ show();
+ stopHideMediaControlsTimer();
+}
+
void MediaControls::hide()
{
m_panel->setIsDisplayed(false);
@@ -165,81 +215,118 @@ void MediaControls::makeTransparent()
m_panel->makeTransparent();
}
-bool MediaControls::shouldHideControls()
+bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const
{
- return !m_panel->hovered();
-}
-
-void MediaControls::bufferingProgressed()
-{
- // We only need to update buffering progress when paused, during normal
- // playback playbackProgressed() will take care of it.
- if (m_mediaController->paused())
- m_timeline->setPosition(m_mediaController->currentTime());
+ // Never hide for a media element without visual representation.
+ if (!mediaElement().hasVideo())
+ return false;
+ // Don't hide if the controls are hovered or the mouse is over the video area.
+ const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover;
+ if (m_panel->hovered() || (!ignoreVideoHover && m_isMouseOverControls))
+ return false;
+ // Don't hide if focus is on the HTMLMediaElement or within the
+ // controls/shadow tree. (Perform the checks separately to avoid going
+ // through all the potential ancestor hosts for the focused element.)
+ const bool ignoreFocus = behaviorFlags & IgnoreFocus;
+ if (!ignoreFocus && (mediaElement().focused() || contains(document().focusedElement())))
+ return false;
+ return true;
}
void MediaControls::playbackStarted()
{
- m_playButton->updateDisplayType();
- m_timeline->setPosition(m_mediaController->currentTime());
+ m_currentTimeDisplay->show();
+ m_durationDisplay->hide();
+
+ updatePlayState();
+ m_timeline->setPosition(mediaElement().currentTime());
updateCurrentTimeDisplay();
- if (m_isFullscreen)
- startHideFullscreenControlsTimer();
+ startHideMediaControlsTimer();
}
void MediaControls::playbackProgressed()
{
- m_timeline->setPosition(m_mediaController->currentTime());
+ m_timeline->setPosition(mediaElement().currentTime());
updateCurrentTimeDisplay();
- if (!m_isMouseOverControls && m_mediaController->hasVideo())
+ if (shouldHideMediaControls())
makeTransparent();
}
void MediaControls::playbackStopped()
{
- m_playButton->updateDisplayType();
- m_timeline->setPosition(m_mediaController->currentTime());
+ updatePlayState();
+ m_timeline->setPosition(mediaElement().currentTime());
updateCurrentTimeDisplay();
makeOpaque();
- stopHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
}
-void MediaControls::showVolumeSlider()
+void MediaControls::updatePlayState()
{
- if (!m_mediaController->hasAudio())
+ if (m_isPausedForScrubbing)
return;
- m_volumeSlider->show();
+ if (m_overlayPlayButton)
+ m_overlayPlayButton->updateDisplayType();
+ m_playButton->updateDisplayType();
}
-void MediaControls::changedMute()
+void MediaControls::beginScrubbing()
{
- m_panelMuteButton->changedMute();
+ if (!mediaElement().togglePlayStateWillPlay()) {
+ m_isPausedForScrubbing = true;
+ mediaElement().togglePlayState();
+ }
}
-void MediaControls::changedVolume()
+void MediaControls::endScrubbing()
{
- if (m_volumeSlider)
- m_volumeSlider->setVolume(m_mediaController->volume());
- if (m_panelMuteButton && m_panelMuteButton->renderer())
- m_panelMuteButton->renderer()->repaint();
+ if (m_isPausedForScrubbing) {
+ m_isPausedForScrubbing = false;
+ if (mediaElement().togglePlayStateWillPlay())
+ mediaElement().togglePlayState();
+ }
+}
+
+void MediaControls::updateCurrentTimeDisplay()
+{
+ double now = mediaElement().currentTime();
+ double duration = mediaElement().duration();
+
+ // After seek, hide duration display and show current time.
+ if (now > 0) {
+ m_currentTimeDisplay->show();
+ m_durationDisplay->hide();
+ }
+
+ // Allow the theme to format the time.
+ m_currentTimeDisplay->setInnerText(RenderTheme::theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION);
+ m_currentTimeDisplay->setCurrentValue(now);
+}
+
+void MediaControls::updateVolume()
+{
+ m_muteButton->updateDisplayType();
+ if (m_muteButton->renderer())
+ m_muteButton->renderer()->paintInvalidationForWholeRenderer();
+
+ if (mediaElement().muted())
+ m_volumeSlider->setVolume(0);
+ else
+ m_volumeSlider->setVolume(mediaElement().volume());
}
void MediaControls::changedClosedCaptionsVisibility()
{
- if (m_toggleClosedCaptionsButton)
- m_toggleClosedCaptionsButton->updateDisplayType();
+ m_toggleClosedCaptionsButton->updateDisplayType();
}
void MediaControls::refreshClosedCaptionsButtonVisibility()
{
- if (!m_toggleClosedCaptionsButton)
- return;
-
- if (m_mediaController->hasClosedCaptions())
+ if (mediaElement().hasClosedCaptions())
m_toggleClosedCaptionsButton->show();
else
m_toggleClosedCaptionsButton->hide();
@@ -252,16 +339,16 @@ void MediaControls::closedCaptionTracksChanged()
void MediaControls::enteredFullscreen()
{
- m_isFullscreen = true;
m_fullScreenButton->setIsFullscreen(true);
- startHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
+ startHideMediaControlsTimer();
}
void MediaControls::exitedFullscreen()
{
- m_isFullscreen = false;
m_fullScreenButton->setIsFullscreen(false);
- stopHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
+ startHideMediaControlsTimer();
}
void MediaControls::defaultEventHandler(Event* event)
@@ -271,10 +358,10 @@ void MediaControls::defaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mouseover) {
if (!containsRelatedTarget(event)) {
m_isMouseOverControls = true;
- if (!m_mediaController->canPlay()) {
+ if (!mediaElement().togglePlayStateWillPlay()) {
makeOpaque();
- if (shouldHideControls())
- startHideFullscreenControlsTimer();
+ if (shouldHideMediaControls())
+ startHideMediaControlsTimer();
}
}
return;
@@ -283,55 +370,43 @@ void MediaControls::defaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mouseout) {
if (!containsRelatedTarget(event)) {
m_isMouseOverControls = false;
- stopHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
}
return;
}
if (event->type() == EventTypeNames::mousemove) {
- if (m_isFullscreen) {
- // When we get a mouse move in fullscreen mode, show the media controls, and start a timer
- // that will hide the media controls after a 3 seconds without a mouse move.
- makeOpaque();
- if (shouldHideControls())
- startHideFullscreenControlsTimer();
- }
+ // When we get a mouse move, show the media controls, and start a timer
+ // that will hide the media controls after a 3 seconds without a mouse move.
+ makeOpaque();
+ if (shouldHideMediaControls(IgnoreVideoHover))
+ startHideMediaControlsTimer();
return;
}
}
-void MediaControls::hideFullscreenControlsTimerFired(Timer<MediaControls>*)
+void MediaControls::hideMediaControlsTimerFired(Timer<MediaControls>*)
{
- if (m_mediaController->paused())
+ if (mediaElement().togglePlayStateWillPlay())
return;
- if (!m_isFullscreen)
- return;
-
- if (!shouldHideControls())
+ if (!shouldHideMediaControls(IgnoreFocus | IgnoreVideoHover))
return;
makeTransparent();
}
-void MediaControls::startHideFullscreenControlsTimer()
+void MediaControls::startHideMediaControlsTimer()
{
- if (!m_isFullscreen)
- return;
-
- Page* page = document().page();
- if (!page)
- return;
-
- m_hideFullscreenControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingFullscreenControls);
+ m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMediaControls, FROM_HERE);
}
-void MediaControls::stopHideFullscreenControlsTimer()
+void MediaControls::stopHideMediaControlsTimer()
{
- m_hideFullscreenControlsTimer.stop();
+ m_hideMediaControlsTimer.stop();
}
-const AtomicString& MediaControls::pseudo() const
+const AtomicString& MediaControls::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
return id;
@@ -352,14 +427,14 @@ void MediaControls::createTextTrackDisplay()
if (m_textDisplayContainer)
return;
- RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
+ RefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(*this);
m_textDisplayContainer = textDisplayContainer.get();
- if (m_mediaController)
- m_textDisplayContainer->setMediaController(m_mediaController);
-
- // Insert it before the first controller element so it always displays behind the controls.
- insertBefore(textDisplayContainer.release(), m_panel, IGNORE_EXCEPTION);
+ // Insert it before (behind) all other control elements.
+ if (m_overlayEnclosure && m_overlayPlayButton)
+ m_overlayEnclosure->insertBefore(textDisplayContainer.release(), m_overlayPlayButton);
+ else
+ insertBefore(textDisplayContainer.release(), m_enclosure);
}
void MediaControls::showTextTrackDisplay()
@@ -384,4 +459,23 @@ void MediaControls::updateTextTrackDisplay()
m_textDisplayContainer->updateDisplay();
}
+void MediaControls::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaElement);
+ visitor->trace(m_panel);
+ visitor->trace(m_textDisplayContainer);
+ visitor->trace(m_overlayPlayButton);
+ visitor->trace(m_overlayEnclosure);
+ visitor->trace(m_playButton);
+ visitor->trace(m_currentTimeDisplay);
+ visitor->trace(m_timeline);
+ visitor->trace(m_muteButton);
+ visitor->trace(m_volumeSlider);
+ visitor->trace(m_toggleClosedCaptionsButton);
+ visitor->trace(m_fullScreenButton);
+ visitor->trace(m_durationDisplay);
+ visitor->trace(m_enclosure);
+ HTMLDivElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h
index ea87254a8e2..7879662b3cb 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h
@@ -27,106 +27,109 @@
#ifndef MediaControls_h
#define MediaControls_h
-#include "core/events/MouseEvent.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/shadow/MediaControlElements.h"
-#include "core/rendering/RenderTheme.h"
namespace WebCore {
class Document;
class Event;
-class MediaPlayer;
-class RenderBox;
-class RenderMedia;
+class MediaControls FINAL : public HTMLDivElement {
+public:
+ static PassRefPtrWillBeRawPtr<MediaControls> create(HTMLMediaElement&);
-// An abstract class with the media control elements that all ports support.
-class MediaControls : public HTMLDivElement {
- public:
- virtual ~MediaControls() {}
+ HTMLMediaElement& mediaElement() const { return *m_mediaElement; }
- // This function is to be implemented in your port-specific media
- // controls implementation since it will return a child instance.
- static PassRefPtr<MediaControls> create(Document&);
+ void reset();
- virtual void setMediaController(MediaControllerInterface*);
+ void show();
+ void hide();
- virtual void reset();
- virtual void reportedError();
- virtual void loadedMetadata();
+ void playbackStarted();
+ void playbackProgressed();
+ void playbackStopped();
- virtual void show();
- virtual void hide();
- virtual void makeOpaque();
- virtual void makeTransparent();
- virtual bool shouldHideControls();
+ void beginScrubbing();
+ void endScrubbing();
- virtual void bufferingProgressed();
- virtual void playbackStarted();
- virtual void playbackProgressed();
- virtual void playbackStopped();
+ void updateCurrentTimeDisplay();
- virtual void updateStatusDisplay() { };
- virtual void updateCurrentTimeDisplay() = 0;
- virtual void showVolumeSlider();
+ void updateVolume();
- virtual void changedMute();
- virtual void changedVolume();
+ void changedClosedCaptionsVisibility();
+ void refreshClosedCaptionsButtonVisibility();
+ void closedCaptionTracksChanged();
- virtual void changedClosedCaptionsVisibility();
- virtual void refreshClosedCaptionsButtonVisibility();
- virtual void closedCaptionTracksChanged();
+ void enteredFullscreen();
+ void exitedFullscreen();
- virtual void enteredFullscreen();
- virtual void exitedFullscreen();
+ void updateTextTrackDisplay();
- virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+ void mediaElementFocused();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit MediaControls(HTMLMediaElement&);
+
+ bool initializeControls();
- virtual void hideFullscreenControlsTimerFired(Timer<MediaControls>*);
- virtual void startHideFullscreenControlsTimer();
- virtual void stopHideFullscreenControlsTimer();
+ void makeOpaque();
+ void makeTransparent();
- virtual void createTextTrackDisplay();
- virtual void showTextTrackDisplay();
- virtual void hideTextTrackDisplay();
- virtual void updateTextTrackDisplay();
+ void updatePlayState();
-protected:
- explicit MediaControls(Document&);
+ enum HideBehaviorFlags {
+ IgnoreVideoHover = 1 << 0,
+ IgnoreFocus = 1 << 1
+ };
- virtual void defaultEventHandler(Event*);
+ bool shouldHideMediaControls(unsigned behaviorFlags = 0) const;
+ void hideMediaControlsTimerFired(Timer<MediaControls>*);
+ void startHideMediaControlsTimer();
+ void stopHideMediaControlsTimer();
- virtual bool containsRelatedTarget(Event*);
+ void createTextTrackDisplay();
+ void showTextTrackDisplay();
+ void hideTextTrackDisplay();
- MediaControllerInterface* m_mediaController;
+ // Node
+ virtual bool isMediaControls() const OVERRIDE { return true; }
+ virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+ virtual void defaultEventHandler(Event*) OVERRIDE;
+ bool containsRelatedTarget(Event*);
+
+ // Element
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
+
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
// Container for the media control elements.
- MediaControlPanelElement* m_panel;
+ RawPtrWillBeMember<MediaControlPanelElement> m_panel;
// Container for the text track cues.
- MediaControlTextTrackContainerElement* m_textDisplayContainer;
+ RawPtrWillBeMember<MediaControlTextTrackContainerElement> m_textDisplayContainer;
// Media control elements.
- MediaControlPlayButtonElement* m_playButton;
- MediaControlCurrentTimeDisplayElement* m_currentTimeDisplay;
- MediaControlTimelineElement* m_timeline;
- MediaControlPanelMuteButtonElement* m_panelMuteButton;
- MediaControlPanelVolumeSliderElement* m_volumeSlider;
- MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
- MediaControlFullscreenButtonElement* m_fullScreenButton;
-
- Timer<MediaControls> m_hideFullscreenControlsTimer;
- bool m_isFullscreen;
- bool m_isMouseOverControls;
-
-private:
- virtual bool isMediaControls() const { return true; }
-
- virtual const AtomicString& pseudo() const;
+ RawPtrWillBeMember<MediaControlOverlayPlayButtonElement> m_overlayPlayButton;
+ RawPtrWillBeMember<MediaControlOverlayEnclosureElement> m_overlayEnclosure;
+ RawPtrWillBeMember<MediaControlPlayButtonElement> m_playButton;
+ RawPtrWillBeMember<MediaControlCurrentTimeDisplayElement> m_currentTimeDisplay;
+ RawPtrWillBeMember<MediaControlTimelineElement> m_timeline;
+ RawPtrWillBeMember<MediaControlMuteButtonElement> m_muteButton;
+ RawPtrWillBeMember<MediaControlVolumeSliderElement> m_volumeSlider;
+ RawPtrWillBeMember<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton;
+ RawPtrWillBeMember<MediaControlFullscreenButtonElement> m_fullScreenButton;
+ RawPtrWillBeMember<MediaControlTimeRemainingDisplayElement> m_durationDisplay;
+ RawPtrWillBeMember<MediaControlPanelEnclosureElement> m_enclosure;
+
+ Timer<MediaControls> m_hideMediaControlsTimer;
+ bool m_isMouseOverControls : 1;
+ bool m_isPausedForScrubbing : 1;
};
-DEFINE_NODE_TYPE_CASTS(MediaControls, isMediaControls());
+DEFINE_ELEMENT_TYPE_CASTS(MediaControls, isMediaControls());
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp
deleted file mode 100644
index d1d4ccbfd40..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED 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 "core/html/shadow/MediaControlsChromium.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-
-using namespace std;
-
-namespace WebCore {
-
-MediaControlsChromium::MediaControlsChromium(Document& document)
- : MediaControls(document)
- , m_durationDisplay(0)
- , m_enclosure(0)
-{
-}
-
-// MediaControls::create() for Android is defined in MediaControlsChromiumAndroid.cpp.
-#if !OS(ANDROID)
-PassRefPtr<MediaControls> MediaControls::create(Document& document)
-{
- return MediaControlsChromium::createControls(document);
-}
-#endif
-
-PassRefPtr<MediaControlsChromium> MediaControlsChromium::createControls(Document& document)
-{
- if (!document.page())
- return 0;
-
- RefPtr<MediaControlsChromium> controls = adoptRef(new MediaControlsChromium(document));
-
- if (controls->initializeControls(document))
- return controls.release();
-
- return 0;
-}
-
-bool MediaControlsChromium::initializeControls(Document& document)
-{
- // Create an enclosing element for the panel so we can visually offset the controls correctly.
- RefPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(document);
-
- RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document);
-
- TrackExceptionState exceptionState;
-
- RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
- m_playButton = playButton.get();
- panel->appendChild(playButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, this);
- m_timeline = timeline.get();
- panel->appendChild(timeline.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document);
- m_currentTimeDisplay = currentTimeDisplay.get();
- m_currentTimeDisplay->hide();
- panel->appendChild(currentTimeDisplay.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(document);
- m_durationDisplay = durationDisplay.get();
- panel->appendChild(durationDisplay.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, this);
- m_panelMuteButton = panelMuteButton.get();
- panel->appendChild(panelMuteButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlPanelVolumeSliderElement> slider = MediaControlPanelVolumeSliderElement::create(document);
- m_volumeSlider = slider.get();
- m_volumeSlider->setClearMutedOnUserInteraction(true);
- panel->appendChild(slider.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- if (RenderTheme::theme().supportsClosedCaptioning()) {
- RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this);
- m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
- panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
- }
-
- RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document);
- m_fullScreenButton = fullscreenButton.get();
- panel->appendChild(fullscreenButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- m_panel = panel.get();
- enclosure->appendChild(panel.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- m_enclosure = enclosure.get();
- appendChild(enclosure.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- return true;
-}
-
-void MediaControlsChromium::setMediaController(MediaControllerInterface* controller)
-{
- if (m_mediaController == controller)
- return;
-
- MediaControls::setMediaController(controller);
-
- if (m_durationDisplay)
- m_durationDisplay->setMediaController(controller);
- if (m_enclosure)
- m_enclosure->setMediaController(controller);
-}
-
-void MediaControlsChromium::reset()
-{
- Page* page = document().page();
- if (!page)
- return;
-
- double duration = m_mediaController->duration();
- m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
- m_durationDisplay->setCurrentValue(duration);
-
- MediaControls::reset();
-}
-
-void MediaControlsChromium::playbackStarted()
-{
- m_currentTimeDisplay->show();
- m_durationDisplay->hide();
-
- MediaControls::playbackStarted();
-}
-
-void MediaControlsChromium::updateCurrentTimeDisplay()
-{
- double now = m_mediaController->currentTime();
- double duration = m_mediaController->duration();
-
- Page* page = document().page();
- if (!page)
- return;
-
- // After seek, hide duration display and show current time.
- if (now > 0) {
- m_currentTimeDisplay->show();
- m_durationDisplay->hide();
- }
-
- // Allow the theme to format the time.
- m_currentTimeDisplay->setInnerText(RenderTheme::theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION);
- m_currentTimeDisplay->setCurrentValue(now);
-}
-
-void MediaControlsChromium::changedMute()
-{
- MediaControls::changedMute();
-
- if (m_mediaController->muted())
- m_volumeSlider->setVolume(0);
- else
- m_volumeSlider->setVolume(m_mediaController->volume());
-}
-
-void MediaControlsChromium::createTextTrackDisplay()
-{
- if (m_textDisplayContainer)
- return;
-
- RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
- m_textDisplayContainer = textDisplayContainer.get();
-
- if (m_mediaController)
- m_textDisplayContainer->setMediaController(m_mediaController);
-
- insertTextTrackContainer(textDisplayContainer.release());
-}
-
-void MediaControlsChromium::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer)
-{
- // Insert it before the first controller element so it always displays behind the controls.
- // In the Chromium case, that's the enclosure element.
- insertBefore(textTrackContainer, m_enclosure);
-}
-
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h
deleted file mode 100644
index 5e3c55e8512..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED 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 MediaControlsChromium_h
-#define MediaControlsChromium_h
-
-#include "core/html/shadow/MediaControls.h"
-
-namespace WebCore {
-
-class MediaControlsChromium : public MediaControls {
-public:
- // Called from port-specific parent create function to create custom controls.
- static PassRefPtr<MediaControlsChromium> createControls(Document&);
-
- virtual void setMediaController(MediaControllerInterface*) OVERRIDE;
-
- virtual void reset() OVERRIDE;
-
- virtual void playbackStarted() OVERRIDE;
-
- void changedMute() OVERRIDE;
-
- virtual void updateCurrentTimeDisplay() OVERRIDE;
-
- void createTextTrackDisplay() OVERRIDE;
-
- virtual void insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement>);
-
-protected:
- explicit MediaControlsChromium(Document&);
-
- bool initializeControls(Document&);
-
-private:
- MediaControlTimeRemainingDisplayElement* m_durationDisplay;
- MediaControlPanelEnclosureElement* m_enclosure;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp
deleted file mode 100644
index f81c9309b37..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED 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 "core/html/shadow/MediaControlsChromiumAndroid.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-
-namespace WebCore {
-
-MediaControlsChromiumAndroid::MediaControlsChromiumAndroid(Document& document)
- : MediaControlsChromium(document)
- , m_overlayPlayButton(0)
- , m_overlayEnclosure(0)
-{
-}
-
-PassRefPtr<MediaControls> MediaControls::create(Document& document)
-{
- return MediaControlsChromiumAndroid::createControls(document);
-}
-
-PassRefPtr<MediaControlsChromiumAndroid> MediaControlsChromiumAndroid::createControls(Document& document)
-{
- if (!document.page())
- return 0;
-
- RefPtr<MediaControlsChromiumAndroid> controls = adoptRef(new MediaControlsChromiumAndroid(document));
-
- TrackExceptionState exceptionState;
-
- RefPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(document);
- RefPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(document);
- controls->m_overlayPlayButton = overlayPlayButton.get();
- overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
-
- controls->m_overlayEnclosure = overlayEnclosure.get();
- controls->appendChild(overlayEnclosure.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
-
- if (controls->initializeControls(document))
- return controls.release();
-
- return 0;
-}
-
-void MediaControlsChromiumAndroid::setMediaController(MediaControllerInterface* controller)
-{
- if (m_overlayPlayButton)
- m_overlayPlayButton->setMediaController(controller);
- if (m_overlayEnclosure)
- m_overlayEnclosure->setMediaController(controller);
- MediaControlsChromium::setMediaController(controller);
-}
-
-void MediaControlsChromiumAndroid::playbackStarted()
-{
- m_overlayPlayButton->updateDisplayType();
- MediaControlsChromium::playbackStarted();
-}
-
-void MediaControlsChromiumAndroid::playbackStopped()
-{
- m_overlayPlayButton->updateDisplayType();
- MediaControlsChromium::playbackStopped();
-}
-
-void MediaControlsChromiumAndroid::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer)
-{
- // Insert it before the overlay play button so it always displays behind it.
- m_overlayEnclosure->insertBefore(textTrackContainer, m_overlayPlayButton);
-}
-}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h
deleted file mode 100644
index 8b8a90069f4..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED 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 MediaControlsChromiumAndroid_h
-#define MediaControlsChromiumAndroid_h
-
-#include "core/html/shadow/MediaControls.h"
-#include "core/html/shadow/MediaControlsChromium.h"
-
-namespace WebCore {
-
-class MediaControlsChromiumAndroid : public MediaControlsChromium {
-public:
- static PassRefPtr<MediaControlsChromiumAndroid> createControls(Document&);
-
- virtual void setMediaController(MediaControllerInterface*) OVERRIDE;
- virtual void playbackStarted() OVERRIDE;
- virtual void playbackStopped() OVERRIDE;
- virtual bool shouldHideControls() OVERRIDE { return true; }
-
- void insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement>) OVERRIDE;
-
-private:
- explicit MediaControlsChromiumAndroid(Document&);
-
- MediaControlOverlayPlayButtonElement* m_overlayPlayButton;
- MediaControlOverlayEnclosureElement* m_overlayEnclosure;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp
index a39c29cdb71..8f8f0cc4671 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp
@@ -32,8 +32,8 @@
#include "core/html/shadow/MeterShadowElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLMeterElement.h"
#include "core/rendering/RenderMeter.h"
#include "core/rendering/RenderTheme.h"
@@ -63,10 +63,10 @@ inline MeterInnerElement::MeterInnerElement(Document& document)
{
}
-PassRefPtr<MeterInnerElement> MeterInnerElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MeterInnerElement> MeterInnerElement::create(Document& document)
{
- RefPtr<MeterInnerElement> element = adoptRef(new MeterInnerElement(document));
- element->setPseudo(AtomicString("-webkit-meter-inner-element", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<MeterInnerElement> element = adoptRefWillBeNoop(new MeterInnerElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-meter-inner-element", AtomicString::ConstructFromLiteral));
return element.release();
}
@@ -89,10 +89,10 @@ inline MeterBarElement::MeterBarElement(Document& document)
{
}
-PassRefPtr<MeterBarElement> MeterBarElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MeterBarElement> MeterBarElement::create(Document& document)
{
- RefPtr<MeterBarElement> element = adoptRef(new MeterBarElement(document));
- element->setPseudo(AtomicString("-webkit-meter-bar", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<MeterBarElement> element = adoptRefWillBeNoop(new MeterBarElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-meter-bar", AtomicString::ConstructFromLiteral));
return element.release();
}
@@ -101,9 +101,9 @@ inline MeterValueElement::MeterValueElement(Document& document)
{
}
-PassRefPtr<MeterValueElement> MeterValueElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MeterValueElement> MeterValueElement::create(Document& document)
{
- RefPtr<MeterValueElement> element = adoptRef(new MeterValueElement(document));
+ RefPtrWillBeRawPtr<MeterValueElement> element = adoptRefWillBeNoop(new MeterValueElement(document));
element->updatePseudo();
return element.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h
index c15bfdcbcb7..22847f7a8f7 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h
@@ -41,39 +41,39 @@ class RenderMeter;
class MeterShadowElement : public HTMLDivElement {
protected:
- MeterShadowElement(Document&);
+ explicit MeterShadowElement(Document&);
HTMLMeterElement* meterElement() const;
private:
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
class MeterInnerElement FINAL : public MeterShadowElement {
public:
- static PassRefPtr<MeterInnerElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MeterInnerElement> create(Document&);
private:
- MeterInnerElement(Document&);
+ explicit MeterInnerElement(Document&);
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
class MeterBarElement FINAL : public MeterShadowElement {
private:
- MeterBarElement(Document&);
+ explicit MeterBarElement(Document&);
public:
- static PassRefPtr<MeterBarElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MeterBarElement> create(Document&);
};
class MeterValueElement FINAL : public MeterShadowElement {
public:
- static PassRefPtr<MeterValueElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MeterValueElement> create(Document&);
void setWidthPercentage(double);
- void updatePseudo() { setPseudo(valuePseudoId()); }
+ void updatePseudo() { setShadowPseudoId(valuePseudoId()); }
private:
- MeterValueElement(Document&);
+ explicit MeterValueElement(Document&);
const AtomicString& valuePseudoId() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp
deleted file mode 100644
index 238c3f41aee..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "core/html/shadow/PasswordGeneratorButtonElement.h"
-
-#include "core/events/Event.h"
-#include "core/dom/NodeRenderStyle.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLInputElement.h"
-#include "core/html/shadow/ShadowElementNames.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "core/rendering/RenderImage.h"
-#include "platform/graphics/Image.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-PasswordGeneratorButtonElement::PasswordGeneratorButtonElement(Document& document)
- : HTMLDivElement(document)
- , m_isInHoverState(false)
-{
- setHasCustomStyleCallbacks();
-}
-
-PassRefPtr<PasswordGeneratorButtonElement> PasswordGeneratorButtonElement::create(Document& document)
-{
- RefPtr<PasswordGeneratorButtonElement> element = adoptRef(new PasswordGeneratorButtonElement(document));
- element->setAttribute(idAttr, ShadowElementNames::passwordGenerator());
- return element.release();
-}
-
-inline HTMLInputElement* PasswordGeneratorButtonElement::hostInput()
-{
- // PasswordGeneratorButtonElement is created only by C++ code, and it is always
- // in <input> shadow.
- return toHTMLInputElement(shadowHost());
-}
-
-void PasswordGeneratorButtonElement::updateImage()
-{
- if (!renderer() || !renderer()->isImage())
- return;
- RenderImageResource* resource = toRenderImage(renderer())->imageResource();
- ImageResource* image = m_isInHoverState ? imageForHoverState() : imageForNormalState();
- ASSERT(image);
- resource->setImageResource(image);
-}
-
-PassRefPtr<RenderStyle> PasswordGeneratorButtonElement::customStyleForRenderer()
-{
- RefPtr<RenderStyle> originalStyle = originalStyleForRenderer();
- RefPtr<RenderStyle> style = RenderStyle::clone(originalStyle.get());
- RenderStyle* inputStyle = hostInput()->renderStyle();
- ASSERT(inputStyle);
- style->setWidth(Length(inputStyle->fontSize(), Fixed));
- style->setHeight(Length(inputStyle->fontSize(), Fixed));
- style->setUnique();
- updateImage();
- return style.release();
-}
-
-RenderObject* PasswordGeneratorButtonElement::createRenderer(RenderStyle*)
-{
- RenderImage* image = new RenderImage(this);
- image->setImageResource(RenderImageResource::create());
- return image;
-}
-
-void PasswordGeneratorButtonElement::attach(const AttachContext& context)
-{
- HTMLDivElement::attach(context);
- updateImage();
-}
-
-ImageResource* PasswordGeneratorButtonElement::imageForNormalState()
-{
- if (!m_cachedImageForNormalState) {
- RefPtr<Image> image = Image::loadPlatformResource("generatePassword");
- m_cachedImageForNormalState = new ImageResource(image.get());
- }
- return m_cachedImageForNormalState.get();
-}
-
-ImageResource* PasswordGeneratorButtonElement::imageForHoverState()
-{
- if (!m_cachedImageForHoverState) {
- RefPtr<Image> image = Image::loadPlatformResource("generatePasswordHover");
- m_cachedImageForHoverState = new ImageResource(image.get());
- }
- return m_cachedImageForHoverState.get();
-}
-
-void PasswordGeneratorButtonElement::defaultEventHandler(Event* event)
-{
- RefPtr<HTMLInputElement> input = hostInput();
- if (!input || input->isDisabledOrReadOnly() || !event->isMouseEvent()) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- RefPtr<PasswordGeneratorButtonElement> protector(this);
- if (event->type() == EventTypeNames::click) {
- if (Page* page = document().page())
- page->chrome().client().openPasswordGenerator(input.get());
- event->setDefaultHandled();
- }
-
- if (event->type() == EventTypeNames::mouseover) {
- m_isInHoverState = true;
- updateImage();
- }
-
- if (event->type() == EventTypeNames::mouseout) {
- m_isInHoverState = false;
- updateImage();
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-bool PasswordGeneratorButtonElement::willRespondToMouseMoveEvents()
-{
- const HTMLInputElement* input = hostInput();
- if (!input->isDisabledOrReadOnly())
- return true;
-
- return HTMLDivElement::willRespondToMouseMoveEvents();
-}
-
-bool PasswordGeneratorButtonElement::willRespondToMouseClickEvents()
-{
- const HTMLInputElement* input = hostInput();
- if (!input->isDisabledOrReadOnly())
- return true;
-
- return HTMLDivElement::willRespondToMouseClickEvents();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h
deleted file mode 100644
index 0d220f9c6b1..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 PasswordGeneratorButtonElement_h
-#define PasswordGeneratorButtonElement_h
-
-#include "core/fetch/ResourcePtr.h"
-#include "core/html/HTMLDivElement.h"
-
-namespace WebCore {
-
-class ImageResource;
-class HTMLInputElement;
-class ShadowRoot;
-
-class PasswordGeneratorButtonElement FINAL : public HTMLDivElement {
-public:
- static PassRefPtr<PasswordGeneratorButtonElement> create(Document&);
-
- void decorate(HTMLInputElement*);
-
- virtual bool willRespondToMouseMoveEvents() OVERRIDE;
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
-
-private:
- PasswordGeneratorButtonElement(Document&);
- virtual bool isPasswordGeneratorButtonElement() const OVERRIDE { return true; }
- virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool isMouseFocusable() const OVERRIDE { return false; }
- virtual void defaultEventHandler(Event*) OVERRIDE;
-
- ImageResource* imageForNormalState();
- ImageResource* imageForHoverState();
-
- HTMLInputElement* hostInput();
- void updateImage();
-
- ResourcePtr<ImageResource> m_cachedImageForNormalState;
- ResourcePtr<ImageResource> m_cachedImageForHoverState;
- bool m_isInHoverState;
-};
-
-}
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
index 40aec28a852..1c838a2683a 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
@@ -37,6 +37,7 @@
#include "core/page/Chrome.h"
#include "core/page/Page.h"
#include "core/rendering/RenderDetailsMarker.h"
+#include "wtf/TemporaryChange.h"
using namespace WTF::Unicode;
@@ -47,21 +48,20 @@ using namespace HTMLNames;
inline PickerIndicatorElement::PickerIndicatorElement(Document& document, PickerIndicatorOwner& pickerIndicatorOwner)
: HTMLDivElement(document)
, m_pickerIndicatorOwner(&pickerIndicatorOwner)
+ , m_isInOpenPopup(false)
{
}
-PassRefPtr<PickerIndicatorElement> PickerIndicatorElement::create(Document& document, PickerIndicatorOwner& pickerIndicatorOwner)
+PassRefPtrWillBeRawPtr<PickerIndicatorElement> PickerIndicatorElement::create(Document& document, PickerIndicatorOwner& pickerIndicatorOwner)
{
- RefPtr<PickerIndicatorElement> element = adoptRef(new PickerIndicatorElement(document, pickerIndicatorOwner));
- element->setPseudo(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<PickerIndicatorElement> element = adoptRefWillBeNoop(new PickerIndicatorElement(document, pickerIndicatorOwner));
+ element->setShadowPseudoId(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::pickerIndicator());
return element.release();
}
PickerIndicatorElement::~PickerIndicatorElement()
{
- closePopup();
- ASSERT(!m_chooser);
}
RenderObject* PickerIndicatorElement::createRenderer(RenderStyle*)
@@ -113,6 +113,12 @@ void PickerIndicatorElement::didEndChooser()
void PickerIndicatorElement::openPopup()
{
+ // The m_isInOpenPopup flag is unnecessary in production.
+ // MockPagePopupDriver allows to execute JavaScript code in
+ // DateTimeChooserImpl constructor. It might create another DateTimeChooser.
+ if (m_isInOpenPopup)
+ return;
+ TemporaryChange<bool> reentrancyProtector(m_isInOpenPopup, true);
if (m_chooser)
return;
if (!document().page())
@@ -143,6 +149,14 @@ bool PickerIndicatorElement::isPickerIndicatorElement() const
return true;
}
+void PickerIndicatorElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_pickerIndicatorOwner);
+ visitor->trace(m_chooser);
+ HTMLDivElement::trace(visitor);
+ DateTimeChooserClient::trace(visitor);
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
index 8b7a5e3d740..914fd9887d3 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
@@ -42,10 +42,11 @@ class HTMLInputElement;
class PagePopup;
class PickerIndicatorElement FINAL : public HTMLDivElement, public DateTimeChooserClient {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PickerIndicatorElement);
public:
// PickerIndicatorOwner implementer must call removePickerIndicatorOwner when
// it doesn't handle event, e.g. at destruction.
- class PickerIndicatorOwner {
+ class PickerIndicatorOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~PickerIndicatorOwner() { }
virtual bool isPickerIndicatorOwnerDisabledOrReadOnly() const = 0;
@@ -55,12 +56,14 @@ public:
virtual bool setupDateTimeChooserParameters(DateTimeChooserParameters&) = 0;
};
- static PassRefPtr<PickerIndicatorElement> create(Document&, PickerIndicatorOwner&);
+ static PassRefPtrWillBeRawPtr<PickerIndicatorElement> create(Document&, PickerIndicatorOwner&);
virtual ~PickerIndicatorElement();
+ virtual void trace(Visitor*) OVERRIDE;
+
void openPopup();
void closePopup();
virtual bool willRespondToMouseClickEvents() OVERRIDE;
- void removePickerIndicatorOwner() { m_pickerIndicatorOwner = 0; }
+ void removePickerIndicatorOwner() { m_pickerIndicatorOwner = nullptr; }
// DateTimeChooserClient implementation.
virtual void didChooseValue(const String&) OVERRIDE;
@@ -76,8 +79,9 @@ private:
HTMLInputElement* hostInput();
- PickerIndicatorOwner* m_pickerIndicatorOwner;
- RefPtr<DateTimeChooser> m_chooser;
+ RawPtrWillBeMember<PickerIndicatorOwner> m_pickerIndicatorOwner;
+ RefPtrWillBeMember<DateTimeChooser> m_chooser;
+ bool m_isInOpenPopup;
};
DEFINE_TYPE_CASTS(PickerIndicatorElement, Element, element, element->isPickerIndicatorElement(), element.isPickerIndicatorElement());
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp
index 50c8d1dc9a4..0f8b72f069c 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp
@@ -32,7 +32,7 @@
#include "core/html/shadow/ProgressShadowElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLProgressElement.h"
#include "core/rendering/RenderProgress.h"
@@ -56,11 +56,13 @@ bool ProgressShadowElement::rendererIsNeeded(const RenderStyle& style)
return progressRenderer && !progressRenderer->style()->hasAppearance() && HTMLDivElement::rendererIsNeeded(style);
}
-ProgressInnerElement::ProgressInnerElement(Document& document)
+inline ProgressInnerElement::ProgressInnerElement(Document& document)
: ProgressShadowElement(document)
{
}
+DEFINE_NODE_FACTORY(ProgressInnerElement)
+
RenderObject* ProgressInnerElement::createRenderer(RenderStyle*)
{
return new RenderProgress(this);
@@ -75,11 +77,13 @@ bool ProgressInnerElement::rendererIsNeeded(const RenderStyle& style)
return progressRenderer && !progressRenderer->style()->hasAppearance() && HTMLDivElement::rendererIsNeeded(style);
}
-ProgressBarElement::ProgressBarElement(Document& document)
+inline ProgressBarElement::ProgressBarElement(Document& document)
: ProgressShadowElement(document)
{
}
+DEFINE_NODE_FACTORY(ProgressBarElement)
+
ProgressValueElement::ProgressValueElement(Document& document)
: ProgressShadowElement(document)
{
@@ -90,4 +94,6 @@ void ProgressValueElement::setWidthPercentage(double width)
setInlineStyleProperty(CSSPropertyWidth, width, CSSPrimitiveValue::CSS_PERCENTAGE);
}
+DEFINE_NODE_FACTORY(ProgressValueElement)
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h
index b375fcc88d7..825b0b68437 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h
@@ -41,56 +41,41 @@ class HTMLProgressElement;
class ProgressShadowElement : public HTMLDivElement {
public:
- ProgressShadowElement(Document&);
+ explicit ProgressShadowElement(Document&);
HTMLProgressElement* progressElement() const;
protected:
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
class ProgressInnerElement FINAL : public ProgressShadowElement {
public:
- static PassRefPtr<ProgressInnerElement> create(Document&);
+ DECLARE_NODE_FACTORY(ProgressInnerElement);
private:
- ProgressInnerElement(Document&);
+ explicit ProgressInnerElement(Document&);
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
-inline PassRefPtr<ProgressInnerElement> ProgressInnerElement::create(Document& document)
-{
- return adoptRef(new ProgressInnerElement(document));
-}
-
class ProgressBarElement FINAL : public ProgressShadowElement {
public:
- static PassRefPtr<ProgressBarElement> create(Document&);
+ DECLARE_NODE_FACTORY(ProgressBarElement);
private:
- ProgressBarElement(Document&);
+ explicit ProgressBarElement(Document&);
};
-inline PassRefPtr<ProgressBarElement> ProgressBarElement::create(Document& document)
-{
- return adoptRef(new ProgressBarElement(document));
-}
-
class ProgressValueElement FINAL : public ProgressShadowElement {
public:
- static PassRefPtr<ProgressValueElement> create(Document&);
+ DECLARE_NODE_FACTORY(ProgressValueElement);
void setWidthPercentage(double);
private:
- ProgressValueElement(Document&);
+ explicit ProgressValueElement(Document&);
};
-inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Document& document)
-{
- return adoptRef(new ProgressValueElement(document));
-}
-
}
#endif // ProgressShadowElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp
index abe60e1d644..ad2f183effb 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp
@@ -35,6 +35,18 @@ namespace WebCore {
namespace ShadowElementNames {
+const AtomicString& detailsContent()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("details-content", AtomicString::ConstructFromLiteral));
+ return name;
+}
+
+const AtomicString& detailsSummary()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("details-summary", AtomicString::ConstructFromLiteral));
+ return name;
+}
+
const AtomicString& dateTimeEdit()
{
DEFINE_STATIC_LOCAL(AtomicString, name, ("date-time-edit", AtomicString::ConstructFromLiteral));
@@ -65,12 +77,6 @@ const AtomicString& innerEditor()
return name;
}
-const AtomicString& passwordGenerator()
-{
- DEFINE_STATIC_LOCAL(AtomicString, name, ("password-generator", AtomicString::ConstructFromLiteral));
- return name;
-}
-
const AtomicString& pickerIndicator()
{
DEFINE_STATIC_LOCAL(AtomicString, name, ("picker", AtomicString::ConstructFromLiteral));
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h
index 46788a1cdfb..61ee1ca1680 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h
@@ -37,12 +37,13 @@ namespace WebCore {
namespace ShadowElementNames {
+const AtomicString& detailsContent();
+const AtomicString& detailsSummary();
const AtomicString& dateTimeEdit();
const AtomicString& spinButton();
const AtomicString& clearButton();
const AtomicString& editingViewPort();
const AtomicString& innerEditor();
-const AtomicString& passwordGenerator();
const AtomicString& pickerIndicator();
const AtomicString& placeholder();
const AtomicString& searchDecoration();
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
index dc7d5080591..3e9ab2fd281 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
@@ -36,18 +36,16 @@
#include "core/events/Event.h"
#include "core/events/MouseEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/StepRange.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderFlexibleBox.h"
#include "core/rendering/RenderSlider.h"
#include "core/rendering/RenderTheme.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -64,9 +62,6 @@ inline static bool hasVerticalAppearance(HTMLInputElement* input)
ASSERT(input->renderer());
RenderStyle* sliderStyle = input->renderer()->style();
- if (sliderStyle->appearance() == MediaVolumeSliderPart && RenderTheme::theme().usesVerticalVolumeSlider())
- return true;
-
return sliderStyle->appearance() == SliderVerticalPart;
}
@@ -131,11 +126,18 @@ void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou
if (zoomFactor != 1.0)
trackHeight *= zoomFactor;
+ // FIXME: The trackHeight should have been added before updateLogicalHeight was called to avoid this hack.
+ updateIntrinsicContentLogicalHeight(trackHeight);
+
RenderBox::computeLogicalHeight(trackHeight, logicalTop, computedValues);
return;
}
if (isVertical)
logicalHeight = RenderSlider::defaultTrackLength;
+
+ // FIXME: The trackHeight should have been added before updateLogicalHeight was called to avoid this hack.
+ updateIntrinsicContentLogicalHeight(logicalHeight);
+
RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues);
}
@@ -157,7 +159,7 @@ void RenderSliderContainer::layout()
RenderBox* thumb = thumbElement ? thumbElement->renderBox() : 0;
RenderBox* track = trackElement ? trackElement->renderBox() : 0;
- SubtreeLayoutScope layoutScope(this);
+ SubtreeLayoutScope layoutScope(*this);
// Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place.
// FIXME: Make a custom Render class for the track and move the thumb positioning code there.
if (track)
@@ -182,14 +184,14 @@ void RenderSliderContainer::layout()
else
thumbLocation.setX(thumbLocation.x() - offset);
thumb->setLocation(thumbLocation);
- if (checkForRepaintDuringLayout() && parent()
+ if (checkForPaintInvalidationDuringLayout() && parent()
&& (parent()->style()->appearance() == MediaVolumeSliderPart || parent()->style()->appearance() == MediaSliderPart)) {
// This will sometimes repaint too much. However, it is necessary to
// correctly repaint media controls (volume and timeline sliders) -
// they have special painting code in RenderMediaControls.cpp:paintMediaVolumeSlider
// and paintMediaSlider that gets called via -webkit-appearance and RenderTheme,
// so nothing else would otherwise invalidate the slider.
- repaint();
+ paintInvalidationForWholeRenderer();
}
}
@@ -201,9 +203,9 @@ inline SliderThumbElement::SliderThumbElement(Document& document)
{
}
-PassRefPtr<SliderThumbElement> SliderThumbElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SliderThumbElement> SliderThumbElement::create(Document& document)
{
- RefPtr<SliderThumbElement> element = adoptRef(new SliderThumbElement(document));
+ RefPtrWillBeRawPtr<SliderThumbElement> element = adoptRefWillBeNoop(new SliderThumbElement(document));
element->setAttribute(idAttr, ShadowElementNames::sliderThumb());
return element.release();
}
@@ -214,7 +216,7 @@ void SliderThumbElement::setPositionFromValue()
// path, we don't actually update the value here. Instead, we poke at the
// renderer directly to trigger layout.
if (renderer())
- renderer()->setNeedsLayout();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
}
RenderObject* SliderThumbElement::createRenderer(RenderStyle*)
@@ -229,12 +231,12 @@ bool SliderThumbElement::isDisabledFormControl() const
bool SliderThumbElement::matchesReadOnlyPseudoClass() const
{
- return hostInput()->matchesReadOnlyPseudoClass();
+ return hostInput() && hostInput()->matchesReadOnlyPseudoClass();
}
bool SliderThumbElement::matchesReadWritePseudoClass() const
{
- return hostInput()->matchesReadWritePseudoClass();
+ return hostInput() && hostInput()->matchesReadWritePseudoClass();
}
Node* SliderThumbElement::focusDelegate()
@@ -244,14 +246,14 @@ Node* SliderThumbElement::focusDelegate()
void SliderThumbElement::dragFrom(const LayoutPoint& point)
{
- RefPtr<SliderThumbElement> protector(this);
+ RefPtrWillBeRawPtr<SliderThumbElement> protector(this);
startDragging();
setPositionFromPoint(point);
}
void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
{
- RefPtr<HTMLInputElement> input(hostInput());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(hostInput());
Element* trackElement = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack());
if (!input->renderer() || !renderBox() || !trackElement->renderBox())
@@ -281,7 +283,7 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
position -= isLeftToRightDirection ? renderBox()->marginLeft() : renderBox()->marginRight();
currentPosition = absoluteThumbOrigin.x() - absoluteSliderContentOrigin.x();
}
- position = max<LayoutUnit>(0, min(position, trackSize));
+ position = std::max<LayoutUnit>(0, std::min(position, trackSize));
const Decimal ratio = Decimal::fromDouble(static_cast<double>(position) / trackSize);
const Decimal fraction = isVertical || !isLeftToRightDirection ? Decimal(1) - ratio : ratio;
StepRange stepRange(input->createStepRange(RejectAny));
@@ -304,13 +306,12 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
// FIXME: This is no longer being set from renderer. Consider updating the method name.
input->setValueFromRenderer(valueString);
if (renderer())
- renderer()->setNeedsLayout();
- input->dispatchFormControlChangeEvent();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
}
void SliderThumbElement::startDragging()
{
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
frame->eventHandler().setCapturingMouseEventsNode(this);
m_inDragMode = true;
}
@@ -321,11 +322,13 @@ void SliderThumbElement::stopDragging()
if (!m_inDragMode)
return;
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_inDragMode = false;
if (renderer())
- renderer()->setNeedsLayout();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
+ if (hostInput())
+ hostInput()->dispatchFormControlChangeEvent();
}
void SliderThumbElement::defaultEventHandler(Event* event)
@@ -387,8 +390,8 @@ bool SliderThumbElement::willRespondToMouseClickEvents()
void SliderThumbElement::detach(const AttachContext& context)
{
if (m_inDragMode) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
}
HTMLDivElement::detach(context);
}
@@ -412,10 +415,10 @@ static const AtomicString& mediaSliderThumbShadowPartId()
return mediaSliderThumb;
}
-const AtomicString& SliderThumbElement::pseudo() const
+const AtomicString& SliderThumbElement::shadowPseudoId() const
{
HTMLInputElement* input = hostInput();
- if (!input)
+ if (!input || !input->renderer())
return sliderThumbShadowPartId();
RenderStyle* sliderStyle = input->renderer()->style();
@@ -439,25 +442,22 @@ inline SliderContainerElement::SliderContainerElement(Document& document)
{
}
-PassRefPtr<SliderContainerElement> SliderContainerElement::create(Document& document)
-{
- return adoptRef(new SliderContainerElement(document));
-}
+DEFINE_NODE_FACTORY(SliderContainerElement)
RenderObject* SliderContainerElement::createRenderer(RenderStyle*)
{
return new RenderSliderContainer(this);
}
-const AtomicString& SliderContainerElement::pseudo() const
+const AtomicString& SliderContainerElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral));
- if (!shadowHost()->hasTagName(inputTag))
+ if (!shadowHost() || !shadowHost()->renderer())
return sliderContainer;
- RenderStyle* sliderStyle = toHTMLInputElement(shadowHost())->renderer()->style();
+ RenderStyle* sliderStyle = shadowHost()->renderer()->style();
switch (sliderStyle->appearance()) {
case MediaSliderPart:
case MediaSliderThumbPart:
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h
index a7af7771fbd..efb41d65fa0 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h
@@ -32,7 +32,7 @@
#ifndef SliderThumbElement_h
#define SliderThumbElement_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLDivElement.h"
#include "core/rendering/RenderBlockFlow.h"
#include "wtf/Forward.h"
@@ -46,43 +46,40 @@ class FloatPoint;
class SliderThumbElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SliderThumbElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SliderThumbElement> create(Document&);
void setPositionFromValue();
void dragFrom(const LayoutPoint&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool willRespondToMouseMoveEvents() OVERRIDE;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
HTMLInputElement* hostInput() const;
void setPositionFromPoint(const LayoutPoint&);
void stopDragging();
private:
SliderThumbElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
virtual bool isDisabledFormControl() const OVERRIDE;
virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
virtual bool matchesReadWritePseudoClass() const OVERRIDE;
- virtual Node* focusDelegate();
+ virtual Node* focusDelegate() OVERRIDE;
void startDragging();
bool m_inDragMode;
};
-inline PassRefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
+inline PassRefPtrWillBeRawPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
{
return create(document());
}
-inline SliderThumbElement* toSliderThumbElement(Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isHTMLElement());
- return static_cast<SliderThumbElement*>(node);
-}
+// FIXME: There are no ways to check if a node is a SliderThumbElement.
+DEFINE_ELEMENT_TYPE_CASTS(SliderThumbElement, isHTMLElement());
// --------------------------------
@@ -92,20 +89,19 @@ public:
void updateAppearance(RenderStyle* parentStyle);
private:
- virtual bool isSliderThumb() const;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual bool isSliderThumb() const OVERRIDE;
};
// --------------------------------
class SliderContainerElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SliderContainerElement> create(Document&);
+ DECLARE_NODE_FACTORY(SliderContainerElement);
private:
- SliderContainerElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual const AtomicString& pseudo() const;
+ explicit SliderContainerElement(Document&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp
index 38303b5aca5..0671ee1beef 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp
@@ -27,14 +27,13 @@
#include "config.h"
#include "core/html/shadow/SpinButtonElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/WheelEvent.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/Chrome.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/rendering/RenderBox.h"
#include "platform/scroll/ScrollbarTheme.h"
@@ -53,17 +52,17 @@ inline SpinButtonElement::SpinButtonElement(Document& document, SpinButtonOwner&
{
}
-PassRefPtr<SpinButtonElement> SpinButtonElement::create(Document& document, SpinButtonOwner& spinButtonOwner)
+PassRefPtrWillBeRawPtr<SpinButtonElement> SpinButtonElement::create(Document& document, SpinButtonOwner& spinButtonOwner)
{
- RefPtr<SpinButtonElement> element = adoptRef(new SpinButtonElement(document, spinButtonOwner));
- element->setPseudo(AtomicString("-webkit-inner-spin-button", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<SpinButtonElement> element = adoptRefWillBeNoop(new SpinButtonElement(document, spinButtonOwner));
+ element->setShadowPseudoId(AtomicString("-webkit-inner-spin-button", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::spinButton());
return element.release();
}
void SpinButtonElement::detach(const AttachContext& context)
{
- releaseCapture();
+ releaseCapture(EventDispatchDisallowed);
HTMLDivElement::detach(context);
}
@@ -95,7 +94,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
// The following functions of HTMLInputElement may run JavaScript
// code which detaches this shadow node. We need to take a reference
// and check renderer() after such function calls.
- RefPtr<Node> protector(this);
+ RefPtrWillBeRawPtr<Node> protector(this);
if (m_spinButtonOwner)
m_spinButtonOwner->focusAndSelectSpinButtonOwner();
if (renderer()) {
@@ -111,12 +110,12 @@ void SpinButtonElement::defaultEventHandler(Event* event)
}
event->setDefaultHandled();
}
- } else if (mouseEvent->type() == EventTypeNames::mouseup && mouseEvent->button() == LeftButton)
- stopRepeatingTimer();
- else if (event->type() == EventTypeNames::mousemove) {
+ } else if (mouseEvent->type() == EventTypeNames::mouseup && mouseEvent->button() == LeftButton) {
+ releaseCapture();
+ } else if (event->type() == EventTypeNames::mousemove) {
if (box->pixelSnappedBorderBoxRect().contains(local)) {
if (!m_capturing) {
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
frame->eventHandler().setCapturingMouseEventsNode(this);
m_capturing = true;
if (Page* page = document().page())
@@ -126,7 +125,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
UpDownState oldUpDownState = m_upDownState;
m_upDownState = (local.y() < box->height() / 2) ? Up : Down;
if (m_upDownState != oldUpDownState)
- renderer()->repaint();
+ renderer()->paintInvalidationForWholeRenderer();
} else {
releaseCapture();
m_upDownState = Indeterminate;
@@ -188,17 +187,20 @@ void SpinButtonElement::doStepAction(int amount)
m_spinButtonOwner->spinButtonStepDown();
}
-void SpinButtonElement::releaseCapture()
+void SpinButtonElement::releaseCapture(EventDispatch eventDispatch)
{
stopRepeatingTimer();
if (m_capturing) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_capturing = false;
if (Page* page = document().page())
page->chrome().unregisterPopupOpeningObserver(this);
}
}
+ if (m_spinButtonOwner)
+ m_spinButtonOwner->spinButtonDidReleaseMouseCapture(eventDispatch);
+
}
bool SpinButtonElement::matchesReadOnlyPseudoClass() const
@@ -215,7 +217,7 @@ void SpinButtonElement::startRepeatingTimer()
{
m_pressStartingState = m_upDownState;
ScrollbarTheme* theme = ScrollbarTheme::theme();
- m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay());
+ m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay(), FROM_HERE);
}
void SpinButtonElement::stopRepeatingTimer()
@@ -255,4 +257,10 @@ bool SpinButtonElement::shouldRespondToMouseEvents()
return !m_spinButtonOwner || m_spinButtonOwner->shouldSpinButtonRespondToMouseEvents();
}
+void SpinButtonElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_spinButtonOwner);
+ HTMLDivElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h
index 41de8fcdaee..25c0b30d8b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h
@@ -40,13 +40,17 @@ public:
Down,
Up,
};
-
- class SpinButtonOwner {
+ enum EventDispatch {
+ EventDispatchAllowed,
+ EventDispatchDisallowed,
+ };
+ class SpinButtonOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~SpinButtonOwner() { }
virtual void focusAndSelectSpinButtonOwner() = 0;
virtual bool shouldSpinButtonRespondToMouseEvents() = 0;
virtual bool shouldSpinButtonRespondToWheelEvents() = 0;
+ virtual void spinButtonDidReleaseMouseCapture(EventDispatch) = 0;
virtual void spinButtonStepDown() = 0;
virtual void spinButtonStepUp() = 0;
};
@@ -54,10 +58,10 @@ public:
// The owner of SpinButtonElement must call removeSpinButtonOwner
// because SpinButtonElement can be outlive SpinButtonOwner
// implementation, e.g. during event handling.
- static PassRefPtr<SpinButtonElement> create(Document&, SpinButtonOwner&);
+ static PassRefPtrWillBeRawPtr<SpinButtonElement> create(Document&, SpinButtonOwner&);
UpDownState upDownState() const { return m_upDownState; }
- virtual void releaseCapture();
- void removeSpinButtonOwner() { m_spinButtonOwner = 0; }
+ void releaseCapture(EventDispatch = EventDispatchAllowed);
+ void removeSpinButtonOwner() { m_spinButtonOwner = nullptr; }
void step(int amount);
@@ -66,25 +70,27 @@ public:
void forwardEvent(Event*);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
SpinButtonElement(Document&, SpinButtonOwner&);
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool isSpinButtonElement() const { return true; }
+ virtual void detach(const AttachContext&) OVERRIDE;
+ virtual bool isSpinButtonElement() const OVERRIDE { return true; }
virtual bool isDisabledFormControl() const OVERRIDE { return shadowHost() && shadowHost()->isDisabledFormControl(); }
virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
virtual bool matchesReadWritePseudoClass() const OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void willOpenPopup() OVERRIDE;
void doStepAction(int);
void startRepeatingTimer();
void stopRepeatingTimer();
void repeatingTimerFired(Timer<SpinButtonElement>*);
- virtual void setHovered(bool = true);
+ virtual void setHovered(bool = true) OVERRIDE;
bool shouldRespondToMouseEvents();
- virtual bool isMouseFocusable() const { return false; }
+ virtual bool isMouseFocusable() const OVERRIDE { return false; }
- SpinButtonOwner* m_spinButtonOwner;
+ RawPtrWillBeMember<SpinButtonOwner> m_spinButtonOwner;
bool m_capturing;
UpDownState m_upDownState;
UpDownState m_pressStartingState;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp
index a19fef2c9e9..57c9fc665a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp
@@ -27,21 +27,18 @@
#include "config.h"
#include "core/html/shadow/TextControlInnerElements.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/events/MouseEvent.h"
#include "core/events/TextEvent.h"
#include "core/events/TextEventInputType.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderTextControlSingleLine.h"
#include "core/rendering/RenderView.h"
-#include "core/speech/SpeechInput.h"
-#include "core/speech/SpeechInputEvent.h"
#include "platform/UserGestureIndicator.h"
namespace WebCore {
@@ -53,9 +50,9 @@ TextControlInnerContainer::TextControlInnerContainer(Document& document)
{
}
-PassRefPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document)
+PassRefPtrWillBeRawPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document)
{
- RefPtr<TextControlInnerContainer> element = adoptRef(new TextControlInnerContainer(document));
+ RefPtrWillBeRawPtr<TextControlInnerContainer> element = adoptRefWillBeNoop(new TextControlInnerContainer(document));
element->setAttribute(idAttr, ShadowElementNames::textFieldContainer());
return element.release();
}
@@ -73,9 +70,9 @@ EditingViewPortElement::EditingViewPortElement(Document& document)
setHasCustomStyleCallbacks();
}
-PassRefPtr<EditingViewPortElement> EditingViewPortElement::create(Document& document)
+PassRefPtrWillBeRawPtr<EditingViewPortElement> EditingViewPortElement::create(Document& document)
{
- RefPtr<EditingViewPortElement> element = adoptRef(new EditingViewPortElement(document));
+ RefPtrWillBeRawPtr<EditingViewPortElement> element = adoptRefWillBeNoop(new EditingViewPortElement(document));
element->setAttribute(idAttr, ShadowElementNames::editingViewPort());
return element.release();
}
@@ -88,9 +85,6 @@ PassRefPtr<RenderStyle> EditingViewPortElement::customStyleForRenderer()
style->inheritFrom(shadowHost()->renderStyle());
style->setFlexGrow(1);
- // min-width: 0; is needed for correct shrinking.
- // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
- style->setMinWidth(Length(0, Fixed));
style->setDisplay(BLOCK);
style->setDirection(LTR);
@@ -104,20 +98,20 @@ PassRefPtr<RenderStyle> EditingViewPortElement::customStyleForRenderer()
// ---------------------------
-inline TextControlInnerTextElement::TextControlInnerTextElement(Document& document)
+inline TextControlInnerEditorElement::TextControlInnerEditorElement(Document& document)
: HTMLDivElement(document)
{
setHasCustomStyleCallbacks();
}
-PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document& document)
+PassRefPtrWillBeRawPtr<TextControlInnerEditorElement> TextControlInnerEditorElement::create(Document& document)
{
- RefPtr<TextControlInnerTextElement> element = adoptRef(new TextControlInnerTextElement(document));
+ RefPtrWillBeRawPtr<TextControlInnerEditorElement> element = adoptRefWillBeNoop(new TextControlInnerEditorElement(document));
element->setAttribute(idAttr, ShadowElementNames::innerEditor());
return element.release();
}
-void TextControlInnerTextElement::defaultEventHandler(Event* event)
+void TextControlInnerEditorElement::defaultEventHandler(Event* event)
{
// FIXME: In the future, we should add a way to have default event listeners.
// Then we would add one to the text field's inner div, and we wouldn't need this subclass.
@@ -136,18 +130,18 @@ void TextControlInnerTextElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
-RenderObject* TextControlInnerTextElement::createRenderer(RenderStyle*)
+RenderObject* TextControlInnerEditorElement::createRenderer(RenderStyle*)
{
return new RenderTextControlInnerBlock(this);
}
-PassRefPtr<RenderStyle> TextControlInnerTextElement::customStyleForRenderer()
+PassRefPtr<RenderStyle> TextControlInnerEditorElement::customStyleForRenderer()
{
RenderObject* parentRenderer = shadowHost()->renderer();
if (!parentRenderer || !parentRenderer->isTextControl())
return originalStyleForRenderer();
RenderTextControl* textControlRenderer = toRenderTextControl(parentRenderer);
- return textControlRenderer->createInnerTextStyle(textControlRenderer->style());
+ return textControlRenderer->createInnerEditorStyle(textControlRenderer->style());
}
// ----------------------------
@@ -157,21 +151,21 @@ inline SearchFieldDecorationElement::SearchFieldDecorationElement(Document& docu
{
}
-PassRefPtr<SearchFieldDecorationElement> SearchFieldDecorationElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SearchFieldDecorationElement> SearchFieldDecorationElement::create(Document& document)
{
- RefPtr<SearchFieldDecorationElement> element = adoptRef(new SearchFieldDecorationElement(document));
+ RefPtrWillBeRawPtr<SearchFieldDecorationElement> element = adoptRefWillBeNoop(new SearchFieldDecorationElement(document));
element->setAttribute(idAttr, ShadowElementNames::searchDecoration());
return element.release();
}
-const AtomicString& SearchFieldDecorationElement::pseudo() const
+const AtomicString& SearchFieldDecorationElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, resultsDecorationId, ("-webkit-search-results-decoration", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, decorationId, ("-webkit-search-decoration", AtomicString::ConstructFromLiteral));
Element* host = shadowHost();
if (!host)
return resultsDecorationId;
- if (host->hasTagName(inputTag)) {
+ if (isHTMLInputElement(*host)) {
if (toHTMLInputElement(host)->maxResults() < 0)
return decorationId;
return resultsDecorationId;
@@ -206,10 +200,10 @@ inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document&
{
}
-PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document)
{
- RefPtr<SearchFieldCancelButtonElement> element = adoptRef(new SearchFieldCancelButtonElement(document));
- element->setPseudo(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<SearchFieldCancelButtonElement> element = adoptRefWillBeNoop(new SearchFieldCancelButtonElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::clearButton());
return element.release();
}
@@ -217,8 +211,8 @@ PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::creat
void SearchFieldCancelButtonElement::detach(const AttachContext& context)
{
if (m_capturing) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
}
HTMLDivElement::detach(context);
}
@@ -227,136 +221,17 @@ void SearchFieldCancelButtonElement::detach(const AttachContext& context)
void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
{
// If the element is visible, on mouseup, clear the value, and set selection
- RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
+ RefPtrWillBeRawPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
if (!input || input->isDisabledOrReadOnly()) {
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
return;
}
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- input->focus();
- input->select();
- event->setDefaultHandled();
- }
- if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (m_capturing) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- if (hovered()) {
- String oldValue = input->value();
- input->setValueForUser("");
- input->onSearch();
- event->setDefaultHandled();
- }
- }
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
-{
- const HTMLInputElement* input = toHTMLInputElement(shadowHost());
- if (input && !input->isDisabledOrReadOnly())
- return true;
-
- return HTMLDivElement::willRespondToMouseClickEvents();
-}
-
-// ----------------------------
-
-#if ENABLE(INPUT_SPEECH)
-
-inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Document& document)
- : HTMLDivElement(document)
- , m_capturing(false)
- , m_state(Idle)
- , m_listenerId(0)
-{
-}
-
-InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement()
-{
- SpeechInput* speech = speechInput();
- if (speech && m_listenerId) { // Could be null when page is unloading.
- if (m_state != Idle)
- speech->cancelRecognition(m_listenerId);
- speech->unregisterListener(m_listenerId);
- }
-}
-
-PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(Document& document)
-{
- RefPtr<InputFieldSpeechButtonElement> element = adoptRef(new InputFieldSpeechButtonElement(document));
- element->setPseudo(AtomicString("-webkit-input-speech-button", AtomicString::ConstructFromLiteral));
- element->setAttribute(idAttr, ShadowElementNames::speechButton());
- return element.release();
-}
-
-void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
-{
- // For privacy reasons, only allow clicks directly coming from the user.
- if (!UserGestureIndicator::processingUserGesture()) {
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- // The call to focus() below dispatches a focus event, and an event handler in the page might
- // remove the input element from DOM. To make sure it remains valid until we finish our work
- // here, we take a temporary reference.
- RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
-
- if (!input || input->isDisabledOrReadOnly()) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
- // On mouse down, select the text and set focus.
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- input->focus();
- input->select();
- event->setDefaultHandled();
- }
- // On mouse up, release capture cleanly.
- if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- }
- }
-
- if (event->type() == EventTypeNames::click && m_listenerId) {
- switch (m_state) {
- case Idle:
- startSpeechInput();
- break;
- case Recording:
- stopSpeechInput();
- break;
- case Recognizing:
- // Nothing to do here, we will continue to wait for results.
- break;
- }
+ if (event->type() == EventTypeNames::click && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
+ input->setValueForUser("");
+ input->onSearch();
event->setDefaultHandled();
}
@@ -364,7 +239,7 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
-bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents()
+bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
{
const HTMLInputElement* input = toHTMLInputElement(shadowHost());
if (input && !input->isDisabledOrReadOnly())
@@ -373,102 +248,4 @@ bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents()
return HTMLDivElement::willRespondToMouseClickEvents();
}
-void InputFieldSpeechButtonElement::setState(SpeechInputState state)
-{
- if (m_state != state) {
- m_state = state;
- shadowHost()->renderer()->repaint();
- }
-}
-
-SpeechInput* InputFieldSpeechButtonElement::speechInput()
-{
- return SpeechInput::from(document().page());
-}
-
-void InputFieldSpeechButtonElement::didCompleteRecording(int)
-{
- setState(Recognizing);
-}
-
-void InputFieldSpeechButtonElement::didCompleteRecognition(int)
-{
- setState(Idle);
-}
-
-void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputResultArray& results)
-{
- m_results = results;
-
- // The call to setValue() below dispatches an event, and an event handler in the page might
- // remove the input element from DOM. To make sure it remains valid until we finish our work
- // here, we take a temporary reference.
- RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
- if (!input || input->isDisabledOrReadOnly())
- return;
-
- RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- if (document().domWindow()) {
- // Call selectionChanged, causing the element to cache the selection,
- // so that the text event inserts the text in this element even if
- // focus has moved away from it.
- input->selectionChanged(false);
- input->dispatchEvent(TextEvent::create(document().domWindow(), results.isEmpty() ? "" : results[0]->utterance(), TextEventInputOther));
- }
-
- // This event is sent after the text event so the website can perform actions using the input field content immediately.
- // It provides alternative recognition hypotheses and notifies that the results come from speech input.
- input->dispatchEvent(SpeechInputEvent::create(EventTypeNames::webkitspeechchange, results));
-
- // Check before accessing the renderer as the above event could have potentially turned off
- // speech in the input element, hence removing this button and renderer from the hierarchy.
- if (renderer())
- renderer()->repaint();
-}
-
-void InputFieldSpeechButtonElement::attach(const AttachContext& context)
-{
- ASSERT(!m_listenerId);
- if (SpeechInput* input = SpeechInput::from(document().page()))
- m_listenerId = input->registerListener(this);
- HTMLDivElement::attach(context);
-}
-
-void InputFieldSpeechButtonElement::detach(const AttachContext& context)
-{
- if (m_capturing) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
- }
-
- if (m_listenerId) {
- if (m_state != Idle)
- speechInput()->cancelRecognition(m_listenerId);
- speechInput()->unregisterListener(m_listenerId);
- m_listenerId = 0;
- }
-
- HTMLDivElement::detach(context);
-}
-
-void InputFieldSpeechButtonElement::startSpeechInput()
-{
- if (m_state != Idle)
- return;
-
- RefPtr<HTMLInputElement> input = toHTMLInputElement(shadowHost());
- AtomicString language = input->computeInheritedLanguage();
- String grammar = input->getAttribute(webkitgrammarAttr);
- IntRect rect = document().view()->contentsToRootView(pixelSnappedBoundingBox());
- if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document().securityOrigin()))
- setState(Recording);
-}
-
-void InputFieldSpeechButtonElement::stopSpeechInput()
-{
- if (m_state == Recording)
- speechInput()->stopRecording(m_listenerId);
-}
-#endif // ENABLE(INPUT_SPEECH)
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h
index 6b6fb0ff6f4..65c994d7d2e 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h
@@ -28,119 +28,72 @@
#define TextControlInnerElements_h
#include "core/html/HTMLDivElement.h"
-#include "core/speech/SpeechInputListener.h"
#include "wtf/Forward.h"
namespace WebCore {
-class SpeechInput;
-
class TextControlInnerContainer FINAL : public HTMLDivElement {
public:
- static PassRefPtr<TextControlInnerContainer> create(Document&);
+ static PassRefPtrWillBeRawPtr<TextControlInnerContainer> create(Document&);
+
protected:
- TextControlInnerContainer(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ explicit TextControlInnerContainer(Document&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
class EditingViewPortElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<EditingViewPortElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<EditingViewPortElement> create(Document&);
protected:
- EditingViewPortElement(Document&);
+ explicit EditingViewPortElement(Document&);
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
private:
virtual bool supportsFocus() const OVERRIDE { return false; }
};
-class TextControlInnerTextElement FINAL : public HTMLDivElement {
+class TextControlInnerEditorElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<TextControlInnerTextElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<TextControlInnerEditorElement> create(Document&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
private:
- TextControlInnerTextElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ explicit TextControlInnerEditorElement(Document&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
virtual bool supportsFocus() const OVERRIDE { return false; }
};
class SearchFieldDecorationElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SearchFieldDecorationElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SearchFieldDecorationElement> create(Document&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
private:
- SearchFieldDecorationElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit SearchFieldDecorationElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual bool supportsFocus() const OVERRIDE { return false; }
};
class SearchFieldCancelButtonElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SearchFieldCancelButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SearchFieldCancelButtonElement> create(Document&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
private:
- SearchFieldCancelButtonElement(Document&);
+ explicit SearchFieldCancelButtonElement(Document&);
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
virtual bool supportsFocus() const OVERRIDE { return false; }
bool m_capturing;
};
-#if ENABLE(INPUT_SPEECH)
-
-class InputFieldSpeechButtonElement FINAL
- : public HTMLDivElement,
- public SpeechInputListener {
-public:
- enum SpeechInputState {
- Idle,
- Recording,
- Recognizing,
- };
-
- static PassRefPtr<InputFieldSpeechButtonElement> create(Document&);
- virtual ~InputFieldSpeechButtonElement();
-
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void defaultEventHandler(Event*);
- virtual bool willRespondToMouseClickEvents();
- virtual bool isInputFieldSpeechButtonElement() const { return true; }
- SpeechInputState state() const { return m_state; }
- void startSpeechInput();
- void stopSpeechInput();
-
- // SpeechInputListener methods.
- void didCompleteRecording(int);
- void didCompleteRecognition(int);
- void setRecognitionResult(int, const SpeechInputResultArray&);
-
-private:
- InputFieldSpeechButtonElement(Document&);
- SpeechInput* speechInput();
- void setState(SpeechInputState state);
- virtual bool isMouseFocusable() const { return false; }
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
-
- bool m_capturing;
- SpeechInputState m_state;
- int m_listenerId;
- SpeechInputResultArray m_results;
-};
-
-DEFINE_TYPE_CASTS(InputFieldSpeechButtonElement, Element, element, element->isInputFieldSpeechButtonElement(), element.isInputFieldSpeechButtonElement());
-
-#endif // ENABLE(INPUT_SPEECH)
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp
new file mode 100644
index 00000000000..cfa0de3f3f6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp
@@ -0,0 +1,86 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/AudioTrack.h"
+
+#include "core/html/HTMLMediaElement.h"
+
+namespace WebCore {
+
+AudioTrack::AudioTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool enabled)
+ : TrackBase(TrackBase::AudioTrack, label, language, id)
+ , m_enabled(enabled)
+{
+ ScriptWrappable::init(this);
+ setKind(kind);
+}
+
+AudioTrack::~AudioTrack()
+{
+}
+
+void AudioTrack::setEnabled(bool enabled)
+{
+ if (enabled == m_enabled)
+ return;
+
+ m_enabled = enabled;
+
+ if (mediaElement())
+ mediaElement()->audioTrackChanged();
+}
+
+const AtomicString& AudioTrack::alternativeKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("alternative", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::descriptionsKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("descriptions", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::mainKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("main", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::mainDescriptionsKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("main-desc", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::translationKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("translation", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::commentaryKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("commentary", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+bool AudioTrack::isValidKind(const AtomicString& kind) const
+{
+ return (kind == alternativeKeyword())
+ || (kind == descriptionsKeyword())
+ || (kind == mainKeyword())
+ || (kind == mainDescriptionsKeyword())
+ || (kind == translationKeyword())
+ || (kind == commentaryKeyword());
+}
+
+AtomicString AudioTrack::defaultKind() const
+{
+ return emptyAtom;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h
new file mode 100644
index 00000000000..dc690ca1dc6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AudioTrack_h
+#define AudioTrack_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/TrackBase.h"
+
+namespace WebCore {
+
+class AudioTrack FINAL : public TrackBase, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<AudioTrack> create(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool enabled)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new AudioTrack(id, kind, label, language, enabled));
+ }
+ virtual ~AudioTrack();
+
+ bool enabled() const { return m_enabled; }
+ void setEnabled(bool);
+
+ // Valid kind keywords.
+ static const AtomicString& alternativeKeyword();
+ static const AtomicString& descriptionsKeyword();
+ static const AtomicString& mainKeyword();
+ static const AtomicString& mainDescriptionsKeyword();
+ static const AtomicString& translationKeyword();
+ static const AtomicString& commentaryKeyword();
+
+private:
+ AudioTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool enabled);
+
+ // TrackBase
+ virtual bool isValidKind(const AtomicString&) const OVERRIDE;
+ virtual AtomicString defaultKind() const OVERRIDE;
+
+ bool m_enabled;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl
new file mode 100644
index 00000000000..d5e0449c02e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl
@@ -0,0 +1,15 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+ WillBeGarbageCollected,
+] interface AudioTrack {
+ readonly attribute DOMString id;
+ readonly attribute DOMString kind;
+ readonly attribute DOMString label;
+ readonly attribute DOMString language;
+ attribute boolean enabled;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp
new file mode 100644
index 00000000000..c4653cdf48b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/AudioTrackList.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<AudioTrackList> AudioTrackList::create(HTMLMediaElement& mediaElement)
+{
+ return adoptRefWillBeRefCountedGarbageCollected(new AudioTrackList(mediaElement));
+}
+
+AudioTrackList::~AudioTrackList()
+{
+}
+
+AudioTrackList::AudioTrackList(HTMLMediaElement& mediaElement)
+ : TrackListBase<AudioTrack>(&mediaElement)
+{
+ ScriptWrappable::init(this);
+}
+
+bool AudioTrackList::hasEnabledTrack() const
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ if (anonymousIndexedGetter(i)->enabled())
+ return true;
+ }
+
+ return false;
+}
+
+const AtomicString& AudioTrackList::interfaceName() const
+{
+ return EventTargetNames::AudioTrackList;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h
new file mode 100644
index 00000000000..504de8be9cd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AudioTrackList_h
+#define AudioTrackList_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/AudioTrack.h"
+#include "core/html/track/TrackListBase.h"
+
+namespace WebCore {
+
+class AudioTrackList FINAL : public TrackListBase<AudioTrack>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<AudioTrackList> create(HTMLMediaElement&);
+
+ virtual ~AudioTrackList();
+
+ bool hasEnabledTrack() const;
+
+ // EventTarget
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+private:
+ explicit AudioTrackList(HTMLMediaElement&);
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl
new file mode 100644
index 00000000000..6bcd4736ce5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl
@@ -0,0 +1,16 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+] interface AudioTrackList : EventTarget {
+ readonly attribute unsigned long length;
+ getter AudioTrack (unsigned long index);
+ AudioTrack? getTrackById(DOMString id);
+
+ attribute EventHandler onchange;
+ attribute EventHandler onaddtrack;
+ attribute EventHandler onremovetrack;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp
index 925f84e7c9d..ce05095498b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp
@@ -27,6 +27,7 @@
#include "core/html/track/InbandTextTrack.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/html/HTMLMediaElement.h"
#include "core/html/track/vtt/VTTCue.h"
#include "platform/Logging.h"
#include "public/platform/WebInbandTextTrack.h"
@@ -38,13 +39,13 @@ using blink::WebString;
namespace WebCore {
-PassRefPtr<InbandTextTrack> InbandTextTrack::create(Document& document, TextTrackClient* client, WebInbandTextTrack* webTrack)
+PassRefPtrWillBeRawPtr<InbandTextTrack> InbandTextTrack::create(Document& document, WebInbandTextTrack* webTrack)
{
- return adoptRef(new InbandTextTrack(document, client, webTrack));
+ return adoptRefWillBeRefCountedGarbageCollected(new InbandTextTrack(document, webTrack));
}
-InbandTextTrack::InbandTextTrack(Document& document, TextTrackClient* client, WebInbandTextTrack* webTrack)
- : TextTrack(document, client, emptyAtom, webTrack->label(), webTrack->language(), webTrack->id(), InBand)
+InbandTextTrack::InbandTextTrack(Document& document, WebInbandTextTrack* webTrack)
+ : TextTrack(document, emptyAtom, webTrack->label(), webTrack->language(), webTrack->id(), InBand)
, m_webTrack(webTrack)
{
m_webTrack->setClient(this);
@@ -74,8 +75,13 @@ InbandTextTrack::InbandTextTrack(Document& document, TextTrackClient* client, We
InbandTextTrack::~InbandTextTrack()
{
+#if ENABLE(OILPAN)
+ if (m_webTrack)
+ m_webTrack->setClient(0);
+#else
// Make sure m_webTrack was cleared by trackRemoved() before destruction.
ASSERT(!m_webTrack);
+#endif
}
size_t InbandTextTrack::inbandTrackIndex()
@@ -84,17 +90,22 @@ size_t InbandTextTrack::inbandTrackIndex()
return m_webTrack->textTrackIndex();
}
-void InbandTextTrack::trackRemoved()
+void InbandTextTrack::setTrackList(TextTrackList* trackList)
{
+ TextTrack::setTrackList(trackList);
+ if (trackList)
+ return;
+
ASSERT(m_webTrack);
m_webTrack->setClient(0);
m_webTrack = 0;
- clearClient();
}
void InbandTextTrack::addWebVTTCue(double start, double end, const WebString& id, const WebString& content, const WebString& settings)
{
- RefPtr<VTTCue> cue = VTTCue::create(document(), start, end, content);
+ HTMLMediaElement* owner = mediaElement();
+ ASSERT(owner);
+ RefPtrWillBeRawPtr<VTTCue> cue = VTTCue::create(owner->document(), start, end, content);
cue->setId(id);
cue->parseSettings(settings);
addCue(cue);
diff --git a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h
index 83948f0e77a..47d39f39555 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h
@@ -27,6 +27,7 @@
#define InbandTextTrack_h
#include "core/html/track/TextTrack.h"
+#include "platform/heap/Handle.h"
#include "public/platform/WebInbandTextTrackClient.h"
#include "wtf/RefPtr.h"
@@ -41,16 +42,16 @@ class Document;
class MediaPlayer;
class TextTrackCue;
-class InbandTextTrack : public TextTrack, public blink::WebInbandTextTrackClient {
+class InbandTextTrack FINAL : public TextTrack, public blink::WebInbandTextTrackClient {
public:
- static PassRefPtr<InbandTextTrack> create(Document&, TextTrackClient*, blink::WebInbandTextTrack*);
+ static PassRefPtrWillBeRawPtr<InbandTextTrack> create(Document&, blink::WebInbandTextTrack*);
virtual ~InbandTextTrack();
size_t inbandTrackIndex();
- void trackRemoved();
+ virtual void setTrackList(TextTrackList*) OVERRIDE FINAL;
private:
- InbandTextTrack(Document&, TextTrackClient*, blink::WebInbandTextTrack*);
+ InbandTextTrack(Document&, blink::WebInbandTextTrack*);
virtual void addWebVTTCue(double, double, const blink::WebString&, const blink::WebString&, const blink::WebString&) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp
index 588c06c79ff..288ec204df8 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp
@@ -26,14 +26,18 @@
#include "config.h"
#include "core/html/track/LoadableTextTrack.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLMediaElement.h"
#include "core/html/HTMLTrackElement.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/vtt/VTTRegionList.h"
namespace WebCore {
+using namespace HTMLNames;
+
LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track)
- : TextTrack(track->document(), track, emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement)
+ : TextTrack(track->document(), emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement)
, m_trackElement(track)
, m_loadTimer(this, &LoadableTextTrack::loadTimerFired)
, m_isDefault(false)
@@ -42,12 +46,26 @@ LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track)
LoadableTextTrack::~LoadableTextTrack()
{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_trackElement);
+#endif
}
-void LoadableTextTrack::clearClient()
+#if !ENABLE(OILPAN)
+void LoadableTextTrack::clearTrackElement()
{
- m_trackElement = 0;
- TextTrack::clearClient();
+ m_trackElement = nullptr;
+}
+#endif
+
+void LoadableTextTrack::setMode(const AtomicString& mode)
+{
+ TextTrack::setMode(mode);
+ if (!m_trackElement)
+ return;
+
+ if (m_trackElement->readyState() == HTMLTrackElement::NONE)
+ m_trackElement->scheduleLoad();
}
void LoadableTextTrack::scheduleLoad(const KURL& url)
@@ -72,7 +90,7 @@ void LoadableTextTrack::scheduleLoad(const KURL& url)
// 3. Asynchronously run the remaining steps, while continuing with whatever task
// was responsible for creating the text track or changing the text track mode.
if (!m_loadTimer.isActive())
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*)
@@ -97,7 +115,7 @@ void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
{
ASSERT_UNUSED(loader, m_loader == loader);
- Vector<RefPtr<VTTCue> > newCues;
+ WillBeHeapVector<RefPtrWillBeMember<VTTCue> > newCues;
m_loader->getNewCues(newCues);
if (!m_cues)
@@ -105,11 +123,11 @@ void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
for (size_t i = 0; i < newCues.size(); ++i) {
newCues[i]->setTrack(this);
- m_cues->add(newCues[i]);
+ m_cues->add(newCues[i].release());
}
- if (client())
- client()->textTrackAddCues(this, m_cues.get());
+ if (mediaElement())
+ mediaElement()->textTrackAddCues(this, m_cues.get());
}
void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed)
@@ -126,7 +144,7 @@ void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader)
{
ASSERT_UNUSED(loader, m_loader == loader);
- Vector<RefPtr<VTTRegion> > newRegions;
+ WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > newRegions;
m_loader->getNewRegions(newRegions);
for (size_t i = 0; i < newRegions.size(); ++i) {
@@ -141,10 +159,10 @@ size_t LoadableTextTrack::trackElementIndex()
ASSERT(m_trackElement->parentNode());
size_t index = 0;
- for (Node* node = m_trackElement->parentNode()->firstChild(); node; node = node->nextSibling()) {
- if (!node->hasTagName(trackTag) || !node->parentNode())
+ for (HTMLTrackElement* track = Traversal<HTMLTrackElement>::firstChild(*m_trackElement->parentNode()); track; track = Traversal<HTMLTrackElement>::nextSibling(*track)) {
+ if (!track->parentNode())
continue;
- if (node == m_trackElement)
+ if (track == m_trackElement)
return index;
++index;
}
@@ -153,5 +171,11 @@ size_t LoadableTextTrack::trackElementIndex()
return 0;
}
-} // namespace WebCore
+void LoadableTextTrack::trace(Visitor* visitor)
+{
+ visitor->trace(m_trackElement);
+ visitor->trace(m_loader);
+ TextTrack::trace(visitor);
+}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h
index 487e7caab78..c99f4f1b3c6 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h
@@ -28,6 +28,7 @@
#include "core/html/track/TextTrack.h"
#include "core/loader/TextTrackLoader.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -35,25 +36,30 @@ namespace WebCore {
class HTMLTrackElement;
class LoadableTextTrack;
-class LoadableTextTrack : public TextTrack, private TextTrackLoaderClient {
+class LoadableTextTrack FINAL : public TextTrack, private TextTrackLoaderClient {
public:
- static PassRefPtr<LoadableTextTrack> create(HTMLTrackElement* track)
+ static PassRefPtrWillBeRawPtr<LoadableTextTrack> create(HTMLTrackElement* track)
{
- return adoptRef(new LoadableTextTrack(track));
+ return adoptRefWillBeRefCountedGarbageCollected(new LoadableTextTrack(track));
}
virtual ~LoadableTextTrack();
void scheduleLoad(const KURL&);
- // This shadows TextTrack::clearClient, but need not be virtual.
- void clearClient();
+ // TextTrack method.
+ virtual void setMode(const AtomicString&) OVERRIDE;
size_t trackElementIndex();
HTMLTrackElement* trackElement() { return m_trackElement; }
+#if !ENABLE(OILPAN)
+ void clearTrackElement();
+#endif
virtual bool isDefault() const OVERRIDE { return m_isDefault; }
virtual void setIsDefault(bool isDefault) OVERRIDE { m_isDefault = isDefault; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
// TextTrackLoaderClient
virtual void newCuesAvailable(TextTrackLoader*) OVERRIDE;
@@ -64,9 +70,11 @@ private:
void loadTimerFired(Timer<LoadableTextTrack>*);
- HTMLTrackElement* m_trackElement;
+ // FIXME: Oilpan: This should be a strong pointer once Member pointers
+ // into the Node hierarchy can be used.
+ RawPtrWillBeWeakMember<HTMLTrackElement> m_trackElement;
Timer<LoadableTextTrack> m_loadTimer;
- OwnPtr<TextTrackLoader> m_loader;
+ OwnPtrWillBeMember<TextTrackLoader> m_loader;
KURL m_url;
bool m_isDefault;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp
index 84dea3e44a3..cf5b51248b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp
@@ -32,7 +32,6 @@
#include "config.h"
#include "core/html/track/TextTrack.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Document.h"
@@ -42,6 +41,7 @@
#include "core/html/track/TextTrackList.h"
#include "core/html/track/vtt/VTTRegion.h"
#include "core/html/track/vtt/VTTRegionList.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -95,17 +95,12 @@ const AtomicString& TextTrack::showingKeyword()
return ended;
}
-TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
- : TrackBase(TrackBase::TextTrack)
- , m_cues(0)
- , m_regions(0)
- , m_document(&document)
- , m_mediaElement(0)
- , m_label(label)
- , m_language(language)
- , m_id(id)
+TextTrack::TextTrack(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
+ : TrackBase(TrackBase::TextTrack, label, language, id)
+ , m_cues(nullptr)
+ , m_regions(nullptr)
+ , m_trackList(nullptr)
, m_mode(disabledKeyword())
- , m_client(client)
, m_trackType(type)
, m_readinessState(NotLoaded)
, m_trackIndex(invalidTrackIndex)
@@ -118,19 +113,18 @@ TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicSt
TextTrack::~TextTrack()
{
- if (m_cues) {
- if (m_client)
- m_client->textTrackRemoveCues(this, m_cues.get());
+#if !ENABLE(OILPAN)
+ ASSERT(!m_trackList);
+ if (m_cues) {
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
}
-
if (m_regions) {
for (size_t i = 0; i < m_regions->length(); ++i)
m_regions->item(i)->setTrack(0);
}
- clearClient();
+#endif
}
bool TextTrack::isValidKindKeyword(const AtomicString& value)
@@ -149,17 +143,22 @@ bool TextTrack::isValidKindKeyword(const AtomicString& value)
return false;
}
-void TextTrack::setKind(const AtomicString& kind)
+void TextTrack::setTrackList(TextTrackList* trackList)
{
- String oldKind = m_kind;
+ if (!trackList && mediaElement() && m_cues)
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
+
+ m_trackList = trackList;
+ invalidateTrackIndex();
+}
- if (isValidKindKeyword(kind))
- m_kind = kind;
- else
- m_kind = subtitlesKeyword();
+void TextTrack::setKind(const AtomicString& newKind)
+{
+ AtomicString oldKind = kind();
+ TrackBase::setKind(newKind);
- if (m_client && oldKind != m_kind)
- m_client->textTrackKindChanged(this);
+ if (mediaElement() && oldKind != kind())
+ mediaElement()->textTrackKindChanged(this);
}
void TextTrack::setMode(const AtomicString& mode)
@@ -173,8 +172,8 @@ void TextTrack::setMode(const AtomicString& mode)
// If mode changes to disabled, remove this track's cues from the client
// because they will no longer be accessible from the cues() function.
- if (mode == disabledKeyword() && m_client && m_cues)
- m_client->textTrackRemoveCues(this, m_cues.get());
+ if (mode == disabledKeyword() && mediaElement() && m_cues)
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
if (mode != showingKeyword() && m_cues)
for (size_t i = 0; i < m_cues->length(); ++i)
@@ -182,8 +181,8 @@ void TextTrack::setMode(const AtomicString& mode)
m_mode = mode;
- if (m_client)
- m_client->textTrackModeChanged(this);
+ if (mediaElement())
+ mediaElement()->textTrackModeChanged(this);
}
TextTrackCueList* TextTrack::cues()
@@ -203,13 +202,13 @@ void TextTrack::removeAllCues()
if (!m_cues)
return;
- if (m_client)
- m_client->textTrackRemoveCues(this, m_cues.get());
+ if (mediaElement())
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
- m_cues = 0;
+ m_cues = nullptr;
}
TextTrackCueList* TextTrack::activeCues() const
@@ -225,12 +224,12 @@ TextTrackCueList* TextTrack::activeCues() const
return 0;
}
-void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue)
+void TextTrack::addCue(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue)
{
if (!prpCue)
return;
- RefPtr<TextTrackCue> cue = prpCue;
+ RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
// TODO(93143): Add spec-compliant behavior for negative time values.
if (std::isnan(cue->startTime()) || std::isnan(cue->endTime()) || cue->startTime() < 0 || cue->endTime() < 0)
@@ -250,8 +249,8 @@ void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue)
cue->setTrack(this);
ensureTextTrackCueList()->add(cue);
- if (m_client)
- m_client->textTrackAddCue(this, cue.get());
+ if (mediaElement())
+ mediaElement()->textTrackAddCue(this, cue.get());
}
void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState)
@@ -277,8 +276,8 @@ void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState)
}
cue->setTrack(0);
- if (m_client)
- m_client->textTrackRemoveCue(this, cue);
+ if (mediaElement())
+ mediaElement()->textTrackRemoveCue(this, cue);
}
VTTRegionList* TextTrack::ensureVTTRegionList()
@@ -302,12 +301,12 @@ VTTRegionList* TextTrack::regions()
return 0;
}
-void TextTrack::addRegion(PassRefPtr<VTTRegion> prpRegion)
+void TextTrack::addRegion(PassRefPtrWillBeRawPtr<VTTRegion> prpRegion)
{
if (!prpRegion)
return;
- RefPtr<VTTRegion> region = prpRegion;
+ RefPtrWillBeRawPtr<VTTRegion> region = prpRegion;
VTTRegionList* regionList = ensureVTTRegionList();
// 1. If the given region is in a text track list of regions, then remove
@@ -354,32 +353,32 @@ void TextTrack::removeRegion(VTTRegion* region, ExceptionState &exceptionState)
void TextTrack::cueWillChange(TextTrackCue* cue)
{
- if (!m_client)
+ if (!mediaElement())
return;
// The cue may need to be repositioned in the media element's interval tree, may need to
// be re-rendered, etc, so remove it before the modification...
- m_client->textTrackRemoveCue(this, cue);
+ mediaElement()->textTrackRemoveCue(this, cue);
}
void TextTrack::cueDidChange(TextTrackCue* cue)
{
- if (!m_client)
+ if (!mediaElement())
return;
// Make sure the TextTrackCueList order is up-to-date.
ensureTextTrackCueList()->updateCueIndex(cue);
// ... and add it back again.
- m_client->textTrackAddCue(this, cue);
+ mediaElement()->textTrackAddCue(this, cue);
}
int TextTrack::trackIndex()
{
- ASSERT(m_mediaElement);
+ ASSERT(m_trackList);
if (m_trackIndex == invalidTrackIndex)
- m_trackIndex = m_mediaElement->textTracks()->getTrackIndex(this);
+ m_trackIndex = m_trackList->getTrackIndex(this);
return m_trackIndex;
}
@@ -392,7 +391,7 @@ void TextTrack::invalidateTrackIndex()
bool TextTrack::isRendered()
{
- if (m_kind != captionsKeyword() && m_kind != subtitlesKeyword())
+ if (kind() != captionsKeyword() && kind() != subtitlesKeyword())
return false;
if (m_mode != showingKeyword())
@@ -411,10 +410,10 @@ TextTrackCueList* TextTrack::ensureTextTrackCueList()
int TextTrack::trackIndexRelativeToRenderedTracks()
{
- ASSERT(m_mediaElement);
+ ASSERT(m_trackList);
if (m_renderedTrackIndex == invalidTrackIndex)
- m_renderedTrackIndex = m_mediaElement->textTracks()->getTrackIndexRelativeToRenderedTracks(this);
+ m_renderedTrackIndex = m_trackList->getTrackIndexRelativeToRenderedTracks(this);
return m_renderedTrackIndex;
}
@@ -426,8 +425,27 @@ const AtomicString& TextTrack::interfaceName() const
ExecutionContext* TextTrack::executionContext() const
{
- return m_document;
+ HTMLMediaElement* owner = mediaElement();
+ return owner ? owner->executionContext() : 0;
}
-} // namespace WebCore
+HTMLMediaElement* TextTrack::mediaElement() const
+{
+ return m_trackList ? m_trackList->owner() : 0;
+}
+
+Node* TextTrack::owner() const
+{
+ return mediaElement();
+}
+void TextTrack::trace(Visitor* visitor)
+{
+ visitor->trace(m_cues);
+ visitor->trace(m_regions);
+ visitor->trace(m_trackList);
+ TrackBase::trace(visitor);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h
index 721c55566b0..3be6bdf469a 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h
@@ -28,7 +28,9 @@
#define TextTrack_h
#include "bindings/v8/ScriptWrappable.h"
+#include "core/events/EventTarget.h"
#include "core/html/track/TrackBase.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -39,33 +41,24 @@ class HTMLMediaElement;
class TextTrack;
class TextTrackCue;
class TextTrackCueList;
+class TextTrackList;
class VTTRegion;
class VTTRegionList;
-class TextTrackClient {
+class TextTrack : public TrackBase, public ScriptWrappable, public EventTargetWithInlineData {
+ REFCOUNTED_EVENT_TARGET(TrackBase);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextTrack);
public:
- virtual ~TextTrackClient() { }
- virtual void textTrackKindChanged(TextTrack*) = 0;
- virtual void textTrackModeChanged(TextTrack*) = 0;
- virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) = 0;
- virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) = 0;
- virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) = 0;
- virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) = 0;
-};
-
-class TextTrack : public TrackBase, public ScriptWrappable {
-public:
- static PassRefPtr<TextTrack> create(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language)
+ static PassRefPtrWillBeRawPtr<TextTrack> create(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language)
{
- return adoptRef(new TextTrack(document, client, kind, label, language, emptyAtom, AddTrack));
+ return adoptRefWillBeRefCountedGarbageCollected(new TextTrack(document, kind, label, language, emptyAtom, AddTrack));
}
virtual ~TextTrack();
- void setMediaElement(HTMLMediaElement* element) { m_mediaElement = element; }
- HTMLMediaElement* mediaElement() { return m_mediaElement; }
+ virtual void setTrackList(TextTrackList*);
+ TextTrackList* trackList() { return m_trackList; }
- const AtomicString& kind() const { return m_kind; }
- void setKind(const AtomicString&);
+ virtual void setKind(const AtomicString&) OVERRIDE;
static const AtomicString& subtitlesKeyword();
static const AtomicString& captionsKeyword();
@@ -74,21 +67,12 @@ public:
static const AtomicString& metadataKeyword();
static bool isValidKindKeyword(const AtomicString&);
- AtomicString label() const { return m_label; }
- void setLabel(const AtomicString& label) { m_label = label; }
-
- AtomicString language() const { return m_language; }
- void setLanguage(const AtomicString& language) { m_language = language; }
-
- AtomicString id() const { return m_id; }
- void setId(const AtomicString& id) { m_id = id; }
-
static const AtomicString& disabledKeyword();
static const AtomicString& hiddenKeyword();
static const AtomicString& showingKeyword();
AtomicString mode() const { return m_mode; }
- void setMode(const AtomicString&);
+ virtual void setMode(const AtomicString&);
enum ReadinessState { NotLoaded = 0, Loading = 1, Loaded = 2, FailedToLoad = 3 };
ReadinessState readinessState() const { return m_readinessState; }
@@ -97,14 +81,14 @@ public:
TextTrackCueList* cues();
TextTrackCueList* activeCues() const;
- void clearClient() { m_client = 0; }
- TextTrackClient* client() { return m_client; }
+ HTMLMediaElement* mediaElement() const;
+ Node* owner() const;
- void addCue(PassRefPtr<TextTrackCue>);
+ void addCue(PassRefPtrWillBeRawPtr<TextTrackCue>);
void removeCue(TextTrackCue*, ExceptionState&);
VTTRegionList* regions();
- void addRegion(PassRefPtr<VTTRegion>);
+ void addRegion(PassRefPtrWillBeRawPtr<VTTRegion>);
void removeRegion(VTTRegion*, ExceptionState&);
void cueWillChange(TextTrackCue*);
@@ -129,33 +113,28 @@ public:
void removeAllCues();
- Document& document() const { return *m_document; }
-
// EventTarget methods
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- TextTrack(Document&, TextTrackClient*, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType);
+ TextTrack(Document&, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType);
- RefPtr<TextTrackCueList> m_cues;
+ virtual bool isValidKind(const AtomicString& kind) const OVERRIDE { return isValidKindKeyword(kind); }
+ virtual AtomicString defaultKind() const OVERRIDE { return subtitlesKeyword(); }
+
+ RefPtrWillBeMember<TextTrackCueList> m_cues;
private:
VTTRegionList* ensureVTTRegionList();
- RefPtr<VTTRegionList> m_regions;
+ RefPtrWillBeMember<VTTRegionList> m_regions;
TextTrackCueList* ensureTextTrackCueList();
- // FIXME: Remove this pointer and get the Document from m_client
- Document* m_document;
-
- HTMLMediaElement* m_mediaElement;
- AtomicString m_kind;
- AtomicString m_label;
- AtomicString m_language;
- AtomicString m_id;
+ RawPtrWillBeMember<TextTrackList> m_trackList;
AtomicString m_mode;
- TextTrackClient* m_client;
TextTrackType m_trackType;
ReadinessState m_readinessState;
int m_trackIndex;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl
index a64462d028f..9a75f4b0def 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl
@@ -27,7 +27,8 @@ enum TextTrackMode { "disabled", "hidden", "showing" };
enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" };
[
- RuntimeEnabled=VideoTrack
+ SetWrapperReferenceFrom=owner,
+ WillBeGarbageCollected,
] interface TextTrack : EventTarget {
readonly attribute TextTrackKind kind;
readonly attribute DOMString label;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp
index cfb2effe24b..bdb32505bb7 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp
@@ -42,20 +42,11 @@ namespace WebCore {
static const int invalidCueIndex = -1;
-bool TextTrackCue::isInfiniteOrNonNumber(double value, ExceptionState& exceptionState)
-{
- if (!std::isfinite(value)) {
- exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(value));
- return true;
- }
- return false;
-}
-
TextTrackCue::TextTrackCue(double start, double end)
: m_startTime(start)
, m_endTime(end)
, m_cueIndex(invalidCueIndex)
- , m_track(0)
+ , m_track(nullptr)
, m_isActive(false)
, m_pauseOnExit(false)
{
@@ -83,7 +74,12 @@ void TextTrackCue::setTrack(TextTrack* track)
m_track = track;
}
-void TextTrackCue::setId(const String& id)
+Node* TextTrackCue::owner() const
+{
+ return m_track ? m_track->owner() : 0;
+}
+
+void TextTrackCue::setId(const AtomicString& id)
{
if (m_id == id)
return;
@@ -93,12 +89,8 @@ void TextTrackCue::setId(const String& id)
cueDidChange();
}
-void TextTrackCue::setStartTime(double value, ExceptionState& exceptionState)
+void TextTrackCue::setStartTime(double value)
{
- // NaN, Infinity and -Infinity values should trigger a TypeError.
- if (isInfiniteOrNonNumber(value, exceptionState))
- return;
-
// TODO(93143): Add spec-compliant behavior for negative time values.
if (m_startTime == value || value < 0)
return;
@@ -108,12 +100,8 @@ void TextTrackCue::setStartTime(double value, ExceptionState& exceptionState)
cueDidChange();
}
-void TextTrackCue::setEndTime(double value, ExceptionState& exceptionState)
+void TextTrackCue::setEndTime(double value)
{
- // NaN, Infinity and -Infinity values should trigger a TypeError.
- if (isInfiniteOrNonNumber(value, exceptionState))
- return;
-
// TODO(93143): Add spec-compliant behavior for negative time values.
if (m_endTime == value || value < 0)
return;
@@ -146,7 +134,7 @@ void TextTrackCue::invalidateCueIndex()
m_cueIndex = invalidCueIndex;
}
-bool TextTrackCue::dispatchEvent(PassRefPtr<Event> event)
+bool TextTrackCue::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
// When a TextTrack's mode is disabled: no cues are active, no events fired.
if (!track() || track()->mode() == TextTrack::disabledKeyword())
@@ -174,4 +162,10 @@ const AtomicString& TextTrackCue::interfaceName() const
return EventTargetNames::TextTrackCue;
}
+void TextTrackCue::trace(Visitor* visitor)
+{
+ visitor->trace(m_track);
+ EventTargetWithInlineData::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h
index 1779e37a7d1..dd2d235b732 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h
@@ -34,17 +34,17 @@
#include "core/events/EventTarget.h"
#include "core/html/HTMLDivElement.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
class ExceptionState;
-class TextTrackCue : public RefCounted<TextTrackCue>, public EventTargetWithInlineData {
+class TextTrackCue : public RefCountedWillBeRefCountedGarbageCollected<TextTrackCue>, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(TextTrackCue);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextTrackCue);
public:
- static bool isInfiniteOrNonNumber(double value, ExceptionState&);
-
static const AtomicString& cueShadowPseudoId()
{
DEFINE_STATIC_LOCAL(const AtomicString, cue, ("cue", AtomicString::ConstructFromLiteral));
@@ -56,14 +56,16 @@ public:
TextTrack* track() const;
void setTrack(TextTrack*);
- const String& id() const { return m_id; }
- void setId(const String&);
+ Node* owner() const;
+
+ const AtomicString& id() const { return m_id; }
+ void setId(const AtomicString&);
double startTime() const { return m_startTime; }
- void setStartTime(double, ExceptionState&);
+ void setStartTime(double);
double endTime() const { return m_endTime; }
- void setEndTime(double, ExceptionState&);
+ void setEndTime(double);
bool pauseOnExit() const { return m_pauseOnExit; }
void setPauseOnExit(bool);
@@ -72,7 +74,7 @@ public:
void invalidateCueIndex();
using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
bool isActive();
void setIsActive(bool);
@@ -94,6 +96,8 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(enter);
DEFINE_ATTRIBUTE_EVENT_LISTENER(exit);
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
TextTrackCue(double start, double end);
@@ -101,12 +105,12 @@ protected:
virtual void cueDidChange();
private:
- String m_id;
+ AtomicString m_id;
double m_startTime;
double m_endTime;
int m_cueIndex;
- TextTrack* m_track;
+ RawPtrWillBeMember<TextTrack> m_track;
bool m_isActive : 1;
bool m_pauseOnExit : 1;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl
index efc18e3e60a..d243c43edec 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl
@@ -23,18 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue
+
[
Custom=ToV8,
- CustomConstructor(double startTime, double endTime, DOMString text),
- RuntimeEnabled=VideoTrack,
+ SetWrapperReferenceFrom=owner,
+ TypeChecking=Unrestricted,
+ WillBeGarbageCollected,
] interface TextTrackCue : EventTarget {
- readonly attribute TextTrack track;
+ readonly attribute TextTrack track; // FIXME: should be nullable
- attribute DOMString id;
- [RaisesException=Setter] attribute double startTime;
- [RaisesException=Setter] attribute double endTime;
- attribute boolean pauseOnExit;
+ attribute DOMString id;
+ attribute double startTime;
+ attribute double endTime;
+ attribute boolean pauseOnExit;
- attribute EventHandler onenter;
- attribute EventHandler onexit;
+ attribute EventHandler onenter;
+ attribute EventHandler onexit;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp
index 43fa9b55c40..a3dba2dc76b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp
@@ -51,7 +51,7 @@ TextTrackCue* TextTrackCueList::item(unsigned index) const
return 0;
}
-TextTrackCue* TextTrackCueList::getCueById(const String& id) const
+TextTrackCue* TextTrackCueList::getCueById(const AtomicString& id) const
{
for (size_t i = 0; i < m_list.size(); ++i) {
if (m_list[i]->id() == id)
@@ -67,14 +67,14 @@ TextTrackCueList* TextTrackCueList::activeCues()
m_activeCues->clear();
for (size_t i = 0; i < m_list.size(); ++i) {
- RefPtr<TextTrackCue> cue = m_list[i];
+ RefPtrWillBeRawPtr<TextTrackCue> cue = m_list[i];
if (cue->isActive())
m_activeCues->add(cue);
}
return m_activeCues.get();
}
-bool TextTrackCueList::add(PassRefPtr<TextTrackCue> cue)
+bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> cue)
{
ASSERT(cue->startTime() >= 0);
ASSERT(cue->endTime() >= 0);
@@ -82,14 +82,14 @@ bool TextTrackCueList::add(PassRefPtr<TextTrackCue> cue)
return add(cue, 0, m_list.size());
}
-bool TextTrackCueList::add(PassRefPtr<TextTrackCue> prpCue, size_t start, size_t end)
+bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue, size_t start, size_t end)
{
ASSERT_WITH_SECURITY_IMPLICATION(start <= m_list.size());
ASSERT_WITH_SECURITY_IMPLICATION(end <= m_list.size());
// Maintain text track cue order:
// http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-order
- RefPtr<TextTrackCue> cue = prpCue;
+ RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
if (start == end) {
if (!m_list.isEmpty() && (start > 0) && (m_list[start - 1].get() == cue.get()))
return false;
@@ -142,5 +142,11 @@ void TextTrackCueList::invalidateCueIndexes(size_t start)
m_list[i]->invalidateCueIndex();
}
+void TextTrackCueList::trace(Visitor* visitor)
+{
+ visitor->trace(m_list);
+ visitor->trace(m_activeCues);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h
index b209fcf6e26..ace42e12f6b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h
@@ -34,11 +34,11 @@
namespace WebCore {
-class TextTrackCueList : public RefCounted<TextTrackCueList>, public ScriptWrappable {
+class TextTrackCueList FINAL : public RefCountedWillBeGarbageCollectedFinalized<TextTrackCueList>, public ScriptWrappable {
public:
- static PassRefPtr<TextTrackCueList> create()
+ static PassRefPtrWillBeRawPtr<TextTrackCueList> create()
{
- return adoptRef(new TextTrackCueList);
+ return adoptRefWillBeNoop(new TextTrackCueList);
}
~TextTrackCueList() { }
@@ -47,23 +47,25 @@ public:
unsigned long getCueIndex(TextTrackCue*) const;
TextTrackCue* item(unsigned index) const;
- TextTrackCue* getCueById(const String&) const;
+ TextTrackCue* getCueById(const AtomicString&) const;
TextTrackCueList* activeCues();
- bool add(PassRefPtr<TextTrackCue>);
+ bool add(PassRefPtrWillBeRawPtr<TextTrackCue>);
bool remove(TextTrackCue*);
bool contains(TextTrackCue*) const;
bool updateCueIndex(TextTrackCue*);
+ void trace(Visitor*);
+
private:
TextTrackCueList();
- bool add(PassRefPtr<TextTrackCue>, size_t, size_t);
+ bool add(PassRefPtrWillBeRawPtr<TextTrackCue>, size_t, size_t);
void clear();
void invalidateCueIndexes(size_t);
- Vector<RefPtr<TextTrackCue> > m_list;
- RefPtr<TextTrackCueList> m_activeCues;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrackCue> > m_list;
+ RefPtrWillBeMember<TextTrackCueList> m_activeCues;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl
index a71d6875ddb..6ea59a645cd 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl
@@ -24,7 +24,7 @@
*/
[
- RuntimeEnabled=VideoTrack
+ WillBeGarbageCollected,
] interface TextTrackCueList {
readonly attribute unsigned long length;
getter TextTrackCue item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
index 0d00ba33fee..0738c95e7ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
@@ -28,7 +28,6 @@
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/events/GenericEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/track/InbandTextTrack.h"
#include "core/html/track/LoadableTextTrack.h"
@@ -46,7 +45,18 @@ TextTrackList::TextTrackList(HTMLMediaElement* owner)
TextTrackList::~TextTrackList()
{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_owner);
+
+ // TextTrackList and m_asyncEventQueue always become unreachable
+ // together. So TextTrackList and m_asyncEventQueue are destructed in the
+ // same GC. We don't need to close it explicitly in Oilpan.
m_asyncEventQueue->close();
+
+ for (unsigned i = 0; i < length(); ++i) {
+ item(i)->setTrackList(0);
+ }
+#endif
}
unsigned TextTrackList::length() const
@@ -148,7 +158,7 @@ TextTrack* TextTrackList::getTrackById(const AtomicString& id)
void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
{
- Vector<RefPtr<TextTrack> >* tracks = 0;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement) {
tracks = &m_elementTracks;
@@ -173,9 +183,9 @@ void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
tracks->at(index)->invalidateTrackIndex();
}
-void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
+void TextTrackList::append(PassRefPtrWillBeRawPtr<TextTrack> prpTrack)
{
- RefPtr<TextTrack> track = prpTrack;
+ RefPtrWillBeRawPtr<TextTrack> track = prpTrack;
if (track->trackType() == TextTrack::AddTrack)
m_addTrackTracks.append(track);
@@ -192,16 +202,15 @@ void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
invalidateTrackIndexesAfterTrack(track.get());
- ASSERT(!track->mediaElement() || track->mediaElement() == m_owner);
- track->setMediaElement(m_owner);
+ ASSERT(!track->trackList());
+ track->setTrackList(this);
scheduleAddTrackEvent(track.release());
}
void TextTrackList::remove(TextTrack* track)
{
- Vector<RefPtr<TextTrack> >* tracks = 0;
- RefPtr<InbandTextTrack> inbandTrack;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement) {
tracks = &m_elementTracks;
@@ -209,7 +218,6 @@ void TextTrackList::remove(TextTrack* track)
tracks = &m_addTrackTracks;
} else if (track->trackType() == TextTrack::InBand) {
tracks = &m_inbandTracks;
- inbandTrack = static_cast<InbandTextTrack*>(track);
} else {
ASSERT_NOT_REACHED();
}
@@ -220,20 +228,25 @@ void TextTrackList::remove(TextTrack* track)
invalidateTrackIndexesAfterTrack(track);
- ASSERT(track->mediaElement() == m_owner);
- track->setMediaElement(0);
+ ASSERT(track->trackList() == this);
+ track->setTrackList(0);
tracks->remove(index);
- if (inbandTrack)
- inbandTrack->trackRemoved();
-
scheduleRemoveTrackEvent(track);
}
+void TextTrackList::removeAllInbandTracks()
+{
+ for (unsigned i = 0; i < m_inbandTracks.size(); ++i) {
+ m_inbandTracks[i]->setTrackList(0);
+ }
+ m_inbandTracks.clear();
+}
+
bool TextTrackList::contains(TextTrack* track) const
{
- const Vector<RefPtr<TextTrack> >* tracks = 0;
+ const WillBeHeapVector<RefPtrWillBeMember<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement)
tracks = &m_elementTracks;
@@ -254,11 +267,17 @@ const AtomicString& TextTrackList::interfaceName() const
ExecutionContext* TextTrackList::executionContext() const
{
- ASSERT(m_owner);
- return m_owner->executionContext();
+ return m_owner ? m_owner->executionContext() : 0;
+}
+
+#if !ENABLE(OILPAN)
+void TextTrackList::clearOwner()
+{
+ m_owner = nullptr;
}
+#endif
-void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TextTrack> track)
+void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<TextTrack> track)
{
TrackEventInit initializer;
initializer.track = track;
@@ -268,7 +287,7 @@ void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr
m_asyncEventQueue->enqueueEvent(TrackEvent::create(eventName, initializer));
}
-void TextTrackList::scheduleAddTrackEvent(PassRefPtr<TextTrack> track)
+void TextTrackList::scheduleAddTrackEvent(PassRefPtrWillBeRawPtr<TextTrack> track)
{
// 4.8.10.12.3 Sourcing out-of-band text tracks
// 4.8.10.12.4 Text track API
@@ -296,7 +315,7 @@ void TextTrackList::scheduleChangeEvent()
m_asyncEventQueue->enqueueEvent(Event::create(EventTypeNames::change, initializer));
}
-void TextTrackList::scheduleRemoveTrackEvent(PassRefPtr<TextTrack> track)
+void TextTrackList::scheduleRemoveTrackEvent(PassRefPtrWillBeRawPtr<TextTrack> track)
{
// 4.8.10.12.3 Sourcing out-of-band text tracks
// When a track element's parent element changes and the old parent was a
@@ -310,7 +329,17 @@ void TextTrackList::scheduleRemoveTrackEvent(PassRefPtr<TextTrack> track)
scheduleTrackEvent(EventTypeNames::removetrack, track);
}
-Node* TextTrackList::owner() const
+HTMLMediaElement* TextTrackList::owner() const
{
return m_owner;
}
+
+void TextTrackList::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
+ visitor->trace(m_asyncEventQueue);
+ visitor->trace(m_addTrackTracks);
+ visitor->trace(m_elementTracks);
+ visitor->trace(m_inbandTracks);
+ EventTargetWithInlineData::trace(visitor);
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h
index 7c150b2c931..a544f24761c 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h
@@ -29,7 +29,9 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
+#include "core/html/HTMLMediaElement.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -37,18 +39,17 @@
namespace WebCore {
class GenericEventQueue;
-class HTMLMediaElement;
class TextTrack;
-class TextTrackList;
-class TextTrackList : public RefCounted<TextTrackList>, public ScriptWrappable, public EventTargetWithInlineData {
+class TextTrackList FINAL : public RefCountedWillBeRefCountedGarbageCollected<TextTrackList>, public ScriptWrappable, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(TextTrackList);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextTrackList);
public:
- static PassRefPtr<TextTrackList> create(HTMLMediaElement* owner)
+ static PassRefPtrWillBeRawPtr<TextTrackList> create(HTMLMediaElement* owner)
{
- return adoptRef(new TextTrackList(owner));
+ return adoptRefWillBeRefCountedGarbageCollected(new TextTrackList(owner));
}
- ~TextTrackList();
+ virtual ~TextTrackList();
unsigned length() const;
int getTrackIndex(TextTrack*);
@@ -57,7 +58,7 @@ public:
TextTrack* item(unsigned index);
TextTrack* getTrackById(const AtomicString& id);
- void append(PassRefPtr<TextTrack>);
+ void append(PassRefPtrWillBeRawPtr<TextTrack>);
void remove(TextTrack*);
// EventTarget
@@ -68,28 +69,33 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
- void clearOwner() { m_owner = 0; }
- Node* owner() const;
+#if !ENABLE(OILPAN)
+ void clearOwner();
+#endif
+ HTMLMediaElement* owner() const;
void scheduleChangeEvent();
+ void removeAllInbandTracks();
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit TextTrackList(HTMLMediaElement*);
- void scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TextTrack>);
+ void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<TextTrack>);
- void scheduleAddTrackEvent(PassRefPtr<TextTrack>);
- void scheduleRemoveTrackEvent(PassRefPtr<TextTrack>);
+ void scheduleAddTrackEvent(PassRefPtrWillBeRawPtr<TextTrack>);
+ void scheduleRemoveTrackEvent(PassRefPtrWillBeRawPtr<TextTrack>);
void invalidateTrackIndexesAfterTrack(TextTrack*);
- HTMLMediaElement* m_owner;
+ RawPtrWillBeMember<HTMLMediaElement> m_owner;
- OwnPtr<GenericEventQueue> m_asyncEventQueue;
+ OwnPtrWillBeMember<GenericEventQueue> m_asyncEventQueue;
- Vector<RefPtr<TextTrack> > m_addTrackTracks;
- Vector<RefPtr<TextTrack> > m_elementTracks;
- Vector<RefPtr<TextTrack> > m_inbandTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_addTrackTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_elementTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_inbandTracks;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl
index bbcd2d96499..8fbc775a993 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl
@@ -24,15 +24,13 @@
*/
[
- GenerateVisitDOMWrapper=owner,
- RuntimeEnabled=VideoTrack,
+ SetWrapperReferenceFrom=owner,
] interface TextTrackList : EventTarget {
readonly attribute unsigned long length;
getter TextTrack item(unsigned long index);
- TextTrack getTrackById(DOMString id);
+ TextTrack? getTrackById(DOMString id);
attribute EventHandler onaddtrack;
attribute EventHandler onchange;
attribute EventHandler onremovetrack;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp
index 17250b38ba6..a63849b253f 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,55 +29,52 @@
*/
#include "config.h"
-#include "core/html/ime/Composition.h"
+#include "core/html/track/TrackBase.h"
-#include "core/html/ime/InputMethodContext.h"
+#include "core/html/HTMLMediaElement.h"
namespace WebCore {
-Composition::~Composition()
+static blink::WebMediaPlayer::TrackId nextTrackId()
{
+ static blink::WebMediaPlayer::TrackId next = 0;
+ return ++next;
}
-void Composition::ref()
+TrackBase::TrackBase(Type type, const AtomicString& label, const AtomicString& language, const String& id)
+ : m_trackId(nextTrackId())
+ , m_type(type)
+ , m_label(label)
+ , m_language(language)
+ , m_id(id)
+ , m_mediaElement(nullptr)
{
- m_inputMethodContext->ref();
}
-void Composition::deref()
+TrackBase::~TrackBase()
{
- m_inputMethodContext->deref();
+#if !ENABLE(OILPAN)
+ ASSERT(!m_mediaElement);
+#endif
}
-PassOwnPtr<Composition> Composition::create(InputMethodContext* context)
-{
- return adoptPtr(new Composition(context));
-}
-
-Composition::Composition(InputMethodContext* context)
- : m_inputMethodContext(context)
-{
- ScriptWrappable::init(this);
-}
-
-String Composition::text() const
-{
- return m_inputMethodContext->compositionText();
-}
-int Composition::selectionStart() const
+Node* TrackBase::owner() const
{
- return m_inputMethodContext->selectionStart();
+ return m_mediaElement;
}
-int Composition::selectionEnd() const
+void TrackBase::trace(Visitor* visitor)
{
- return m_inputMethodContext->selectionEnd();
+ visitor->trace(m_mediaElement);
}
-const Vector<unsigned>& Composition::getSegments() const
+void TrackBase::setKind(const AtomicString& kind)
{
- return m_inputMethodContext->segments();
+ if (isValidKind(kind))
+ m_kind = kind;
+ else
+ m_kind = defaultKind();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h
index 38ead6489f0..cff2b8a6562 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h
@@ -26,24 +26,56 @@
#ifndef TrackBase_h
#define TrackBase_h
-#include "core/events/EventTarget.h"
+#include "platform/heap/Handle.h"
+#include "public/platform/WebMediaPlayer.h"
#include "wtf/RefCounted.h"
+#include "wtf/text/AtomicString.h"
namespace WebCore {
-class TrackBase : public RefCounted<TrackBase>, public EventTargetWithInlineData {
- REFCOUNTED_EVENT_TARGET(TrackBase);
+class HTMLMediaElement;
+
+class TrackBase : public RefCountedWillBeRefCountedGarbageCollected<TrackBase> {
public:
- virtual ~TrackBase() { }
+ virtual ~TrackBase();
+
+ blink::WebMediaPlayer::TrackId trackId() const { return m_trackId; }
enum Type { TextTrack, AudioTrack, VideoTrack };
Type type() const { return m_type; }
+ const AtomicString& kind() const { return m_kind; }
+ virtual void setKind(const AtomicString&);
+
+ AtomicString label() const { return m_label; }
+ void setLabel(const AtomicString& label) { m_label = label; }
+
+ AtomicString language() const { return m_language; }
+ void setLanguage(const AtomicString& language) { m_language = language; }
+
+ String id() const { return m_id; }
+ void setId(const String& id) { m_id = id; }
+
+ void setMediaElement(HTMLMediaElement* mediaElement) { m_mediaElement = mediaElement; }
+ HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+ Node* owner() const;
+
+ virtual void trace(Visitor*);
+
protected:
- explicit TrackBase(Type type) : m_type(type) { }
+ TrackBase(Type, const AtomicString& label, const AtomicString& language, const String& id);
+
+ virtual bool isValidKind(const AtomicString&) const = 0;
+ virtual AtomicString defaultKind() const = 0;
private:
+ blink::WebMediaPlayer::TrackId m_trackId;
Type m_type;
+ AtomicString m_kind;
+ AtomicString m_label;
+ AtomicString m_language;
+ String m_id;
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp
index 39d70bd1961..12d9263eb33 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp
@@ -27,8 +27,6 @@
#include "core/html/track/TrackEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
TrackEventInit::TrackEventInit()
@@ -57,5 +55,11 @@ const AtomicString& TrackEvent::interfaceName() const
return EventNames::TrackEvent;
}
+void TrackEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_track);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h
index 606bc1488cc..b77be6b7998 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h
@@ -34,32 +34,34 @@ namespace WebCore {
struct TrackEventInit : public EventInit {
TrackEventInit();
- RefPtr<TrackBase> track;
+ RefPtrWillBeMember<TrackBase> track;
};
-class TrackEvent : public Event {
+class TrackEvent FINAL : public Event {
public:
virtual ~TrackEvent();
- static PassRefPtr<TrackEvent> create()
+ static PassRefPtrWillBeRawPtr<TrackEvent> create()
{
- return adoptRef(new TrackEvent);
+ return adoptRefWillBeNoop(new TrackEvent);
}
- static PassRefPtr<TrackEvent> create(const AtomicString& type, const TrackEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<TrackEvent> create(const AtomicString& type, const TrackEventInit& initializer)
{
- return adoptRef(new TrackEvent(type, initializer));
+ return adoptRefWillBeNoop(new TrackEvent(type, initializer));
}
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
TrackBase* track() const { return m_track.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
TrackEvent();
TrackEvent(const AtomicString& type, const TrackEventInit& initializer);
- RefPtr<TrackBase> m_track;
+ RefPtrWillBeMember<TrackBase> m_track;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl
index eed92389f38..38ad03dcdd8 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl
@@ -24,9 +24,7 @@
*/
[
- RuntimeEnabled=VideoTrack,
EventConstructor,
] interface TrackEvent : Event {
[InitializedByEventConstructor, Custom=Getter] readonly attribute object track;
-};
-
+}; \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h b/chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h
new file mode 100644
index 00000000000..24405a482d7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h
@@ -0,0 +1,139 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TrackListBase_h
+#define TrackListBase_h
+
+#include "core/events/EventTarget.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/track/TrackEvent.h"
+
+namespace WebCore {
+
+template<class T>
+class TrackListBase : public RefCountedWillBeRefCountedGarbageCollected<TrackListBase<T> >, public EventTargetWithInlineData {
+ REFCOUNTED_EVENT_TARGET(TrackListBase);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TrackListBase);
+public:
+ explicit TrackListBase(HTMLMediaElement* mediaElement)
+ : m_mediaElement(mediaElement)
+ {
+ }
+
+ virtual ~TrackListBase()
+ {
+#if !ENABLE(OILPAN)
+ ASSERT(m_tracks.isEmpty());
+ ASSERT(!m_mediaElement);
+#endif
+ }
+
+ unsigned length() const { return m_tracks.size(); }
+ T* anonymousIndexedGetter(unsigned index) const
+ {
+ if (index >= m_tracks.size())
+ return 0;
+ return m_tracks[index].get();
+ }
+
+ T* getTrackById(const String& id) const
+ {
+ for (unsigned i = 0; i < m_tracks.size(); ++i) {
+ if (m_tracks[i]->id() == id)
+ return m_tracks[i].get();
+ }
+
+ return 0;
+ }
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
+
+ // EventTarget interface
+ virtual ExecutionContext* executionContext() const OVERRIDE
+ {
+ if (m_mediaElement)
+ return m_mediaElement->executionContext();
+ return 0;
+ }
+
+#if !ENABLE(OILPAN)
+ void shutdown()
+ {
+ removeAll();
+ m_mediaElement = nullptr;
+ }
+#endif
+
+ void add(PassRefPtrWillBeRawPtr<T> prpTrack)
+ {
+ RefPtrWillBeRawPtr<T> track = prpTrack;
+
+ track->setMediaElement(m_mediaElement);
+ m_tracks.append(track);
+ scheduleTrackEvent(EventTypeNames::addtrack, track.release());
+ }
+
+ void remove(blink::WebMediaPlayer::TrackId trackId)
+ {
+ for (unsigned i = 0; i < m_tracks.size(); ++i) {
+ if (m_tracks[i]->trackId() != trackId)
+ continue;
+
+ m_tracks[i]->setMediaElement(0);
+ scheduleTrackEvent(EventTypeNames::removetrack, m_tracks[i]);
+ m_tracks.remove(i);
+ return;
+ }
+ ASSERT_NOT_REACHED();
+ }
+
+ void removeAll()
+ {
+ for (unsigned i = 0; i < m_tracks.size(); ++i)
+ m_tracks[i]->setMediaElement(0);
+
+ m_tracks.clear();
+ }
+
+ void scheduleChangeEvent()
+ {
+ EventInit initializer;
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::change, initializer);
+ event->setTarget(this);
+ m_mediaElement->scheduleEvent(event);
+ }
+
+ Node* owner() const { return m_mediaElement; }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_tracks);
+ visitor->trace(m_mediaElement);
+ EventTargetWithInlineData::trace(visitor);
+ }
+
+private:
+ void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<T> track)
+ {
+ TrackEventInit initializer;
+ initializer.track = track;
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+ RefPtrWillBeRawPtr<Event> event = TrackEvent::create(eventName, initializer);
+ event->setTarget(this);
+ m_mediaElement->scheduleEvent(event);
+ }
+
+ WillBeHeapVector<RefPtrWillBeMember<T> > m_tracks;
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp
new file mode 100644
index 00000000000..5a93e6ed0f7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/VideoTrack.h"
+
+#include "core/html/HTMLMediaElement.h"
+
+namespace WebCore {
+
+VideoTrack::VideoTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool selected)
+ : TrackBase(TrackBase::VideoTrack, label, language, id)
+ , m_selected(selected)
+{
+ ScriptWrappable::init(this);
+ setKind(kind);
+}
+
+VideoTrack::~VideoTrack()
+{
+}
+
+void VideoTrack::setSelected(bool selected)
+{
+ if (selected == m_selected)
+ return;
+
+ m_selected = selected;
+
+ if (mediaElement()) {
+ blink::WebMediaPlayer::TrackId selectedTrackId = trackId();
+ mediaElement()->selectedVideoTrackChanged(selected ? &selectedTrackId : 0);
+ }
+}
+
+const AtomicString& VideoTrack::alternativeKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("alternative", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::captionsKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("captions", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::mainKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("main", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::signKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("sign", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::subtitlesKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("subtitles", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::commentaryKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("commentary", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+bool VideoTrack::isValidKind(const AtomicString& kind) const
+{
+ return (kind == alternativeKeyword())
+ || (kind == captionsKeyword())
+ || (kind == mainKeyword())
+ || (kind == signKeyword())
+ || (kind == subtitlesKeyword())
+ || (kind == commentaryKeyword());
+}
+
+AtomicString VideoTrack::defaultKind() const
+{
+ return emptyAtom;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h
new file mode 100644
index 00000000000..8e405e4f2ab
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h
@@ -0,0 +1,48 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VideoTrack_h
+#define VideoTrack_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/TrackBase.h"
+
+namespace WebCore {
+
+class VideoTrack FINAL : public TrackBase, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<VideoTrack> create(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool selected)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new VideoTrack(id, kind, label, language, selected));
+ }
+ virtual ~VideoTrack();
+
+ bool selected() const { return m_selected; }
+ void setSelected(bool);
+
+ // Set selected to false without notifying the owner media element. Used when
+ // another video track is selected, implicitly deselecting this one.
+ void clearSelected() { m_selected = false; }
+
+ // Valid kind keywords.
+ static const AtomicString& alternativeKeyword();
+ static const AtomicString& captionsKeyword();
+ static const AtomicString& mainKeyword();
+ static const AtomicString& signKeyword();
+ static const AtomicString& subtitlesKeyword();
+ static const AtomicString& commentaryKeyword();
+
+private:
+ VideoTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool selected);
+
+ // TrackBase
+ virtual bool isValidKind(const AtomicString&) const OVERRIDE;
+ virtual AtomicString defaultKind() const OVERRIDE;
+
+ bool m_selected;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl
new file mode 100644
index 00000000000..cc4efee29da
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl
@@ -0,0 +1,15 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+ WillBeGarbageCollected,
+] interface VideoTrack {
+ readonly attribute DOMString id;
+ readonly attribute DOMString kind;
+ readonly attribute DOMString label;
+ readonly attribute DOMString language;
+ attribute boolean selected;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp
new file mode 100644
index 00000000000..e107717dfa4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp
@@ -0,0 +1,60 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/VideoTrackList.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/track/VideoTrack.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<VideoTrackList> VideoTrackList::create(HTMLMediaElement& mediaElement)
+{
+ return adoptRefWillBeRefCountedGarbageCollected(new VideoTrackList(mediaElement));
+}
+
+VideoTrackList::~VideoTrackList()
+{
+}
+
+VideoTrackList::VideoTrackList(HTMLMediaElement& mediaElement)
+ : TrackListBase<VideoTrack>(&mediaElement)
+{
+ ScriptWrappable::init(this);
+}
+
+const AtomicString& VideoTrackList::interfaceName() const
+{
+ return EventTargetNames::VideoTrackList;
+}
+
+int VideoTrackList::selectedIndex() const
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ VideoTrack* track = anonymousIndexedGetter(i);
+
+ if (track->selected())
+ return i;
+ }
+
+ return -1;
+}
+
+void VideoTrackList::trackSelected(blink::WebMediaPlayer::TrackId selectedTrackId)
+{
+ // Clear the selected flag on the previously selected track, if any.
+ for (unsigned i = 0; i < length(); ++i) {
+ VideoTrack* track = anonymousIndexedGetter(i);
+
+ if (track->trackId() != selectedTrackId)
+ track->clearSelected();
+ else
+ ASSERT(track->selected());
+ }
+
+ scheduleChangeEvent();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h
new file mode 100644
index 00000000000..5e60b3171cb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VideoTrackList_h
+#define VideoTrackList_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/TrackListBase.h"
+#include "core/html/track/VideoTrack.h"
+
+namespace WebCore {
+
+class VideoTrackList FINAL : public TrackListBase<VideoTrack>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<VideoTrackList> create(HTMLMediaElement&);
+
+ virtual ~VideoTrackList();
+
+ int selectedIndex() const;
+
+ // EventTarget
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ void trackSelected(blink::WebMediaPlayer::TrackId selectedTrackId);
+
+private:
+ explicit VideoTrackList(HTMLMediaElement&);
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl
new file mode 100644
index 00000000000..f7663350649
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl
@@ -0,0 +1,17 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+] interface VideoTrackList : EventTarget {
+ readonly attribute unsigned long length;
+ getter VideoTrack (unsigned long index);
+ VideoTrack? getTrackById(DOMString id);
+ readonly attribute long selectedIndex;
+
+ attribute EventHandler onchange;
+ attribute EventHandler onaddtrack;
+ attribute EventHandler onremovetrack;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp
index 3a4aab74416..2c024bb3d9c 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "BufferedLineReader.h"
+#include "core/html/track/vtt/BufferedLineReader.h"
#include "wtf/unicode/CharacterNames.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp
index ab185dc3d67..8069c26ad2f 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp
@@ -30,21 +30,23 @@
#include "config.h"
#include "core/html/track/vtt/VTTCue.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/NodeTraversal.h"
#include "core/events/Event.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/vtt/VTTElement.h"
#include "core/html/track/vtt/VTTParser.h"
#include "core/html/track/vtt/VTTRegionList.h"
+#include "core/html/track/vtt/VTTScanner.h"
#include "core/rendering/RenderVTTCue.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/BidiResolver.h"
#include "platform/text/TextRunIterator.h"
#include "wtf/MathExtras.h"
@@ -53,6 +55,7 @@
namespace WebCore {
static const int undefinedPosition = -1;
+static const int undefinedSize = -1;
static const CSSValueID displayWritingModeMap[] = {
CSSValueHorizontalTb, CSSValueVerticalRl, CSSValueVerticalLr
@@ -113,12 +116,10 @@ static const String& verticalGrowingRightKeyword()
return verticallr;
}
-static bool isInvalidPercentage(double value, ExceptionState& exceptionState)
+static bool isInvalidPercentage(int value, ExceptionState& exceptionState)
{
- if (TextTrackCue::isInfiniteOrNonNumber(value, exceptionState))
- return true;
if (value < 0 || value > 100) {
- exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0, ExceptionMessages::InclusiveBound, 100, ExceptionMessages::InclusiveBound));
return true;
}
return false;
@@ -128,7 +129,7 @@ VTTCueBox::VTTCueBox(Document& document, VTTCue* cue)
: HTMLDivElement(document)
, m_cue(cue)
{
- setPseudo(AtomicString("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
+ setShadowPseudoId(AtomicString("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
}
void VTTCueBox::applyCSSProperties(const IntSize&)
@@ -199,6 +200,12 @@ RenderObject* VTTCueBox::createRenderer(RenderStyle*)
return new RenderVTTCue(this);
}
+void VTTCueBox::trace(Visitor* visitor)
+{
+ visitor->trace(m_cue);
+ HTMLDivElement::trace(visitor);
+}
+
VTTCue::VTTCue(Document& document, double startTime, double endTime, const String& text)
: TextTrackCue(startTime, endTime)
, m_text(text)
@@ -208,19 +215,29 @@ VTTCue::VTTCue(Document& document, double startTime, double endTime, const Strin
, m_cueSize(100)
, m_writingDirection(Horizontal)
, m_cueAlignment(Middle)
- , m_vttNodeTree(0)
+ , m_vttNodeTree(nullptr)
, m_cueBackgroundBox(HTMLDivElement::create(document))
, m_displayDirection(CSSValueLtr)
+ , m_displaySize(undefinedSize)
, m_snapToLines(true)
, m_displayTreeShouldChange(true)
, m_notifyRegion(true)
{
ScriptWrappable::init(this);
+ UseCounter::count(document, UseCounter::VTTCue);
}
VTTCue::~VTTCue()
{
- displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+ // Using oilpan, if m_displayTree is in the document it will strongly keep
+ // the cue alive. Thus, if the cue is dead, either m_displayTree is not in
+ // the document or the entire document is dead too.
+#if !ENABLE(OILPAN)
+ // FIXME: This is scary, we should make the life cycle smarter so the destructor
+ // doesn't need to do DOM mutations.
+ if (m_displayTree)
+ m_displayTree->remove(ASSERT_NO_EXCEPTION);
+#endif
}
#ifndef NDEBUG
@@ -230,11 +247,11 @@ String VTTCue::toString() const
}
#endif
-PassRefPtr<VTTCueBox> VTTCue::displayTreeInternal()
+VTTCueBox& VTTCue::ensureDisplayTree()
{
if (!m_displayTree)
m_displayTree = VTTCueBox::create(document(), this);
- return m_displayTree;
+ return *m_displayTree;
}
void VTTCue::cueDidChange()
@@ -258,14 +275,8 @@ const String& VTTCue::vertical() const
}
}
-void VTTCue::setVertical(const String& value, ExceptionState& exceptionState)
+void VTTCue::setVertical(const String& value)
{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-vertical
- // On setting, the text track cue writing direction must be set to the value given
- // in the first cell of the row in the table above whose second cell is a
- // case-sensitive match for the new value, if any. If none of the values match, then
- // the user agent must instead throw a SyntaxError exception.
-
WritingDirection direction = m_writingDirection;
if (value == horizontalKeyword())
direction = Horizontal;
@@ -274,7 +285,7 @@ void VTTCue::setVertical(const String& value, ExceptionState& exceptionState)
else if (value == verticalGrowingRightKeyword())
direction = VerticalGrowingRight;
else
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("vertical", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'rl', 'lr', and the empty string are accepted."));
+ ASSERT_NOT_REACHED();
if (direction == m_writingDirection)
return;
@@ -300,7 +311,7 @@ void VTTCue::setLine(int position, ExceptionState& exceptionState)
// On setting, if the text track cue snap-to-lines flag is not set, and the new
// value is negative or greater than 100, then throw an IndexSizeError exception.
if (!m_snapToLines && (position < 0 || position > 100)) {
- exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("line", "TextTrackCue", "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100."));
+ exceptionState.throwDOMException(IndexSizeError, "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100.");
return;
}
@@ -367,14 +378,8 @@ const String& VTTCue::align() const
}
}
-void VTTCue::setAlign(const String& value, ExceptionState& exceptionState)
+void VTTCue::setAlign(const String& value)
{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-align
- // On setting, the text track cue alignment must be set to the value given in the
- // first cell of the row in the table above whose second cell is a case-sensitive
- // match for the new value, if any. If none of the values match, then the user
- // agent must instead throw a SyntaxError exception.
-
CueAlignment alignment = m_cueAlignment;
if (value == startKeyword())
alignment = Start;
@@ -387,7 +392,7 @@ void VTTCue::setAlign(const String& value, ExceptionState& exceptionState)
else if (value == rightKeyword())
alignment = Right;
else
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("align", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'start', 'middle', 'end', 'left', and 'right' are accepted."));
+ ASSERT_NOT_REACHED();
if (alignment == m_cueAlignment)
return;
@@ -405,7 +410,7 @@ void VTTCue::setText(const String& text)
cueWillChange();
// Clear the document fragment but don't bother to create it again just yet as we can do that
// when it is requested.
- m_vttNodeTree = 0;
+ m_vttNodeTree = nullptr;
m_text = text;
cueDidChange();
}
@@ -419,7 +424,7 @@ void VTTCue::createVTTNodeTree()
void VTTCue::copyVTTNodeToDOMTree(ContainerNode* vttNode, ContainerNode* parent)
{
for (Node* node = vttNode->firstChild(); node; node = node->nextSibling()) {
- RefPtr<Node> clonedNode;
+ RefPtrWillBeRawPtr<Node> clonedNode;
if (node->isVTTElement())
clonedNode = toVTTElement(node)->createEquivalentHTMLElement(document());
else
@@ -430,19 +435,18 @@ void VTTCue::copyVTTNodeToDOMTree(ContainerNode* vttNode, ContainerNode* parent)
}
}
-PassRefPtr<DocumentFragment> VTTCue::getCueAsHTML()
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTCue::getCueAsHTML()
{
createVTTNodeTree();
- RefPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
+ RefPtrWillBeRawPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
copyVTTNodeToDOMTree(m_vttNodeTree.get(), clonedFragment.get());
return clonedFragment.release();
}
-PassRefPtr<DocumentFragment> VTTCue::createCueRenderingTree()
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTCue::createCueRenderingTree()
{
- RefPtr<DocumentFragment> clonedFragment;
createVTTNodeTree();
- clonedFragment = DocumentFragment::create(document());
+ RefPtrWillBeRawPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
m_vttNodeTree->cloneChildNodes(clonedFragment.get());
return clonedFragment.release();
}
@@ -550,6 +554,9 @@ void VTTCue::calculateDisplayParameters()
// Steps 10.2, 10.3
m_displayDirection = determineTextDirection(m_vttNodeTree.get());
+ if (m_displayDirection == CSSValueRtl)
+ UseCounter::count(document(), UseCounter::VTTCueRenderRtl);
+
// 10.4 If the text track cue writing direction is horizontal, then let
// block-flow be 'tb'. Otherwise, if the text track cue writing direction is
// vertical growing left, then let block-flow be 'lr'. Otherwise, the text
@@ -621,7 +628,7 @@ void VTTCue::calculateDisplayParameters()
else
m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2;
break;
- case NumberOfAlignments:
+ default:
ASSERT_NOT_REACHED();
}
} else {
@@ -638,7 +645,7 @@ void VTTCue::calculateDisplayParameters()
case Middle:
m_displayPosition.second = m_textPosition - m_displaySize / 2;
break;
- case NumberOfAlignments:
+ default:
ASSERT_NOT_REACHED();
}
}
@@ -675,10 +682,8 @@ void VTTCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestam
for (Node* child = root->firstChild(); child; child = NodeTraversal::next(*child, root)) {
if (child->nodeName() == timestampTag) {
- unsigned position = 0;
- String timestamp = child->nodeValue();
double currentTimestamp;
- bool check = VTTParser::collectTimeStamp(timestamp, &position, currentTimestamp);
+ bool check = VTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp);
ASSERT_UNUSED(check, check);
if (currentTimestamp > movieTime)
@@ -706,16 +711,16 @@ void VTTCue::updateDisplayTree(double movieTime)
m_cueBackgroundBox->removeChildren();
// Update the two sets containing past and future WebVTT objects.
- RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
+ RefPtrWillBeRawPtr<DocumentFragment> referenceTree = createCueRenderingTree();
markFutureAndPastNodes(referenceTree.get(), startTime(), movieTime);
m_cueBackgroundBox->appendChild(referenceTree, ASSERT_NO_EXCEPTION);
}
-PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
+PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
{
- RefPtr<VTTCueBox> displayTree = displayTreeInternal();
+ RefPtrWillBeRawPtr<VTTCueBox> displayTree(ensureDisplayTree());
if (!m_displayTreeShouldChange || !track()->isRendered())
- return displayTree;
+ return displayTree.release();
// 10.1 - 10.10
calculateDisplayParameters();
@@ -732,7 +737,7 @@ PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
// background box.
// Note: This is contained by default in m_cueBackgroundBox.
- m_cueBackgroundBox->setPseudo(cueShadowPseudoId());
+ m_cueBackgroundBox->setShadowPseudoId(cueShadowPseudoId());
displayTree->appendChild(m_cueBackgroundBox);
// FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not
@@ -752,7 +757,7 @@ PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
// 10.15. Let cue's text track cue display state have the CSS boxes in
// boxes.
- return displayTree;
+ return displayTree.release();
}
void VTTCue::removeDisplayTree()
@@ -764,12 +769,33 @@ void VTTCue::removeDisplayTree()
region->willRemoveVTTCueBox(m_displayTree.get());
}
- displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+ if (m_displayTree)
+ m_displayTree->remove(ASSERT_NO_EXCEPTION);
}
void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container)
{
- RefPtr<VTTCueBox> displayBox = getDisplayTree(videoSize);
+ UseCounter::count(document(), UseCounter::VTTCueRender);
+
+ if (m_writingDirection != Horizontal)
+ UseCounter::count(document(), UseCounter::VTTCueRenderVertical);
+
+ if (!m_snapToLines)
+ UseCounter::count(document(), UseCounter::VTTCueRenderSnapToLinesFalse);
+
+ if (m_linePosition != undefinedPosition)
+ UseCounter::count(document(), UseCounter::VTTCueRenderLineNotAuto);
+
+ if (m_textPosition != 50)
+ UseCounter::count(document(), UseCounter::VTTCueRenderPositionNot50);
+
+ if (m_cueSize != 100)
+ UseCounter::count(document(), UseCounter::VTTCueRenderSizeNot100);
+
+ if (m_cueAlignment != Middle)
+ UseCounter::count(document(), UseCounter::VTTCueRenderAlignNotMiddle);
+
+ RefPtrWillBeRawPtr<VTTCueBox> displayBox = getDisplayTree(videoSize);
VTTRegion* region = 0;
if (track()->regions())
region = track()->regions()->getRegionById(regionId());
@@ -778,14 +804,14 @@ void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container)
// If cue has an empty text track cue region identifier or there is no
// WebVTT region whose region identifier is identical to cue's text
// track cue region identifier, run the following substeps:
- if (displayBox->hasChildNodes() && !container.contains(displayBox.get())) {
+ if (displayBox->hasChildren() && !container.contains(displayBox.get())) {
// Note: the display tree of a cue is removed when the active flag of the cue is unset.
container.appendChild(displayBox);
}
} else {
// Let region be the WebVTT region whose region identifier
// matches the text track cue region identifier of cue.
- RefPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
+ RefPtrWillBeRawPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
// Append the region to the viewport, if it was not already.
if (!container.contains(regionNode.get()))
@@ -833,42 +859,65 @@ std::pair<double, double> VTTCue::getPositionCoordinates() const
return coordinates;
}
-VTTCue::CueSetting VTTCue::settingName(const String& name)
+VTTCue::CueSetting VTTCue::settingName(VTTScanner& input)
{
- DEFINE_STATIC_LOCAL(const String, verticalKeyword, ("vertical"));
- DEFINE_STATIC_LOCAL(const String, lineKeyword, ("line"));
- DEFINE_STATIC_LOCAL(const String, positionKeyword, ("position"));
- DEFINE_STATIC_LOCAL(const String, sizeKeyword, ("size"));
- DEFINE_STATIC_LOCAL(const String, alignKeyword, ("align"));
- DEFINE_STATIC_LOCAL(const String, regionIdKeyword, ("region"));
-
- if (name == verticalKeyword)
- return Vertical;
- if (name == lineKeyword)
- return Line;
- if (name == positionKeyword)
- return Position;
- if (name == sizeKeyword)
- return Size;
- if (name == alignKeyword)
- return Align;
- if (RuntimeEnabledFeatures::webVTTRegionsEnabled() && name == regionIdKeyword)
- return RegionId;
-
+ CueSetting parsedSetting = None;
+ if (input.scan("vertical"))
+ parsedSetting = Vertical;
+ else if (input.scan("line"))
+ parsedSetting = Line;
+ else if (input.scan("position"))
+ parsedSetting = Position;
+ else if (input.scan("size"))
+ parsedSetting = Size;
+ else if (input.scan("align"))
+ parsedSetting = Align;
+ else if (RuntimeEnabledFeatures::webVTTRegionsEnabled() && input.scan("region"))
+ parsedSetting = RegionId;
+ // Verify that a ':' follows.
+ if (parsedSetting != None && input.scan(':'))
+ return parsedSetting;
return None;
}
-void VTTCue::parseSettings(const String& input)
+// Used for 'position' and 'size'.
+static bool scanPercentage(VTTScanner& input, const VTTScanner::Run& valueRun, int& number)
{
- unsigned position = 0;
+ // 1. If value contains any characters other than U+0025 PERCENT SIGN
+ // characters (%) and characters in the range U+0030 DIGIT ZERO (0) to
+ // U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
+ // 2. If value does not contain at least one character in the range U+0030
+ // DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step
+ // labeled next setting.
+ if (!input.scanDigits(number))
+ return false;
+
+ // 3. If any character in value other than the last character is a U+0025
+ // PERCENT SIGN character (%), then jump to the step labeled next
+ // setting.
+ // 4. If the last character in value is not a U+0025 PERCENT SIGN character
+ // (%), then jump to the step labeled next setting.
+ if (!input.scan('%') || !input.isAt(valueRun.end()))
+ return false;
+
+ // 5. Ignoring the trailing percent sign, interpret value as an integer,
+ // and let number be that number.
+ // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step
+ // labeled next setting.
+ return number >= 0 && number <= 100;
+}
+
+void VTTCue::parseSettings(const String& inputString)
+{
+ VTTScanner input(inputString);
- while (position < input.length()) {
+ while (!input.isAtEnd()) {
// The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order,
// separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
- while (position < input.length() && VTTParser::isValidSettingDelimiter(input[position]))
- position++;
- if (position >= input.length())
+ input.skipWhile<VTTParser::isValidSettingDelimiter>();
+
+ if (input.isAtEnd())
break;
// When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue,
@@ -877,48 +926,38 @@ void VTTCue::parseSettings(const String& input)
// 2. For each token setting in the list settings, run the following substeps:
// 1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:)
// in setting is either the first or last character of setting, then jump to the step labeled next setting.
- unsigned endOfSetting = position;
- String setting = VTTParser::collectWord(input, &endOfSetting);
- CueSetting name;
- size_t colonOffset = setting.find(':', 1);
- if (colonOffset == kNotFound || !colonOffset || colonOffset == setting.length() - 1)
- goto NextSetting;
-
- // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
- name = settingName(setting.substring(0, colonOffset));
+ // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
+ CueSetting name = settingName(input);
// 3. Let value be the trailing substring of setting starting from the character immediately after the first U+003A COLON character (:) in that string.
- position += colonOffset + 1;
- if (position >= input.length())
- break;
+ VTTScanner::Run valueRun = input.collectUntil<VTTParser::isValidSettingDelimiter>();
// 4. Run the appropriate substeps that apply for the value of name, as follows:
switch (name) {
- case Vertical:
- {
+ case Vertical: {
// If name is a case-sensitive match for "vertical"
// 1. If value is a case-sensitive match for the string "rl", then let cue's text track cue writing direction
// be vertical growing left.
- String writingDirection = VTTParser::collectWord(input, &position);
- if (writingDirection == verticalGrowingLeftKeyword())
+ if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
m_writingDirection = VerticalGrowingLeft;
// 2. Otherwise, if value is a case-sensitive match for the string "lr", then let cue's text track cue writing
// direction be vertical growing right.
- else if (writingDirection == verticalGrowingRightKeyword())
+ else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
m_writingDirection = VerticalGrowingRight;
- }
break;
- case Line:
- {
+ }
+ case Line: {
// 1-2 - Collect chars that are either '-', '%', or a digit.
// 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN
// characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
// to the step labeled next setting.
- StringBuilder linePositionBuilder;
- while (position < input.length() && (input[position] == '-' || input[position] == '%' || isASCIIDigit(input[position])))
- linePositionBuilder.append(input[position++]);
- if (position < input.length() && !VTTParser::isValidSettingDelimiter(input[position]))
+ bool isNegative = input.scan('-');
+ int linePosition;
+ unsigned numDigits = input.scanDigits(linePosition);
+ bool isPercentage = input.scan('%');
+
+ if (!input.isAt(valueRun.end()))
break;
// 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
@@ -927,134 +966,83 @@ void VTTCue::parseSettings(const String& input)
// jump to the step labeled next setting.
// 4. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then
// jump to the step labeled next setting.
- String linePosition = linePositionBuilder.toString();
- if (linePosition.find('-', 1) != kNotFound || linePosition.reverseFind("%", linePosition.length() - 2) != kNotFound)
- break;
// 5. If the first character in value is a U+002D HYPHEN-MINUS character (-) and the last character in value is a
// U+0025 PERCENT SIGN character (%), then jump to the step labeled next setting.
- if (linePosition[0] == '-' && linePosition[linePosition.length() - 1] == '%')
+ if (!numDigits || (isPercentage && isNegative))
break;
// 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and
// let number be that number.
- // NOTE: toInt ignores trailing non-digit characters, such as '%'.
- bool validNumber;
- int number = linePosition.toInt(&validNumber);
- if (!validNumber)
- break;
-
// 7. If the last character in value is a U+0025 PERCENT SIGN character (%), but number is not in the range
// 0 ≤ number ≤ 100, then jump to the step labeled next setting.
// 8. Let cue's text track cue line position be number.
// 9. If the last character in value is a U+0025 PERCENT SIGN character (%), then let cue's text track cue
// snap-to-lines flag be false. Otherwise, let it be true.
- if (linePosition[linePosition.length() - 1] == '%') {
- if (number < 0 || number > 100)
+ if (isPercentage) {
+ if (linePosition < 0 || linePosition > 100)
break;
-
// 10 - If '%' then set snap-to-lines flag to false.
m_snapToLines = false;
+ } else {
+ if (isNegative)
+ linePosition = -linePosition;
+ m_snapToLines = true;
}
-
- m_linePosition = number;
- }
+ m_linePosition = linePosition;
break;
- case Position:
- {
- // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the range
- // U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
- // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
- // then jump to the step labeled next setting.
+ }
+ case Position: {
int number;
- if (!VTTParser::collectDigitsToInt(input, &position, number))
- break;
- if (position >= input.length())
- break;
-
- // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then jump
- // to the step labeled next setting.
- // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step labeled
- // next setting.
- if (input[position++] != '%')
- break;
- if (position < input.length() && !VTTParser::isValidSettingDelimiter(input[position]))
- break;
-
- // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
- // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
- // NOTE: toInt ignores trailing non-digit characters, such as '%'.
- if (number < 0 || number > 100)
+ // Steps 1 - 6.
+ if (!scanPercentage(input, valueRun, number))
break;
// 7. Let cue's text track cue text position be number.
m_textPosition = number;
- }
break;
- case Size:
- {
- // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the
- // range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
- // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
- // NINE (9), then jump to the step labeled next setting.
+ }
+ case Size: {
int number;
- if (!VTTParser::collectDigitsToInt(input, &position, number))
- break;
- if (position >= input.length())
- break;
-
- // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%),
- // then jump to the step labeled next setting.
- // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step
- // labeled next setting.
- if (input[position++] != '%')
- break;
- if (position < input.length() && !VTTParser::isValidSettingDelimiter(input[position]))
- break;
-
- // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
- // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
- if (number < 0 || number > 100)
+ // Steps 1 - 6.
+ if (!scanPercentage(input, valueRun, number))
break;
// 7. Let cue's text track cue size be number.
m_cueSize = number;
- }
break;
- case Align:
- {
- String cueAlignment = VTTParser::collectWord(input, &position);
-
+ }
+ case Align: {
// 1. If value is a case-sensitive match for the string "start", then let cue's text track cue alignment be start alignment.
- if (cueAlignment == startKeyword())
+ if (input.scanRun(valueRun, startKeyword()))
m_cueAlignment = Start;
// 2. If value is a case-sensitive match for the string "middle", then let cue's text track cue alignment be middle alignment.
- else if (cueAlignment == middleKeyword())
+ else if (input.scanRun(valueRun, middleKeyword()))
m_cueAlignment = Middle;
// 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment.
- else if (cueAlignment == endKeyword())
+ else if (input.scanRun(valueRun, endKeyword()))
m_cueAlignment = End;
// 4. If value is a case-sensitive match for the string "left", then let cue's text track cue alignment be left alignment.
- else if (cueAlignment == leftKeyword())
+ else if (input.scanRun(valueRun, leftKeyword()))
m_cueAlignment = Left;
// 5. If value is a case-sensitive match for the string "right", then let cue's text track cue alignment be right alignment.
- else if (cueAlignment == rightKeyword())
+ else if (input.scanRun(valueRun, rightKeyword()))
m_cueAlignment = Right;
- }
break;
+ }
case RegionId:
- m_regionId = VTTParser::collectWord(input, &position);
+ m_regionId = input.extractString(valueRun);
break;
case None:
break;
}
-NextSetting:
- position = endOfSetting;
+ // Make sure the entire run is consumed.
+ input.skipRun(valueRun);
}
// If cue's line position is not auto or cue's size is not 100 or cue's
@@ -1084,6 +1072,7 @@ CSSValueID VTTCue::getCSSWritingMode() const
int VTTCue::getCSSSize() const
{
+ ASSERT(m_displaySize != undefinedSize);
return m_displaySize;
}
@@ -1107,4 +1096,12 @@ Document& VTTCue::document() const
return m_cueBackgroundBox->document();
}
+void VTTCue::trace(Visitor* visitor)
+{
+ visitor->trace(m_vttNodeTree);
+ visitor->trace(m_cueBackgroundBox);
+ visitor->trace(m_displayTree);
+ TextTrackCue::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h
index 05e6f8ecf1b..a43112dce4b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h
@@ -32,42 +32,46 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/track/TextTrackCue.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class Document;
class ExecutionContext;
class VTTCue;
+class VTTScanner;
class VTTCueBox FINAL : public HTMLDivElement {
public:
- static PassRefPtr<VTTCueBox> create(Document& document, VTTCue* cue)
+ static PassRefPtrWillBeRawPtr<VTTCueBox> create(Document& document, VTTCue* cue)
{
- return adoptRef(new VTTCueBox(document, cue));
+ return adoptRefWillBeNoop(new VTTCueBox(document, cue));
}
VTTCue* getCue() const { return m_cue; }
void applyCSSProperties(const IntSize& videoSize);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
VTTCueBox(Document&, VTTCue*);
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- VTTCue* m_cue;
+ RawPtrWillBeMember<VTTCue> m_cue;
};
class VTTCue FINAL : public TextTrackCue, public ScriptWrappable {
public:
- static PassRefPtr<VTTCue> create(Document& document, double startTime, double endTime, const String& text)
+ static PassRefPtrWillBeRawPtr<VTTCue> create(Document& document, double startTime, double endTime, const String& text)
{
- return adoptRef(new VTTCue(document, startTime, endTime, text));
+ return adoptRefWillBeRefCountedGarbageCollected(new VTTCue(document, startTime, endTime, text));
}
virtual ~VTTCue();
const String& vertical() const;
- void setVertical(const String&, ExceptionState&);
+ void setVertical(const String&);
bool snapToLines() const { return m_snapToLines; }
void setSnapToLines(bool);
@@ -82,15 +86,15 @@ public:
void setSize(int, ExceptionState&);
const String& align() const;
- void setAlign(const String&, ExceptionState&);
+ void setAlign(const String&);
const String& text() const { return m_text; }
void setText(const String&);
void parseSettings(const String&);
- PassRefPtr<DocumentFragment> getCueAsHTML();
- PassRefPtr<DocumentFragment> createCueRenderingTree();
+ PassRefPtrWillBeRawPtr<DocumentFragment> getCueAsHTML();
+ PassRefPtrWillBeRawPtr<DocumentFragment> createCueRenderingTree();
const String& regionId() const { return m_regionId; }
void setRegionId(const String&);
@@ -136,13 +140,15 @@ public:
virtual String toString() const OVERRIDE;
#endif
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
VTTCue(Document&, double startTime, double endTime, const String& text);
Document& document() const;
- PassRefPtr<VTTCueBox> displayTreeInternal();
- PassRefPtr<VTTCueBox> getDisplayTree(const IntSize& videoSize);
+ VTTCueBox& ensureDisplayTree();
+ PassRefPtrWillBeRawPtr<VTTCueBox> getDisplayTree(const IntSize& videoSize);
virtual void cueDidChange() OVERRIDE;
@@ -162,7 +168,7 @@ private:
Align,
RegionId
};
- CueSetting settingName(const String&);
+ CueSetting settingName(VTTScanner&);
String m_text;
int m_linePosition;
@@ -173,9 +179,9 @@ private:
CueAlignment m_cueAlignment;
String m_regionId;
- RefPtr<DocumentFragment> m_vttNodeTree;
- RefPtr<HTMLDivElement> m_cueBackgroundBox;
- RefPtr<VTTCueBox> m_displayTree;
+ RefPtrWillBeMember<DocumentFragment> m_vttNodeTree;
+ RefPtrWillBeMember<HTMLDivElement> m_cueBackgroundBox;
+ RefPtrWillBeMember<VTTCueBox> m_displayTree;
CSSValueID m_displayDirection;
int m_displaySize;
@@ -186,11 +192,8 @@ private:
bool m_notifyRegion : 1;
};
-inline VTTCue* toVTTCue(TextTrackCue* cue)
-{
- // VTTCue is currently the only TextTrackCue subclass.
- return static_cast<VTTCue*>(cue);
-}
+// VTTCue is currently the only TextTrackCue subclass.
+DEFINE_TYPE_CASTS(VTTCue, TextTrackCue, cue, true, true);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl
index 8b958174353..3ca0307dfa3 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl
@@ -27,18 +27,21 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum DirectionSetting { "" /* horizontal */, "rl", "lr" };
+enum AlignSetting { "start", "middle", "end", "left", "right" };
+
[
Constructor(double startTime, double endTime, DOMString text),
ConstructorCallWith=Document,
- RuntimeEnabled=VideoTrack,
+ SetWrapperReferenceFrom=owner,
] interface VTTCue : TextTrackCue {
[RuntimeEnabled=WebVTTRegions] attribute DOMString regionId;
- [RaisesException=Setter] attribute DOMString vertical;
+ attribute DirectionSetting vertical;
attribute boolean snapToLines;
[RaisesException=Setter] attribute long line;
[RaisesException=Setter] attribute long position;
[RaisesException=Setter] attribute long size;
- [RaisesException=Setter] attribute DOMString align;
+ attribute AlignSetting align;
attribute DOMString text;
DocumentFragment getCueAsHTML();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp
index e9b350a1304..c56084ce40e 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/track/vtt/VTTElement.h"
-#include "HTMLElementFactory.h"
+#include "core/HTMLElementFactory.h"
namespace WebCore {
@@ -71,21 +71,21 @@ VTTElement::VTTElement(VTTNodeType nodeType, Document* document)
{
}
-PassRefPtr<VTTElement> VTTElement::create(VTTNodeType nodeType, Document* document)
+PassRefPtrWillBeRawPtr<VTTElement> VTTElement::create(VTTNodeType nodeType, Document* document)
{
- return adoptRef(new VTTElement(nodeType, document));
+ return adoptRefWillBeNoop(new VTTElement(nodeType, document));
}
-PassRefPtr<Element> VTTElement::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> VTTElement::cloneElementWithoutAttributesAndChildren()
{
- RefPtr<VTTElement> clone = create(static_cast<VTTNodeType>(m_webVTTNodeType), &document());
+ RefPtrWillBeRawPtr<VTTElement> clone = create(static_cast<VTTNodeType>(m_webVTTNodeType), &document());
clone->setLanguage(m_language);
- return clone;
+ return clone.release();
}
-PassRefPtr<HTMLElement> VTTElement::createEquivalentHTMLElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> VTTElement::createEquivalentHTMLElement(Document& document)
{
- RefPtr<HTMLElement> htmlElement;
+ RefPtrWillBeRawPtr<HTMLElement> htmlElement = nullptr;
switch (m_webVTTNodeType) {
case VTTNodeTypeClass:
case VTTNodeTypeLanguage:
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h
index 2fe08c79abe..6705add645b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h
@@ -41,11 +41,11 @@ enum VTTNodeType {
class VTTElement FINAL : public Element {
public:
- static PassRefPtr<VTTElement> create(const VTTNodeType, Document*);
- static PassRefPtr<VTTElement> create(const QualifiedName&, Document*);
- PassRefPtr<HTMLElement> createEquivalentHTMLElement(Document&);
+ static PassRefPtrWillBeRawPtr<VTTElement> create(const VTTNodeType, Document*);
+ static PassRefPtrWillBeRawPtr<VTTElement> create(const QualifiedName&, Document*);
+ PassRefPtrWillBeRawPtr<HTMLElement> createEquivalentHTMLElement(Document&);
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
void setVTTNodeType(VTTNodeType type) { m_webVTTNodeType = static_cast<unsigned>(type); }
VTTNodeType webVTTNodeType() const { return static_cast<VTTNodeType>(m_webVTTNodeType); }
@@ -79,7 +79,7 @@ private:
AtomicString m_language;
};
-DEFINE_NODE_TYPE_CASTS(VTTElement, isVTTElement());
+DEFINE_ELEMENT_TYPE_CASTS(VTTElement, isVTTElement());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
index e1b4b2a372d..ef09051af16 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
@@ -35,103 +35,45 @@
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/Text.h"
#include "core/html/track/vtt/VTTElement.h"
+#include "core/html/track/vtt/VTTScanner.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/SegmentedString.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+using namespace HTMLNames;
+
const double secondsPerHour = 3600;
const double secondsPerMinute = 60;
const double secondsPerMillisecond = 0.001;
const unsigned fileIdentifierLength = 6;
-static unsigned scanDigits(const String& input, unsigned* position)
-{
- unsigned startPosition = *position;
- while (*position < input.length() && isASCIIDigit(input[*position]))
- (*position)++;
- return *position - startPosition;
-}
-
-unsigned VTTParser::collectDigitsToInt(const String& input, unsigned* position, int& number)
-{
- unsigned startPosition = *position;
- unsigned numDigits = scanDigits(input, position);
- if (!numDigits) {
- number = 0;
- return 0;
- }
- bool validNumber;
- if (input.is8Bit())
- number = charactersToInt(input.characters8() + startPosition, numDigits, &validNumber);
- else
- number = charactersToInt(input.characters16() + startPosition, numDigits, &validNumber);
-
- // Since we know that scanDigits only scanned valid (ASCII) digits (and
- // hence that's what got passed to charactersToInt()), the remaining
- // failure mode for charactersToInt() is overflow, so if |validNumber| is
- // not true, then set |number| to the maximum int value.
- if (!validNumber)
- number = std::numeric_limits<int>::max();
- return numDigits;
-}
-
-String VTTParser::collectWord(const String& input, unsigned* position)
+bool VTTParser::parseFloatPercentageValue(VTTScanner& valueScanner, float& percentage)
{
- StringBuilder string;
- while (*position < input.length() && !isASpace(input[*position]))
- string.append(input[(*position)++]);
- return string.toString();
-}
-
-void VTTParser::skipWhiteSpace(const String& line, unsigned* position)
-{
- while (*position < line.length() && isASpace(line[*position]))
- (*position)++;
-}
-
-bool VTTParser::parseFloatPercentageValue(const String& value, float& percentage)
-{
- // '%' must be present and at the end of the setting value.
- if (value.isEmpty() || value[value.length() - 1] != '%')
+ float number;
+ if (!valueScanner.scanFloat(number))
return false;
-
- unsigned position = 0;
- unsigned digitsBeforeDot = scanDigits(value, &position);
- unsigned digitsAfterDot = 0;
- if (value[position] == '.') {
- position++;
-
- digitsAfterDot = scanDigits(value, &position);
- }
-
- // At least one digit required.
- if (!digitsBeforeDot && !digitsAfterDot)
+ // '%' must be present and at the end of the setting value.
+ if (!valueScanner.scan('%'))
return false;
-
- float number = value.toFloat();
if (number < 0 || number > 100)
return false;
-
percentage = number;
return true;
}
-bool VTTParser::parseFloatPercentageValuePair(const String& value, char delimiter, FloatPoint& valuePair)
+bool VTTParser::parseFloatPercentageValuePair(VTTScanner& valueScanner, char delimiter, FloatPoint& valuePair)
{
- // The delimiter can't be the first or second value because a pair of
- // percentages (x%,y%) implies that at least the first two characters
- // are the first percentage value.
- size_t delimiterOffset = value.find(delimiter, 2);
- if (delimiterOffset == kNotFound || delimiterOffset == value.length() - 1)
+ float firstCoord;
+ if (!parseFloatPercentageValue(valueScanner, firstCoord))
return false;
- float firstCoord;
- if (!parseFloatPercentageValue(value.substring(0, delimiterOffset), firstCoord))
+ if (!valueScanner.scan(delimiter))
return false;
float secondCoord;
- if (!parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), secondCoord))
+ if (!parseFloatPercentageValue(valueScanner, secondCoord))
return false;
valuePair = FloatPoint(firstCoord, secondCoord);
@@ -148,13 +90,13 @@ VTTParser::VTTParser(VTTParserClient* client, Document& document)
{
}
-void VTTParser::getNewCues(Vector<RefPtr<VTTCue> >& outputCues)
+void VTTParser::getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >& outputCues)
{
- outputCues = m_cuelist;
- m_cuelist.clear();
+ outputCues = m_cueList;
+ m_cueList.clear();
}
-void VTTParser::getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions)
+void VTTParser::getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >& outputRegions)
{
outputRegions = m_regionList;
m_regionList.clear();
@@ -301,41 +243,35 @@ VTTParser::ParseState VTTParser::collectCueId(const String& line)
{
if (line.contains("-->"))
return collectTimingsAndSettings(line);
- m_currentId = line;
+ m_currentId = AtomicString(line);
return TimingsAndSettings;
}
VTTParser::ParseState VTTParser::collectTimingsAndSettings(const String& line)
{
+ VTTScanner input(line);
+
// Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and settings parsing.)
// Steps 1 - 3 - Let input be the string being parsed and position be a pointer into input.
- unsigned position = 0;
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue start time be the collected time.
- if (!collectTimeStamp(line, &position, m_currentStartTime))
- return BadCue;
- if (position >= line.length())
+ if (!collectTimeStamp(input, m_currentStartTime))
return BadCue;
-
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Steps 6 - 9 - If the next three characters are not "-->", abort and return failure.
- if (line.find("-->", position) == kNotFound)
+ if (!input.scan("-->"))
return BadCue;
- position += 3;
- if (position >= line.length())
- return BadCue;
-
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected time.
- if (!collectTimeStamp(line, &position, m_currentEndTime))
+ if (!collectTimeStamp(input, m_currentEndTime))
return BadCue;
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCue).
- m_currentSettings = line.substring(position, line.length()-1);
+ m_currentSettings = input.restOfInputAsString();
return CueText;
}
@@ -381,31 +317,33 @@ VTTParser::ParseState VTTParser::ignoreBadCue(const String& line)
// A helper class for the construction of a "cue fragment" from the cue text.
class VTTTreeBuilder {
+ STACK_ALLOCATED();
public:
- VTTTreeBuilder(Document& document)
- : m_document(document) { }
+ explicit VTTTreeBuilder(Document& document)
+ : m_document(&document) { }
- PassRefPtr<DocumentFragment> buildFromString(const String& cueText);
+ PassRefPtrWillBeRawPtr<DocumentFragment> buildFromString(const String& cueText);
private:
void constructTreeFromToken(Document&);
+ Document& document() const { return *m_document; }
VTTToken m_token;
- RefPtr<ContainerNode> m_currentNode;
+ RefPtrWillBeMember<ContainerNode> m_currentNode;
Vector<AtomicString> m_languageStack;
- Document& m_document;
+ RawPtrWillBeMember<Document> m_document;
};
-PassRefPtr<DocumentFragment> VTTTreeBuilder::buildFromString(const String& cueText)
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTTreeBuilder::buildFromString(const String& cueText)
{
// Cue text processing based on
// 5.4 WebVTT cue text parsing rules, and
// 5.5 WebVTT cue text DOM construction rules
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document());
if (cueText.isEmpty()) {
- fragment->parserAppendChild(Text::create(m_document, ""));
+ fragment->parserAppendChild(Text::create(document(), ""));
return fragment;
}
@@ -415,12 +353,12 @@ PassRefPtr<DocumentFragment> VTTTreeBuilder::buildFromString(const String& cueTe
m_languageStack.clear();
while (tokenizer.nextToken(m_token))
- constructTreeFromToken(m_document);
+ constructTreeFromToken(document());
return fragment.release();
}
-PassRefPtr<DocumentFragment> VTTParser::createDocumentFragmentFromCueText(Document& document, const String& cueText)
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTParser::createDocumentFragmentFromCueText(Document& document, const String& cueText)
{
VTTTreeBuilder treeBuilder(document);
return treeBuilder.buildFromString(cueText);
@@ -428,18 +366,18 @@ PassRefPtr<DocumentFragment> VTTParser::createDocumentFragmentFromCueText(Docume
void VTTParser::createNewCue()
{
- RefPtr<VTTCue> cue = VTTCue::create(*m_document, m_currentStartTime, m_currentEndTime, m_currentContent.toString());
+ RefPtrWillBeRawPtr<VTTCue> cue = VTTCue::create(*m_document, m_currentStartTime, m_currentEndTime, m_currentContent.toString());
cue->setId(m_currentId);
cue->parseSettings(m_currentSettings);
- m_cuelist.append(cue);
+ m_cueList.append(cue);
if (m_client)
m_client->newCuesParsed();
}
void VTTParser::resetCueValues()
{
- m_currentId = emptyString();
+ m_currentId = emptyAtom;
m_currentSettings = emptyString();
m_currentStartTime = 0;
m_currentEndTime = 0;
@@ -452,7 +390,7 @@ void VTTParser::createNewRegion(const String& headerValue)
return;
// Steps 12.5.1 - 12.5.9 - Construct and initialize a WebVTT Region object.
- RefPtr<VTTRegion> region = VTTRegion::create();
+ RefPtrWillBeRawPtr<VTTRegion> region = VTTRegion::create();
region->setRegionSettings(headerValue);
// Step 12.5.10 If the text track list of regions regions contains a region
@@ -468,7 +406,13 @@ void VTTParser::createNewRegion(const String& headerValue)
m_regionList.append(region);
}
-bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double& timeStamp)
+bool VTTParser::collectTimeStamp(const String& line, double& timeStamp)
+{
+ VTTScanner input(line);
+ return collectTimeStamp(input, timeStamp);
+}
+
+bool VTTParser::collectTimeStamp(VTTScanner& input, double& timeStamp)
{
// Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.)
// Steps 1 - 4 - Initial checks, let most significant units be minutes.
@@ -478,25 +422,21 @@ bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double&
// Steps 5 - 7 - Collect a sequence of characters that are 0-9.
// If not 2 characters or value is greater than 59, interpret as hours.
int value1;
- unsigned value1Digits = collectDigitsToInt(line, position, value1);
+ unsigned value1Digits = input.scanDigits(value1);
if (!value1Digits)
return false;
if (value1Digits != 2 || value1 > 59)
mode = Hours;
// Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
- if (*position >= line.length() || line[(*position)++] != ':')
- return false;
int value2;
- if (collectDigitsToInt(line, position, value2) != 2)
+ if (!input.scan(':') || input.scanDigits(value2) != 2)
return false;
// Step 12 - Detect whether this timestamp includes hours.
int value3;
- if (mode == Hours || (*position < line.length() && line[*position] == ':')) {
- if (*position >= line.length() || line[(*position)++] != ':')
- return false;
- if (collectDigitsToInt(line, position, value3) != 2)
+ if (mode == Hours || input.match(':')) {
+ if (!input.scan(':') || input.scanDigits(value3) != 2)
return false;
} else {
value3 = value2;
@@ -505,10 +445,8 @@ bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double&
}
// Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
- if (*position >= line.length() || line[(*position)++] != '.')
- return false;
int value4;
- if (collectDigitsToInt(line, position, value4) != 3)
+ if (!input.scan('.') || input.scanDigits(value4) != 3)
return false;
if (value2 > 59 || value3 > 59)
return false;
@@ -553,8 +491,7 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
switch (m_token.type()) {
case VTTTokenTypes::Character: {
- RefPtr<Text> child = Text::create(document, m_token.characters());
- m_currentNode->parserAppendChild(child);
+ m_currentNode->parserAppendChild(Text::create(document, m_token.characters()));
break;
}
case VTTTokenTypes::StartTag: {
@@ -567,7 +504,7 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
if (nodeType == VTTNodeTypeRubyText && currentType != VTTNodeTypeRuby)
break;
- RefPtr<VTTElement> child = VTTElement::create(nodeType, &document);
+ RefPtrWillBeRawPtr<VTTElement> child = VTTElement::create(nodeType, &document);
if (!m_token.classes().isEmpty())
child->setAttribute(classAttr, m_token.classes());
@@ -611,10 +548,9 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
break;
}
case VTTTokenTypes::TimestampTag: {
- unsigned position = 0;
String charactersString = m_token.characters();
double parsedTimeStamp;
- if (VTTParser::collectTimeStamp(charactersString, &position, parsedTimeStamp))
+ if (VTTParser::collectTimeStamp(charactersString, parsedTimeStamp))
m_currentNode->parserAppendChild(ProcessingInstruction::create(document, "timestamp", charactersString));
break;
}
@@ -623,5 +559,11 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
}
}
+void VTTParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_cueList);
+ visitor->trace(m_regionList);
}
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h
index df4e584cae9..3fca1af5e74 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h
@@ -31,22 +31,21 @@
#ifndef VTTParser_h
#define VTTParser_h
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/dom/DocumentFragment.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/track/vtt/BufferedLineReader.h"
#include "core/html/track/vtt/VTTCue.h"
#include "core/html/track/vtt/VTTRegion.h"
#include "core/html/track/vtt/VTTTokenizer.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-using namespace HTMLNames;
-
class Document;
+class VTTScanner;
class VTTParserClient {
public:
@@ -57,7 +56,7 @@ public:
virtual void fileFailedToParse() = 0;
};
-class VTTParser FINAL {
+class VTTParser FINAL : public NoBaseWillBeGarbageCollectedFinalized<VTTParser> {
public:
enum ParseState {
Initial,
@@ -68,54 +67,53 @@ public:
BadCue
};
- static PassOwnPtr<VTTParser> create(VTTParserClient* client, Document& document)
+ static PassOwnPtrWillBeRawPtr<VTTParser> create(VTTParserClient* client, Document& document)
{
- return adoptPtr(new VTTParser(client, document));
+ return adoptPtrWillBeNoop(new VTTParser(client, document));
}
static inline bool isRecognizedTag(const AtomicString& tagName)
{
- return tagName == iTag
- || tagName == bTag
- || tagName == uTag
- || tagName == rubyTag
- || tagName == rtTag;
+ return tagName == HTMLNames::iTag
+ || tagName == HTMLNames::bTag
+ || tagName == HTMLNames::uTag
+ || tagName == HTMLNames::rubyTag
+ || tagName == HTMLNames::rtTag;
}
-
- static inline bool isASpace(char c)
+ static inline bool isASpace(UChar c)
{
// WebVTT space characters are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';
}
- static inline bool isValidSettingDelimiter(char c)
+ static inline bool isValidSettingDelimiter(UChar c)
{
// ... a WebVTT cue consists of zero or more of the following components, in any order, separated from each other by one or more
// U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
return c == ' ' || c == '\t';
}
- static unsigned collectDigitsToInt(const String& input, unsigned* position, int& number);
- static String collectWord(const String&, unsigned*);
- static bool collectTimeStamp(const String&, unsigned*, double& timeStamp);
+ static bool collectTimeStamp(const String&, double& timeStamp);
// Useful functions for parsing percentage settings.
- static bool parseFloatPercentageValue(const String&, float&);
- static bool parseFloatPercentageValuePair(const String&, char, FloatPoint&);
+ static bool parseFloatPercentageValue(VTTScanner& valueScanner, float& percentage);
+ static bool parseFloatPercentageValuePair(VTTScanner&, char, FloatPoint&);
// Create the DocumentFragment representation of the WebVTT cue text.
- static PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
// Input data to the parser to parse.
void parseBytes(const char* data, unsigned length);
void flush();
// Transfers ownership of last parsed cues to caller.
- void getNewCues(Vector<RefPtr<VTTCue> >&);
- void getNewRegions(Vector<RefPtr<VTTRegion> >&);
+ void getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >&);
+ void getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >&);
+
+ void trace(Visitor*);
private:
VTTParser(VTTParserClient*, Document&);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
ParseState m_state;
void parse();
@@ -133,11 +131,11 @@ private:
void collectMetadataHeader(const String&);
void createNewRegion(const String& headerValue);
- static void skipWhiteSpace(const String&, unsigned*);
+ static bool collectTimeStamp(VTTScanner& input, double& timeStamp);
BufferedLineReader m_lineReader;
OwnPtr<TextResourceDecoder> m_decoder;
- String m_currentId;
+ AtomicString m_currentId;
double m_currentStartTime;
double m_currentEndTime;
StringBuilder m_currentContent;
@@ -145,9 +143,9 @@ private:
VTTParserClient* m_client;
- Vector<RefPtr<VTTCue> > m_cuelist;
+ WillBeHeapVector<RefPtrWillBeMember<VTTCue> > m_cueList;
- Vector<RefPtr<VTTRegion> > m_regionList;
+ WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > m_regionList;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
index 4f39fb51cc9..26b32a39864 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
@@ -37,6 +37,7 @@
#include "core/dom/DOMTokenList.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/track/vtt/VTTParser.h"
+#include "core/html/track/vtt/VTTScanner.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderObject.h"
#include "platform/Logging.h"
@@ -67,14 +68,10 @@ static const float lineHeight = 5.33;
// Default scrolling animation time period (s).
static const float scrollTime = 0.433;
-static bool isInfiniteOrNonNumberOrNonPercentage(double value, const char* method, ExceptionState& exceptionState)
+static bool isNonPercentage(double value, const char* method, ExceptionState& exceptionState)
{
- if (!std::isfinite(value)) {
- exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(value));
- return true;
- }
if (value < 0 || value > 100) {
- exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0.0, ExceptionMessages::InclusiveBound, 100.0, ExceptionMessages::InclusiveBound));
return true;
}
return false;
@@ -87,7 +84,7 @@ VTTRegion::VTTRegion()
, m_regionAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
, m_viewportAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
, m_scroll(defaultScroll)
- , m_track(0)
+ , m_track(nullptr)
, m_currentTop(0)
, m_scrollTimer(this, &VTTRegion::scrollTimerFired)
{
@@ -109,7 +106,7 @@ void VTTRegion::setId(const String& id)
void VTTRegion::setWidth(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "width", exceptionState))
+ if (isNonPercentage(value, "width", exceptionState))
return;
m_width = value;
@@ -127,7 +124,7 @@ void VTTRegion::setHeight(long value, ExceptionState& exceptionState)
void VTTRegion::setRegionAnchorX(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "regionAnchorX", exceptionState))
+ if (isNonPercentage(value, "regionAnchorX", exceptionState))
return;
m_regionAnchor.setX(value);
@@ -135,7 +132,7 @@ void VTTRegion::setRegionAnchorX(double value, ExceptionState& exceptionState)
void VTTRegion::setRegionAnchorY(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "regionAnchorY", exceptionState))
+ if (isNonPercentage(value, "regionAnchorY", exceptionState))
return;
m_regionAnchor.setY(value);
@@ -143,7 +140,7 @@ void VTTRegion::setRegionAnchorY(double value, ExceptionState& exceptionState)
void VTTRegion::setViewportAnchorX(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "viewportAnchorX", exceptionState))
+ if (isNonPercentage(value, "viewportAnchorX", exceptionState))
return;
m_viewportAnchor.setX(value);
@@ -151,7 +148,7 @@ void VTTRegion::setViewportAnchorX(double value, ExceptionState& exceptionState)
void VTTRegion::setViewportAnchorY(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "viewportAnchorY", exceptionState))
+ if (isNonPercentage(value, "viewportAnchorY", exceptionState))
return;
m_viewportAnchor.setY(value);
@@ -190,83 +187,102 @@ void VTTRegion::updateParametersFromRegion(VTTRegion* region)
setScroll(region->scroll(), ASSERT_NO_EXCEPTION);
}
-void VTTRegion::setRegionSettings(const String& input)
+void VTTRegion::setRegionSettings(const String& inputString)
{
- m_settings = input;
- unsigned position = 0;
+ m_settings = inputString;
+
+ VTTScanner input(inputString);
- while (position < input.length()) {
- while (position < input.length() && VTTParser::isValidSettingDelimiter(input[position]))
- position++;
+ while (!input.isAtEnd()) {
+ input.skipWhile<VTTParser::isValidSettingDelimiter>();
- if (position >= input.length())
+ if (input.isAtEnd())
break;
- parseSetting(input, &position);
+ // Scan the name part.
+ RegionSetting name = scanSettingName(input);
+
+ // Verify that we're looking at a '='.
+ if (name == None || !input.scan('=')) {
+ input.skipUntil<VTTParser::isASpace>();
+ continue;
+ }
+
+ // Scan the value part.
+ parseSettingValue(name, input);
}
}
-VTTRegion::RegionSetting VTTRegion::getSettingFromString(const String& setting)
+VTTRegion::RegionSetting VTTRegion::scanSettingName(VTTScanner& input)
{
- DEFINE_STATIC_LOCAL(const AtomicString, idKeyword, ("id", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, heightKeyword, ("height", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, widthKeyword, ("width", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, regionAnchorKeyword, ("regionanchor", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, viewportAnchorKeyword, ("viewportanchor", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, scrollKeyword, ("scroll", AtomicString::ConstructFromLiteral));
-
- if (setting == idKeyword)
+ if (input.scan("id"))
return Id;
- if (setting == heightKeyword)
+ if (input.scan("height"))
return Height;
- if (setting == widthKeyword)
+ if (input.scan("width"))
return Width;
- if (setting == viewportAnchorKeyword)
+ if (input.scan("viewportanchor"))
return ViewportAnchor;
- if (setting == regionAnchorKeyword)
+ if (input.scan("regionanchor"))
return RegionAnchor;
- if (setting == scrollKeyword)
+ if (input.scan("scroll"))
return Scroll;
return None;
}
-void VTTRegion::parseSettingValue(RegionSetting setting, const String& value)
+static inline bool parsedEntireRun(const VTTScanner& input, const VTTScanner::Run& run)
+{
+ return input.isAt(run.end());
+}
+
+void VTTRegion::parseSettingValue(RegionSetting setting, VTTScanner& input)
{
DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicString::ConstructFromLiteral));
+ VTTScanner::Run valueRun = input.collectUntil<VTTParser::isASpace>();
+
switch (setting) {
- case Id:
- if (value.find("-->") == kNotFound)
- m_id = value;
+ case Id: {
+ String stringValue = input.extractString(valueRun);
+ if (stringValue.find("-->") == kNotFound)
+ m_id = stringValue;
break;
+ }
case Width: {
float floatWidth;
- if (VTTParser::parseFloatPercentageValue(value, floatWidth))
+ if (VTTParser::parseFloatPercentageValue(input, floatWidth) && parsedEntireRun(input, valueRun))
m_width = floatWidth;
else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid Width");
break;
}
case Height: {
- unsigned position = 0;
int number;
- if (VTTParser::collectDigitsToInt(value, &position, number) && position == value.length())
+ if (input.scanDigits(number) && parsedEntireRun(input, valueRun))
m_heightInLines = number;
else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid Height");
break;
}
- case RegionAnchor:
- if (!VTTParser::parseFloatPercentageValuePair(value, ',', m_regionAnchor))
+ case RegionAnchor: {
+ FloatPoint anchor;
+ if (VTTParser::parseFloatPercentageValuePair(input, ',', anchor) && parsedEntireRun(input, valueRun))
+ m_regionAnchor = anchor;
+ else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid RegionAnchor");
break;
- case ViewportAnchor:
- if (!VTTParser::parseFloatPercentageValuePair(value, ',', m_viewportAnchor))
+ }
+ case ViewportAnchor: {
+ FloatPoint anchor;
+ if (VTTParser::parseFloatPercentageValuePair(input, ',', anchor) && parsedEntireRun(input, valueRun))
+ m_viewportAnchor = anchor;
+ else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid ViewportAnchor");
break;
+ }
case Scroll:
- if (value == scrollUpValueKeyword)
+ if (input.scanRun(valueRun, scrollUpValueKeyword))
m_scroll = true;
else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid Scroll");
@@ -274,20 +290,8 @@ void VTTRegion::parseSettingValue(RegionSetting setting, const String& value)
case None:
break;
}
-}
-
-void VTTRegion::parseSetting(const String& input, unsigned* position)
-{
- String setting = VTTParser::collectWord(input, position);
- size_t equalOffset = setting.find('=', 1);
- if (equalOffset == kNotFound || !equalOffset || equalOffset == setting.length() - 1)
- return;
-
- RegionSetting name = getSettingFromString(setting.substring(0, equalOffset));
- String value = setting.substring(equalOffset + 1, setting.length() - 1);
-
- parseSettingValue(name, value);
+ input.skipRun(valueRun);
}
const AtomicString& VTTRegion::textTrackCueContainerShadowPseudoId()
@@ -314,7 +318,7 @@ const AtomicString& VTTRegion::textTrackRegionShadowPseudoId()
return trackRegionShadowPseudoId;
}
-PassRefPtr<HTMLDivElement> VTTRegion::getDisplayTree(Document& document)
+PassRefPtrWillBeRawPtr<HTMLDivElement> VTTRegion::getDisplayTree(Document& document)
{
if (!m_regionDisplayTree) {
m_regionDisplayTree = HTMLDivElement::create(document);
@@ -331,13 +335,13 @@ void VTTRegion::willRemoveVTTCueBox(VTTCueBox* box)
double boxHeight = box->getBoundingClientRect()->bottom() - box->getBoundingClientRect()->top();
- m_cueContainer->classList()->remove(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
+ m_cueContainer->classList().remove(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
m_currentTop += boxHeight;
m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSSPrimitiveValue::CSS_PX);
}
-void VTTRegion::appendVTTCueBox(PassRefPtr<VTTCueBox> displayBox)
+void VTTRegion::appendVTTCueBox(PassRefPtrWillBeRawPtr<VTTCueBox> displayBox)
{
ASSERT(m_cueContainer);
@@ -362,14 +366,14 @@ void VTTRegion::displayLastVTTCueBox()
// If it's a scrolling region, add the scrolling class.
if (isScrollingRegion())
- m_cueContainer->classList()->add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
+ m_cueContainer->classList().add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
float regionBottom = m_regionDisplayTree->getBoundingClientRect()->bottom();
// Find first cue that is not entirely displayed and scroll it upwards.
- for (size_t i = 0; i < m_cueContainer->childNodeCount() && !m_scrollTimer.isActive(); ++i) {
- float childTop = toHTMLDivElement(m_cueContainer->childNode(i))->getBoundingClientRect()->top();
- float childBottom = toHTMLDivElement(m_cueContainer->childNode(i))->getBoundingClientRect()->bottom();
+ for (Element* child = ElementTraversal::firstWithin(*m_cueContainer); child && !m_scrollTimer.isActive(); child = ElementTraversal::nextSibling(*child)) {
+ float childTop = toHTMLDivElement(child)->getBoundingClientRect()->top();
+ float childBottom = toHTMLDivElement(child)->getBoundingClientRect()->bottom();
if (regionBottom >= childBottom)
continue;
@@ -429,11 +433,11 @@ void VTTRegion::prepareRegionDisplayTree()
0.0,
CSSPrimitiveValue::CSS_PX);
- m_cueContainer->setPseudo(textTrackCueContainerShadowPseudoId());
+ m_cueContainer->setShadowPseudoId(textTrackCueContainerShadowPseudoId());
m_regionDisplayTree->appendChild(m_cueContainer);
// 7.5 Every WebVTT region object is initialised with the following CSS
- m_regionDisplayTree->setPseudo(textTrackRegionShadowPseudoId());
+ m_regionDisplayTree->setShadowPseudoId(textTrackRegionShadowPseudoId());
}
void VTTRegion::startTimer()
@@ -444,7 +448,7 @@ void VTTRegion::startTimer()
return;
double duration = isScrollingRegion() ? scrollTime : 0;
- m_scrollTimer.startOneShot(duration);
+ m_scrollTimer.startOneShot(duration, FROM_HERE);
}
void VTTRegion::stopTimer()
@@ -463,4 +467,11 @@ void VTTRegion::scrollTimerFired(Timer<VTTRegion>*)
displayLastVTTCueBox();
}
+void VTTRegion::trace(Visitor* visitor)
+{
+ visitor->trace(m_cueContainer);
+ visitor->trace(m_regionDisplayTree);
+ visitor->trace(m_track);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
index f9452c22498..ab2121eab97 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
@@ -35,6 +35,7 @@
#include "core/html/track/TextTrack.h"
#include "platform/Timer.h"
#include "platform/geometry/FloatPoint.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
@@ -43,12 +44,13 @@ namespace WebCore {
class ExceptionState;
class HTMLDivElement;
class VTTCueBox;
+class VTTScanner;
-class VTTRegion : public RefCounted<VTTRegion> {
+class VTTRegion FINAL : public RefCountedWillBeGarbageCollectedFinalized<VTTRegion> {
public:
- static PassRefPtr<VTTRegion> create()
+ static PassRefPtrWillBeRawPtr<VTTRegion> create()
{
- return adoptRef(new VTTRegion());
+ return adoptRefWillBeNoop(new VTTRegion());
}
virtual ~VTTRegion();
@@ -87,12 +89,14 @@ public:
bool isScrollingRegion() { return m_scroll; }
- PassRefPtr<HTMLDivElement> getDisplayTree(Document&);
+ PassRefPtrWillBeRawPtr<HTMLDivElement> getDisplayTree(Document&);
- void appendVTTCueBox(PassRefPtr<VTTCueBox>);
+ void appendVTTCueBox(PassRefPtrWillBeRawPtr<VTTCueBox>);
void displayLastVTTCueBox();
void willRemoveVTTCueBox(VTTCueBox*);
+ void trace(Visitor*);
+
private:
VTTRegion();
@@ -112,9 +116,8 @@ private:
ViewportAnchor,
Scroll
};
- RegionSetting getSettingFromString(const String&);
- void parseSettingValue(RegionSetting, const String&);
- void parseSetting(const String&, unsigned*);
+ RegionSetting scanSettingName(VTTScanner&);
+ void parseSettingValue(RegionSetting, VTTScanner&);
static const AtomicString& textTrackCueContainerShadowPseudoId();
static const AtomicString& textTrackCueContainerScrollingClass();
@@ -130,14 +133,14 @@ private:
// The cue container is the container that is scrolled up to obtain the
// effect of scrolling cues when this is enabled for the regions.
- RefPtr<HTMLDivElement> m_cueContainer;
- RefPtr<HTMLDivElement> m_regionDisplayTree;
+ RefPtrWillBeMember<HTMLDivElement> m_cueContainer;
+ RefPtrWillBeMember<HTMLDivElement> m_regionDisplayTree;
// The member variable track can be a raw pointer as it will never
// reference a destroyed TextTrack, as this member variable
// is cleared in the TextTrack destructor and it is generally
// set/reset within the addRegion and removeRegion methods.
- TextTrack* m_track;
+ RawPtrWillBeMember<TextTrack> m_track;
// Keep track of the current numeric value of the css "top" property.
double m_currentTop;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
index 398f7404b97..1a28e70b4da 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
@@ -25,7 +25,9 @@
[
Constructor,
- RuntimeEnabled=WebVTTRegions
+ RuntimeEnabled=WebVTTRegions,
+ TypeChecking=Unrestricted,
+ WillBeGarbageCollected,
] interface VTTRegion {
readonly attribute TextTrack track;
@@ -38,4 +40,3 @@
[RaisesException=Setter] attribute double viewportAnchorY;
[RaisesException=Setter] attribute DOMString scroll;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp
index 914da521ae7..41bf33ad8b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp
@@ -58,7 +58,7 @@ VTTRegion* VTTRegionList::getRegionById(const String& id) const
return 0;
}
-void VTTRegionList::add(PassRefPtr<VTTRegion> region)
+void VTTRegionList::add(PassRefPtrWillBeRawPtr<VTTRegion> region)
{
m_list.append(region);
}
@@ -73,9 +73,9 @@ bool VTTRegionList::remove(VTTRegion* region)
return true;
}
-void VTTRegionList::clear()
+void VTTRegionList::trace(Visitor* visitor)
{
- m_list.clear();
+ visitor->trace(m_list);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h
index 35e1b8e8d47..edb87d601b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h
@@ -33,28 +33,27 @@
namespace WebCore {
-class VTTRegionList : public RefCounted<VTTRegionList> {
+class VTTRegionList FINAL : public RefCountedWillBeGarbageCollected<VTTRegionList> {
public:
- static PassRefPtr<VTTRegionList> create()
+ static PassRefPtrWillBeRawPtr<VTTRegionList> create()
{
- return adoptRef(new VTTRegionList());
+ return adoptRefWillBeNoop(new VTTRegionList());
}
- ~VTTRegionList() { }
-
unsigned long length() const;
VTTRegion* item(unsigned index) const;
VTTRegion* getRegionById(const String&) const;
- void add(PassRefPtr<VTTRegion>);
+ void add(PassRefPtrWillBeRawPtr<VTTRegion>);
bool remove(VTTRegion*);
+ void trace(Visitor*);
+
private:
VTTRegionList();
- void clear();
- Vector<RefPtr<VTTRegion> > m_list;
+ WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > m_list;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl
index 4a06653bba0..cdd3d4dd131 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl
@@ -24,7 +24,8 @@
*/
[
- RuntimeEnabled=WebVTTRegions
+ RuntimeEnabled=WebVTTRegions,
+ WillBeGarbageCollected,
] interface VTTRegionList {
readonly attribute unsigned long length;
getter VTTRegion item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
new file mode 100644
index 00000000000..590178f8864
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/track/vtt/VTTScanner.h"
+
+namespace WebCore {
+
+VTTScanner::VTTScanner(const String& line) : m_is8Bit(line.is8Bit())
+{
+ if (m_is8Bit) {
+ m_data.characters8 = line.characters8();
+ m_end.characters8 = m_data.characters8 + line.length();
+ } else {
+ m_data.characters16 = line.characters16();
+ m_end.characters16 = m_data.characters16 + line.length();
+ }
+}
+
+bool VTTScanner::scan(char c)
+{
+ if (!match(c))
+ return false;
+ advance();
+ return true;
+}
+
+bool VTTScanner::scan(const LChar* characters, size_t charactersCount)
+{
+ unsigned matchLength = m_is8Bit ? m_end.characters8 - m_data.characters8 : m_end.characters16 - m_data.characters16;
+ if (matchLength < charactersCount)
+ return false;
+ bool matched;
+ if (m_is8Bit)
+ matched = WTF::equal(m_data.characters8, characters, charactersCount);
+ else
+ matched = WTF::equal(m_data.characters16, characters, charactersCount);
+ if (matched)
+ advance(charactersCount);
+ return matched;
+}
+
+bool VTTScanner::scanRun(const Run& run, const String& toMatch)
+{
+ ASSERT(run.start() == position());
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ size_t matchLength = run.length();
+ if (toMatch.length() > matchLength)
+ return false;
+ bool matched;
+ if (m_is8Bit)
+ matched = WTF::equal(toMatch.impl(), m_data.characters8, matchLength);
+ else
+ matched = WTF::equal(toMatch.impl(), m_data.characters16, matchLength);
+ if (matched)
+ seekTo(run.end());
+ return matched;
+}
+
+void VTTScanner::skipRun(const Run& run)
+{
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ seekTo(run.end());
+}
+
+String VTTScanner::extractString(const Run& run)
+{
+ ASSERT(run.start() == position());
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ String s;
+ if (m_is8Bit)
+ s = String(m_data.characters8, run.length());
+ else
+ s = String(m_data.characters16, run.length());
+ seekTo(run.end());
+ return s;
+}
+
+String VTTScanner::restOfInputAsString()
+{
+ Run rest(position(), end(), m_is8Bit);
+ return extractString(rest);
+}
+
+unsigned VTTScanner::scanDigits(int& number)
+{
+ Run runOfDigits = collectWhile<isASCIIDigit>();
+ if (runOfDigits.isEmpty()) {
+ number = 0;
+ return 0;
+ }
+ bool validNumber;
+ size_t numDigits = runOfDigits.length();
+ if (m_is8Bit)
+ number = charactersToInt(m_data.characters8, numDigits, &validNumber);
+ else
+ number = charactersToInt(m_data.characters16, numDigits, &validNumber);
+
+ // Since we know that scanDigits only scanned valid (ASCII) digits (and
+ // hence that's what got passed to charactersToInt()), the remaining
+ // failure mode for charactersToInt() is overflow, so if |validNumber| is
+ // not true, then set |number| to the maximum int value.
+ if (!validNumber)
+ number = std::numeric_limits<int>::max();
+ // Consume the digits.
+ seekTo(runOfDigits.end());
+ return numDigits;
+}
+
+bool VTTScanner::scanFloat(float& number)
+{
+ Run integerRun = collectWhile<isASCIIDigit>();
+ seekTo(integerRun.end());
+ Run decimalRun(position(), position(), m_is8Bit);
+ if (scan('.')) {
+ decimalRun = collectWhile<isASCIIDigit>();
+ seekTo(decimalRun.end());
+ }
+
+ // At least one digit required.
+ if (integerRun.isEmpty() && decimalRun.isEmpty()) {
+ // Restore to starting position.
+ seekTo(integerRun.start());
+ return false;
+ }
+
+ size_t lengthOfFloat = Run(integerRun.start(), position(), m_is8Bit).length();
+ bool validNumber;
+ if (m_is8Bit)
+ number = charactersToFloat(integerRun.start(), lengthOfFloat, &validNumber);
+ else
+ number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber);
+
+ if (!validNumber)
+ number = std::numeric_limits<float>::max();
+ return true;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
new file mode 100644
index 00000000000..aa097e780ec
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VTTScanner_h
+#define VTTScanner_h
+
+#include "platform/ParsingUtilities.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+// Helper class for "scanning" an input string and performing parsing of
+// "micro-syntax"-like constructs.
+//
+// There's two primary operations: match and scan.
+//
+// The 'match' operation matches an explicitly or implicitly specified sequence
+// against the characters ahead of the current input pointer, and returns true
+// if the sequence can be matched.
+//
+// The 'scan' operation performs a 'match', and if the match is successful it
+// advance the input pointer past the matched sequence.
+class VTTScanner {
+ WTF_MAKE_NONCOPYABLE(VTTScanner);
+public:
+ explicit VTTScanner(const String& line);
+
+ typedef const LChar* Position;
+
+ class Run {
+ public:
+ Run(Position start, Position end, bool is8Bit)
+ : m_start(start), m_end(end), m_is8Bit(is8Bit) { }
+
+ Position start() const { return m_start; }
+ Position end() const { return m_end; }
+
+ bool isEmpty() const { return m_start == m_end; }
+ size_t length() const;
+
+ private:
+ Position m_start;
+ Position m_end;
+ bool m_is8Bit;
+ };
+
+ // Check if the input pointer points at the specified position.
+ bool isAt(Position checkPosition) const { return position() == checkPosition; }
+ // Check if the input pointer points at the end of the input.
+ bool isAtEnd() const { return position() == end(); }
+ // Match the character |c| against the character at the input pointer (~lookahead).
+ bool match(char c) const { return !isAtEnd() && currentChar() == c; }
+ // Scan the character |c|.
+ bool scan(char);
+ // Scan the first |charactersCount| characters of the string |characters|.
+ bool scan(const LChar* characters, size_t charactersCount);
+
+ // Scan the literal |characters|.
+ template<unsigned charactersCount>
+ bool scan(const char (&characters)[charactersCount]);
+
+ // Skip (advance the input pointer) as long as the specified
+ // |characterPredicate| returns true, and the input pointer is not passed
+ // the end of the input.
+ template<bool characterPredicate(UChar)>
+ void skipWhile();
+
+ // Like skipWhile, but using a negated predicate.
+ template<bool characterPredicate(UChar)>
+ void skipUntil();
+
+ // Return the run of characters for which the specified
+ // |characterPredicate| returns true. The start of the run will be the
+ // current input pointer.
+ template<bool characterPredicate(UChar)>
+ Run collectWhile();
+
+ // Like collectWhile, but using a negated predicate.
+ template<bool characterPredicate(UChar)>
+ Run collectUntil();
+
+ // Scan the string |toMatch|, using the specified |run| as the sequence to
+ // match against.
+ bool scanRun(const Run&, const String& toMatch);
+
+ // Skip to the end of the specified |run|.
+ void skipRun(const Run&);
+
+ // Return the String made up of the characters in |run|, and advance the
+ // input pointer to the end of the run.
+ String extractString(const Run&);
+
+ // Return a String constructed from the rest of the input (between input
+ // pointer and end of input), and advance the input pointer accordingly.
+ String restOfInputAsString();
+
+ // Scan a set of ASCII digits from the input. Return the number of digits
+ // scanned, and set |number| to the computed value. If the digits make up a
+ // number that does not fit the 'int' type, |number| is set to INT_MAX.
+ // Note: Does not handle sign.
+ unsigned scanDigits(int& number);
+
+ // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+
+ bool scanFloat(float& number);
+
+protected:
+ Position position() const { return m_data.characters8; }
+ Position end() const { return m_end.characters8; }
+ void seekTo(Position);
+ UChar currentChar() const;
+ void advance(unsigned amount = 1);
+ // Adapt a UChar-predicate to an LChar-predicate.
+ // (For use with skipWhile/Until from ParsingUtilities.h).
+ template<bool characterPredicate(UChar)>
+ static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c); }
+ union {
+ const LChar* characters8;
+ const UChar* characters16;
+ } m_data;
+ union {
+ const LChar* characters8;
+ const UChar* characters16;
+ } m_end;
+ bool m_is8Bit;
+};
+
+inline size_t VTTScanner::Run::length() const
+{
+ if (m_is8Bit)
+ return m_end - m_start;
+ return reinterpret_cast<const UChar*>(m_end) - reinterpret_cast<const UChar*>(m_start);
+}
+
+template<unsigned charactersCount>
+inline bool VTTScanner::scan(const char (&characters)[charactersCount])
+{
+ return scan(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
+}
+
+template<bool characterPredicate(UChar)>
+inline void VTTScanner::skipWhile()
+{
+ if (m_is8Bit)
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
+ else
+ ::skipWhile<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
+}
+
+template<bool characterPredicate(UChar)>
+inline void VTTScanner::skipUntil()
+{
+ if (m_is8Bit)
+ ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
+ else
+ ::skipUntil<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
+}
+
+template<bool characterPredicate(UChar)>
+inline VTTScanner::Run VTTScanner::collectWhile()
+{
+ if (m_is8Bit) {
+ const LChar* current = m_data.characters8;
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
+ return Run(position(), current, m_is8Bit);
+ }
+ const UChar* current = m_data.characters16;
+ ::skipWhile<UChar, characterPredicate>(current, m_end.characters16);
+ return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
+}
+
+template<bool characterPredicate(UChar)>
+inline VTTScanner::Run VTTScanner::collectUntil()
+{
+ if (m_is8Bit) {
+ const LChar* current = m_data.characters8;
+ ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
+ return Run(position(), current, m_is8Bit);
+ }
+ const UChar* current = m_data.characters16;
+ ::skipUntil<UChar, characterPredicate>(current, m_end.characters16);
+ return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
+}
+
+inline void VTTScanner::seekTo(Position position)
+{
+ ASSERT(position <= end());
+ m_data.characters8 = position;
+}
+
+inline UChar VTTScanner::currentChar() const
+{
+ ASSERT(position() < end());
+ return m_is8Bit ? *m_data.characters8 : *m_data.characters16;
+}
+
+inline void VTTScanner::advance(unsigned amount)
+{
+ ASSERT(position() < end());
+ if (m_is8Bit)
+ m_data.characters8 += amount;
+ else
+ m_data.characters16 += amount;
+}
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
new file mode 100644
index 00000000000..d5bcfb8f52f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/track/vtt/VTTScanner.h"
+
+#include "wtf/text/WTFString.h"
+
+#include <gtest/gtest.h>
+
+using WebCore::VTTScanner;
+
+namespace {
+
+TEST(VTTScanner, Constructor)
+{
+ String data8("foo");
+ EXPECT_TRUE(data8.is8Bit());
+ VTTScanner scanner8(data8);
+ EXPECT_FALSE(scanner8.isAtEnd());
+
+ String data16(data8);
+ data16.ensure16Bit();
+ EXPECT_FALSE(data16.is8Bit());
+ VTTScanner scanner16(data16);
+ EXPECT_FALSE(scanner16.isAtEnd());
+
+ VTTScanner scannerEmpty(emptyString());
+ EXPECT_TRUE(scannerEmpty.isAtEnd());
+}
+
+void scanSequenceHelper1(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ EXPECT_TRUE(scanner.match('f'));
+ EXPECT_FALSE(scanner.match('o'));
+
+ EXPECT_TRUE(scanner.scan('f'));
+ EXPECT_FALSE(scanner.match('f'));
+ EXPECT_TRUE(scanner.match('o'));
+
+ EXPECT_FALSE(scanner.scan('e'));
+ EXPECT_TRUE(scanner.scan('o'));
+
+ EXPECT_TRUE(scanner.scan('e'));
+ EXPECT_FALSE(scanner.match('e'));
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Run TESTFUNC with DATA in Latin and then UTF-16. (Requires DATA being Latin.)
+#define TEST_WITH(TESTFUNC, DATA) do { \
+ String data8(DATA); \
+ EXPECT_TRUE(data8.is8Bit()); \
+ TESTFUNC(data8); \
+ \
+ String data16(data8); \
+ data16.ensure16Bit(); \
+ EXPECT_FALSE(data16.is8Bit()); \
+ TESTFUNC(data16); \
+} while (false)
+
+
+// Exercises match(c) and scan(c).
+TEST(VTTScanner, BasicOperations1)
+{
+ TEST_WITH(scanSequenceHelper1, "foe");
+}
+
+void scanSequenceHelper2(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ EXPECT_FALSE(scanner.scan("fe"));
+
+ EXPECT_TRUE(scanner.scan("fo"));
+ EXPECT_FALSE(scanner.isAtEnd());
+
+ EXPECT_FALSE(scanner.scan("ee"));
+
+ EXPECT_TRUE(scanner.scan('e'));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Exercises scan(<literal>[, length]).
+TEST(VTTScanner, BasicOperations2)
+{
+ TEST_WITH(scanSequenceHelper2, "foe");
+}
+
+bool lowerCaseAlpha(UChar c)
+{
+ return c >= 'a' && c <= 'z';
+}
+
+void scanWithPredicate(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Collect "bad".
+ VTTScanner::Run lcRun = scanner.collectWhile<lowerCaseAlpha>();
+ // collectWhile doesn't move the scan position.
+ EXPECT_TRUE(scanner.match('b'));
+ // Consume "bad".
+ scanner.skipWhile<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.match('A'));
+ EXPECT_TRUE(scanner.isAt(lcRun.end()));
+
+ // Consume "A".
+ EXPECT_TRUE(scanner.scan('A'));
+
+ // Collect "bing".
+ lcRun = scanner.collectWhile<lowerCaseAlpha>();
+ // collectWhile doesn't move the scan position.
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Consume "bing".
+ scanner.skipWhile<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.isAt(lcRun.end()));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests skipWhile() and collectWhile().
+TEST(VTTScanner, PredicateScanning)
+{
+ TEST_WITH(scanWithPredicate, "badAbing");
+}
+
+void scanWithInvPredicate(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Collect "BAD".
+ VTTScanner::Run ucRun = scanner.collectUntil<lowerCaseAlpha>();
+ // collectUntil doesn't move the scan position.
+ EXPECT_TRUE(scanner.match('B'));
+ // Consume "BAD".
+ scanner.skipUntil<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.match('a'));
+ EXPECT_TRUE(scanner.isAt(ucRun.end()));
+
+ // Consume "a".
+ EXPECT_TRUE(scanner.scan('a'));
+
+ // Collect "BING".
+ ucRun = scanner.collectUntil<lowerCaseAlpha>();
+ // collectUntil doesn't move the scan position.
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Consume "BING".
+ scanner.skipUntil<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.isAt(ucRun.end()));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests skipUntil() and collectUntil().
+TEST(VTTScanner, InversePredicateScanning)
+{
+ TEST_WITH(scanWithInvPredicate, "BADaBING");
+}
+
+void scanRuns(const String& input)
+{
+ String fooString("foo");
+ String barString("bar");
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>();
+ EXPECT_FALSE(scanner.scanRun(word, barString));
+ EXPECT_TRUE(scanner.scanRun(word, fooString));
+
+ EXPECT_TRUE(scanner.match(':'));
+ EXPECT_TRUE(scanner.scan(':'));
+
+ // Skip 'baz'.
+ scanner.skipRun(scanner.collectWhile<lowerCaseAlpha>());
+
+ EXPECT_TRUE(scanner.match(':'));
+ EXPECT_TRUE(scanner.scan(':'));
+
+ word = scanner.collectWhile<lowerCaseAlpha>();
+ EXPECT_FALSE(scanner.scanRun(word, fooString));
+ EXPECT_TRUE(scanner.scanRun(word, barString));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests scanRun/skipRun.
+TEST(VTTScanner, RunScanning)
+{
+ TEST_WITH(scanRuns, "foo:baz:bar");
+}
+
+void scanRunsToStrings(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>();
+ String fooString = scanner.extractString(word);
+ EXPECT_EQ(fooString, "foo");
+ EXPECT_TRUE(scanner.isAt(word.end()));
+
+ EXPECT_TRUE(scanner.match(':'));
+ EXPECT_TRUE(scanner.scan(':'));
+
+ word = scanner.collectWhile<lowerCaseAlpha>();
+ String barString = scanner.extractString(word);
+ EXPECT_EQ(barString, "bar");
+ EXPECT_TRUE(scanner.isAt(word.end()));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests extractString.
+TEST(VTTScanner, ExtractString)
+{
+ TEST_WITH(scanRunsToStrings, "foo:bar");
+}
+
+void tailStringExtract(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_TRUE(scanner.scan("foo"));
+ EXPECT_TRUE(scanner.scan(':'));
+ String barSuffix = scanner.restOfInputAsString();
+ EXPECT_EQ(barSuffix, "bar");
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests restOfInputAsString().
+TEST(VTTScanner, ExtractRestAsString)
+{
+ TEST_WITH(tailStringExtract, "foo:bar");
+}
+
+void scanDigits1(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_TRUE(scanner.scan("foo"));
+ int number;
+ EXPECT_EQ(scanner.scanDigits(number), 0u);
+ EXPECT_EQ(number, 0);
+ EXPECT_TRUE(scanner.scan(' '));
+ EXPECT_EQ(scanner.scanDigits(number), 3u);
+ EXPECT_TRUE(scanner.match(' '));
+ EXPECT_EQ(number, 123);
+
+ EXPECT_TRUE(scanner.scan(' '));
+ EXPECT_TRUE(scanner.scan("bar"));
+ EXPECT_TRUE(scanner.scan(' '));
+
+ EXPECT_EQ(scanner.scanDigits(number), 5u);
+ EXPECT_EQ(number, 45678);
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+void scanDigits2(const String& input)
+{
+ VTTScanner scanner(input);
+ int number;
+ EXPECT_EQ(scanner.scanDigits(number), 0u);
+ EXPECT_EQ(number, 0);
+ EXPECT_TRUE(scanner.scan('-'));
+ EXPECT_EQ(scanner.scanDigits(number), 3u);
+ EXPECT_EQ(number, 654);
+
+ EXPECT_TRUE(scanner.scan(' '));
+
+ EXPECT_EQ(scanner.scanDigits(number), 19u);
+ EXPECT_EQ(number, std::numeric_limits<int>::max());
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests scanDigits().
+TEST(VTTScanner, ScanDigits)
+{
+ TEST_WITH(scanDigits1, "foo 123 bar 45678");
+ TEST_WITH(scanDigits2, "-654 1000000000000000000");
+}
+
+void scanFloatValue(const String& input)
+{
+ VTTScanner scanner(input);
+ float value;
+ // "1."
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "1.0"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // ".0"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 0.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "." (invalid)
+ EXPECT_FALSE(scanner.scanFloat(value));
+ EXPECT_TRUE(scanner.match('.'));
+ EXPECT_TRUE(scanner.scan('.'));
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "1.0000"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "01.000"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests scanFloat().
+TEST(VTTScanner, ScanFloat)
+{
+ TEST_WITH(scanFloatValue, "1. 1.0 .0 . 1.0000 01.000");
+}
+
+#undef TEST_WITH
+
+} // namespace