summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-09-13 16:35:48 +0100
committerIain Merrick <husky@google.com>2010-09-16 12:10:42 +0100
commit5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306 (patch)
treeddce1aa5e3b6967a69691892e500897558ff8ab6
parent12bec63ec71e46baba27f0bd9bd9d8067683690a (diff)
downloadexternal_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.zip
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.gz
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.bz2
Merge WebKit at r67178 : Initial merge by git.
Change-Id: I57e01163b6866cb029cdadf405a0394a3918bc18
-rw-r--r--ANGLE/ANGLE.xcodeproj/project.pbxproj5
-rw-r--r--ANGLE/ChangeLog458
-rw-r--r--ANGLE/include/GLES2/gl2ext.h58
-rw-r--r--ANGLE/include/GLSLANG/ResourceLimits.h21
-rw-r--r--ANGLE/include/GLSLANG/ShaderLang.h30
-rw-r--r--ANGLE/src/compiler/BaseTypes.h21
-rw-r--r--ANGLE/src/compiler/Initialize.cpp38
-rw-r--r--ANGLE/src/compiler/Initialize.h2
-rw-r--r--ANGLE/src/compiler/InitializeDll.cpp95
-rw-r--r--ANGLE/src/compiler/InitializeDll.h7
-rw-r--r--ANGLE/src/compiler/InitializeParseContext.h5
-rw-r--r--ANGLE/src/compiler/Intermediate.cpp123
-rw-r--r--ANGLE/src/compiler/OutputGLSL.cpp6
-rw-r--r--ANGLE/src/compiler/OutputHLSL.cpp30
-rw-r--r--ANGLE/src/compiler/ParseHelper.cpp78
-rw-r--r--ANGLE/src/compiler/PoolAlloc.h28
-rw-r--r--ANGLE/src/compiler/ShaderLang.cpp44
-rw-r--r--ANGLE/src/compiler/SymbolTable.cpp2
-rw-r--r--ANGLE/src/compiler/SymbolTable.h2
-rw-r--r--ANGLE/src/compiler/Types.h165
-rw-r--r--ANGLE/src/compiler/glslang.l4
-rw-r--r--ANGLE/src/compiler/glslang.y35
-rw-r--r--ANGLE/src/compiler/intermediate.h119
-rw-r--r--ANGLE/src/compiler/parseConst.cpp36
-rw-r--r--ANGLE/src/compiler/preprocessor/atom.c7
-rw-r--r--ANGLE/src/compiler/preprocessor/atom.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/compile.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/cpp.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/cpp.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/cppstruct.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/memory.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/memory.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/parser.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/preprocess.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/scanner.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/scanner.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/slglobals.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/symbols.c7
-rw-r--r--ANGLE/src/compiler/preprocessor/symbols.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/tokens.c7
-rw-r--r--ANGLE/src/compiler/preprocessor/tokens.h5
-rw-r--r--ANGLE/src/libEGL/Display.cpp341
-rw-r--r--ANGLE/src/libEGL/Display.h12
-rw-r--r--ANGLE/src/libEGL/Surface.cpp242
-rw-r--r--ANGLE/src/libEGL/Surface.h13
-rw-r--r--ANGLE/src/libEGL/libEGL.cpp5
-rw-r--r--ANGLE/src/libEGL/libEGL.vcproj4
-rw-r--r--ANGLE/src/libGLESv2/Blit.cpp6
-rw-r--r--ANGLE/src/libGLESv2/Buffer.cpp2
-rw-r--r--ANGLE/src/libGLESv2/Buffer.h5
-rw-r--r--ANGLE/src/libGLESv2/Context.cpp1287
-rw-r--r--ANGLE/src/libGLESv2/Context.h111
-rw-r--r--ANGLE/src/libGLESv2/Framebuffer.cpp286
-rw-r--r--ANGLE/src/libGLESv2/Framebuffer.h41
-rw-r--r--ANGLE/src/libGLESv2/Program.cpp94
-rw-r--r--ANGLE/src/libGLESv2/Program.h15
-rw-r--r--ANGLE/src/libGLESv2/RefCountObject.cpp51
-rw-r--r--ANGLE/src/libGLESv2/RefCountObject.h70
-rw-r--r--ANGLE/src/libGLESv2/Renderbuffer.cpp295
-rw-r--r--ANGLE/src/libGLESv2/Renderbuffer.h123
-rw-r--r--ANGLE/src/libGLESv2/ResourceManager.cpp340
-rw-r--r--ANGLE/src/libGLESv2/ResourceManager.h92
-rw-r--r--ANGLE/src/libGLESv2/Shader.cpp43
-rw-r--r--ANGLE/src/libGLESv2/Shader.h22
-rw-r--r--ANGLE/src/libGLESv2/Texture.cpp558
-rw-r--r--ANGLE/src/libGLESv2/Texture.h103
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.cpp508
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.def12
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.vcproj16
-rw-r--r--ANGLE/src/libGLESv2/main.h1
-rw-r--r--ANGLE/src/libGLESv2/utilities.cpp68
-rw-r--r--ANGLE/src/libGLESv2/utilities.h6
-rw-r--r--JavaScriptCore/API/JSObjectRef.cpp2
-rw-r--r--JavaScriptCore/API/tests/testapi.c29
-rw-r--r--JavaScriptCore/CMakeListsEfl.txt6
-rw-r--r--JavaScriptCore/ChangeLog473
-rw-r--r--JavaScriptCore/Configurations/Base.xcconfig12
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--JavaScriptCore/GNUmakefile.am3
-rw-r--r--JavaScriptCore/JavaScriptCore.exp8
-rw-r--r--JavaScriptCore/JavaScriptCore.gypi1
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def6
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj4
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj65
-rw-r--r--JavaScriptCore/assembler/MIPSAssembler.h17
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerMIPS.h117
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.cpp28
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.h7
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.cpp5
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.h1
-rw-r--r--JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp21
-rw-r--r--JavaScriptCore/jit/JIT.h46
-rw-r--r--JavaScriptCore/jit/JITOpcodes32_64.cpp64
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess32_64.cpp6
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp246
-rw-r--r--JavaScriptCore/jit/JITStubs.h20
-rw-r--r--JavaScriptCore/jsc.cpp3
-rw-r--r--JavaScriptCore/parser/JSParser.cpp73
-rw-r--r--JavaScriptCore/parser/Lexer.cpp61
-rw-r--r--JavaScriptCore/parser/Lexer.h1
-rw-r--r--JavaScriptCore/runtime/InitializeThreading.cpp1
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp44
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h15
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp99
-rw-r--r--JavaScriptCore/runtime/RegExp.h23
-rw-r--r--JavaScriptCore/wtf/ByteArray.h11
-rw-r--r--JavaScriptCore/wtf/CMakeListsEfl.txt4
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp47
-rw-r--r--JavaScriptCore/wtf/NonCopyingSort.h89
-rw-r--r--JavaScriptCore/wtf/Platform.h19
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.cpp13
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.h2
-rw-r--r--JavaScriptCore/wtf/gobject/GTypedefs.h (renamed from JavaScriptCore/wtf/gtk/GtkTypedefs.h)19
-rw-r--r--JavaScriptCore/wtf/text/WTFString.cpp3
-rw-r--r--JavaScriptCore/wtf/url/api/ParsedURL.cpp90
-rw-r--r--JavaScriptCore/wtf/url/api/ParsedURL.h62
-rw-r--r--JavaScriptCore/wtf/url/api/URLString.h55
-rw-r--r--JavaScriptCore/yarr/RegexJIT.h4
-rw-r--r--JavaScriptGlue/ChangeLog19
-rw-r--r--JavaScriptGlue/Configurations/Base.xcconfig2
-rw-r--r--JavaScriptGlue/Configurations/Version.xcconfig2
-rw-r--r--JavaScriptGlue/ForwardingHeaders/wtf/ListHashSet.h1
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback-expected.txt18
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback.html12
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/multiple-frames-expected.txt15
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/multiple-frames.html12
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events-expected.txt10
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events.html12
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/null-values-expected.txt21
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/null-values.html12
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/add-listener-from-callback.js48
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/basic-operation.js4
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/create-event.js2
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/multiple-frames.js43
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/no-synchronous-events.js16
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/null-values.js56
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/optional-event-properties.js2
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/updates.js37
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/script-tests/window-property.js6
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/updates-expected.txt15
-rw-r--r--LayoutTests/fast/dom/DeviceOrientation/updates.html12
-rw-r--r--LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js18
-rw-r--r--LayoutTests/platform/android/Skipped2
-rw-r--r--LayoutTests/storage/indexeddb/basics.html31
-rw-r--r--LayoutTests/storage/indexeddb/database-basics-expected.txt58
-rw-r--r--LayoutTests/storage/indexeddb/database-basics.html76
-rw-r--r--LayoutTests/storage/indexeddb/keyrange-expected.txt28
-rw-r--r--LayoutTests/storage/indexeddb/keyrange.html113
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-basics-expected.txt26
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-basics.html99
-rw-r--r--LayoutTests/storage/indexeddb/objectstore-cursor.html5
-rw-r--r--LayoutTests/storage/indexeddb/open-cursor.html88
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/TEMPLATE.html13
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/basics.js26
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/database-basics.js51
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/keyrange.js76
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/objectstore-basics.js82
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/open-cursor.js83
-rw-r--r--LayoutTests/storage/indexeddb/script-tests/transaction-basics.js47
-rw-r--r--LayoutTests/storage/indexeddb/transaction-basics.html52
-rw-r--r--WebCore/Android.mk16
-rw-r--r--WebCore/CMakeLists.txt29
-rw-r--r--WebCore/CMakeListsEfl.txt37
-rw-r--r--WebCore/ChangeLog5468
-rw-r--r--WebCore/Configurations/Base.xcconfig12
-rw-r--r--WebCore/Configurations/Version.xcconfig2
-rw-r--r--WebCore/DerivedSources.cpp2
-rw-r--r--WebCore/DerivedSources.make2
-rw-r--r--WebCore/English.lproj/localizedStrings.jsbin45878 -> 45952 bytes
-rw-r--r--WebCore/ForwardingHeaders/runtime/RegExp.h4
-rw-r--r--WebCore/ForwardingHeaders/runtime/RegExpObject.h4
-rw-r--r--WebCore/ForwardingHeaders/wtf/NonCopyingSort.h4
-rw-r--r--WebCore/GNUmakefile.am74
-rw-r--r--WebCore/WebCore.exp.in34
-rw-r--r--WebCore/WebCore.gyp/WebCore.gyp23
-rw-r--r--WebCore/WebCore.gypi66
-rw-r--r--WebCore/WebCore.pri8
-rw-r--r--WebCore/WebCore.pro60
-rw-r--r--WebCore/WebCore.vcproj/WebCore.vcproj734
-rw-r--r--WebCore/WebCore.vcproj/WebCoreCommon.vsprops2
-rw-r--r--WebCore/WebCore.xcodeproj/project.pbxproj218
-rw-r--r--WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp4
-rw-r--r--WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp12
-rw-r--r--WebCore/accessibility/mac/AccessibilityObjectWrapper.mm65
-rw-r--r--WebCore/bindings/generic/ActiveDOMCallback.cpp1
-rw-r--r--WebCore/bindings/generic/BindingDOMWindow.h15
-rw-r--r--WebCore/bindings/generic/BindingFrame.h57
-rw-r--r--WebCore/bindings/generic/BindingLocation.h65
-rw-r--r--WebCore/bindings/generic/GenericBinding.h14
-rw-r--r--WebCore/bindings/generic/RuntimeEnabledFeatures.h14
-rw-r--r--WebCore/bindings/js/JSBinding.h51
-rw-r--r--WebCore/bindings/js/JSBindingsAllInOne.cpp1
-rw-r--r--WebCore/bindings/js/JSDOMBinding.cpp20
-rw-r--r--WebCore/bindings/js/JSElementCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSLocationCustom.cpp24
-rw-r--r--WebCore/bindings/js/SerializedScriptValue.cpp1719
-rw-r--r--WebCore/bindings/js/SerializedScriptValue.h233
-rw-r--r--WebCore/bindings/js/specialization/JSBindingState.cpp63
-rw-r--r--WebCore/bindings/js/specialization/JSBindingState.h75
-rw-r--r--WebCore/bindings/objc/DOMHTML.mm9
-rw-r--r--WebCore/bindings/objc/DOMPrivate.h5
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm11
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorV8.pm148
-rw-r--r--WebCore/bindings/scripts/test/CPP/WebDOMTestObj.cpp16
-rw-r--r--WebCore/bindings/scripts/test/CPP/WebDOMTestObj.h2
-rw-r--r--WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.cpp19
-rw-r--r--WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.h6
-rw-r--r--WebCore/bindings/scripts/test/JS/JSTestObj.cpp59
-rw-r--r--WebCore/bindings/scripts/test/JS/JSTestObj.h2
-rw-r--r--WebCore/bindings/scripts/test/ObjC/DOMTestObj.h2
-rw-r--r--WebCore/bindings/scripts/test/ObjC/DOMTestObj.mm12
-rw-r--r--WebCore/bindings/scripts/test/TestObj.idl5
-rw-r--r--WebCore/bindings/scripts/test/V8/V8TestObj.cpp50
-rw-r--r--WebCore/bindings/v8/V8Binding.h8
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.cpp18
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.h2
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.cpp4
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.h15
-rw-r--r--WebCore/bindings/v8/V8GCController.cpp11
-rw-r--r--WebCore/bindings/v8/V8Utilities.cpp9
-rw-r--r--WebCore/bindings/v8/custom/V8LocationCustom.cpp15
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp2
-rw-r--r--WebCore/bindings/v8/specialization/V8BindingState.cpp5
-rw-r--r--WebCore/bindings/v8/specialization/V8BindingState.h3
-rw-r--r--WebCore/bridge/qt/qt_instance.cpp28
-rw-r--r--WebCore/bridge/qt/qt_runtime.cpp18
-rw-r--r--WebCore/css/CSSComputedStyleDeclaration.cpp43
-rw-r--r--WebCore/css/CSSComputedStyleDeclaration.h1
-rw-r--r--WebCore/css/CSSCursorImageValue.cpp4
-rw-r--r--WebCore/css/CSSCursorImageValue.h2
-rw-r--r--WebCore/css/CSSFontFaceSource.cpp6
-rw-r--r--WebCore/css/CSSFontSelector.cpp8
-rw-r--r--WebCore/css/CSSFontSelector.h4
-rw-r--r--WebCore/css/CSSGrammar.y6
-rw-r--r--WebCore/css/CSSImageValue.cpp6
-rw-r--r--WebCore/css/CSSImageValue.h6
-rw-r--r--WebCore/css/CSSImportRule.cpp10
-rw-r--r--WebCore/css/CSSParser.cpp84
-rw-r--r--WebCore/css/CSSParser.h12
-rw-r--r--WebCore/css/CSSPrimitiveValue.cpp64
-rw-r--r--WebCore/css/CSSPrimitiveValue.h9
-rw-r--r--WebCore/css/CSSStyleSelector.cpp76
-rw-r--r--WebCore/css/CSSStyleSelector.h8
-rw-r--r--WebCore/css/CSSStyleSheet.h2
-rw-r--r--WebCore/css/CSSTimingFunctionValue.cpp17
-rw-r--r--WebCore/css/CSSTimingFunctionValue.h68
-rw-r--r--WebCore/css/CSSValueKeywords.in2
-rw-r--r--WebCore/css/MediaList.cpp1
-rw-r--r--WebCore/css/MediaQuery.cpp21
-rw-r--r--WebCore/css/MediaQuery.h6
-rw-r--r--WebCore/css/MediaQueryEvaluator.cpp6
-rw-r--r--WebCore/css/MediaQueryExp.cpp8
-rw-r--r--WebCore/css/MediaQueryExp.h5
-rw-r--r--WebCore/css/mathml.css3
-rw-r--r--WebCore/css/tokenizer.flex3
-rw-r--r--WebCore/dom/AsyncScriptRunner.cpp15
-rw-r--r--WebCore/dom/AsyncScriptRunner.h6
-rw-r--r--WebCore/dom/ContainerNode.cpp24
-rw-r--r--WebCore/dom/DecodedDataDocumentParser.cpp3
-rw-r--r--WebCore/dom/DecodedDataDocumentParser.h7
-rw-r--r--WebCore/dom/Document.cpp43
-rw-r--r--WebCore/dom/Document.h15
-rw-r--r--WebCore/dom/DocumentParser.cpp19
-rw-r--r--WebCore/dom/DocumentParser.h41
-rw-r--r--WebCore/dom/Element.cpp52
-rw-r--r--WebCore/dom/Element.h2
-rw-r--r--WebCore/dom/InputElement.cpp4
-rw-r--r--WebCore/dom/InputElement.h2
-rw-r--r--WebCore/dom/MessagePortChannel.cpp2
-rw-r--r--WebCore/dom/ProcessingInstruction.cpp6
-rw-r--r--WebCore/dom/RawDataDocumentParser.h2
-rw-r--r--WebCore/dom/ScriptElement.cpp6
-rw-r--r--WebCore/dom/ScriptableDocumentParser.cpp4
-rw-r--r--WebCore/dom/ScriptableDocumentParser.h2
-rw-r--r--WebCore/dom/SelectElement.h2
-rw-r--r--WebCore/dom/XMLDocumentParser.cpp9
-rw-r--r--WebCore/dom/XMLDocumentParser.h4
-rw-r--r--WebCore/dom/XMLDocumentParserLibxml2.cpp54
-rw-r--r--WebCore/dom/XMLDocumentParserQt.cpp10
-rw-r--r--WebCore/dom/XMLDocumentParserScope.cpp16
-rw-r--r--WebCore/dom/XMLDocumentParserScope.h10
-rw-r--r--WebCore/editing/ApplyStyleCommand.cpp236
-rw-r--r--WebCore/editing/ApplyStyleCommand.h3
-rw-r--r--WebCore/editing/CompositeEditCommand.cpp6
-rw-r--r--WebCore/editing/DeleteSelectionCommand.cpp2
-rw-r--r--WebCore/editing/Editor.cpp521
-rw-r--r--WebCore/editing/Editor.h63
-rw-r--r--WebCore/editing/EditorCommand.cpp21
-rw-r--r--WebCore/editing/SelectionController.cpp2
-rw-r--r--WebCore/editing/mac/EditorMac.mm105
-rw-r--r--WebCore/editing/markup.cpp453
-rw-r--r--WebCore/fileapi/DOMFileSystem.cpp1
-rw-r--r--WebCore/fileapi/Entry.idl2
-rw-r--r--WebCore/fileapi/ErrorCallback.h1
-rw-r--r--WebCore/fileapi/FileCallback.h51
-rw-r--r--WebCore/fileapi/FileCallback.idl38
-rw-r--r--WebCore/fileapi/FileWriterCallback.h52
-rw-r--r--WebCore/fileapi/FileWriterCallback.idl38
-rw-r--r--WebCore/fileapi/MetadataCallback.h1
-rw-r--r--WebCore/html/FTPDirectoryDocument.cpp (renamed from WebCore/loader/FTPDirectoryDocument.cpp)0
-rw-r--r--WebCore/html/FTPDirectoryDocument.h (renamed from WebCore/loader/FTPDirectoryDocument.h)0
-rw-r--r--WebCore/html/HTMLEmbedElement.cpp46
-rw-r--r--WebCore/html/HTMLEmbedElement.h6
-rw-r--r--WebCore/html/HTMLImageElement.cpp18
-rw-r--r--WebCore/html/HTMLInputElement.cpp28
-rw-r--r--WebCore/html/HTMLInputElement.h2
-rw-r--r--WebCore/html/HTMLLinkElement.cpp6
-rw-r--r--WebCore/html/HTMLMediaElement.cpp263
-rw-r--r--WebCore/html/HTMLMediaElement.h14
-rw-r--r--WebCore/html/HTMLObjectElement.cpp168
-rw-r--r--WebCore/html/HTMLObjectElement.h10
-rw-r--r--WebCore/html/HTMLPlugInImageElement.cpp58
-rw-r--r--WebCore/html/HTMLPlugInImageElement.h20
-rw-r--r--WebCore/html/HTMLSelectElement.cpp11
-rw-r--r--WebCore/html/HTMLSelectElement.h2
-rw-r--r--WebCore/html/HTMLViewSourceDocument.cpp12
-rw-r--r--WebCore/html/HTMLViewSourceDocument.h3
-rw-r--r--WebCore/html/ImageDocument.cpp (renamed from WebCore/loader/ImageDocument.cpp)6
-rw-r--r--WebCore/html/ImageDocument.h (renamed from WebCore/loader/ImageDocument.h)0
-rw-r--r--WebCore/html/MediaDocument.cpp (renamed from WebCore/loader/MediaDocument.cpp)2
-rw-r--r--WebCore/html/MediaDocument.h (renamed from WebCore/loader/MediaDocument.h)0
-rw-r--r--WebCore/html/PluginDocument.cpp (renamed from WebCore/loader/PluginDocument.cpp)0
-rw-r--r--WebCore/html/PluginDocument.h (renamed from WebCore/loader/PluginDocument.h)0
-rw-r--r--WebCore/html/TextDocument.cpp44
-rw-r--r--WebCore/html/TextDocument.h (renamed from WebCore/loader/TextDocument.h)6
-rw-r--r--WebCore/html/canvas/ArrayBufferView.cpp28
-rw-r--r--WebCore/html/canvas/ArrayBufferView.h4
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext.cpp12
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext.h13
-rwxr-xr-x[-rw-r--r--]WebCore/html/canvas/CanvasRenderingContext2D.cpp91
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.h26
-rw-r--r--WebCore/html/canvas/TypedArrayBase.h10
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.cpp5
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.h6
-rw-r--r--WebCore/html/parser/CSSPreloadScanner.cpp4
-rw-r--r--WebCore/html/parser/HTMLConstructionSite.cpp13
-rw-r--r--WebCore/html/parser/HTMLDocumentParser.cpp65
-rw-r--r--WebCore/html/parser/HTMLDocumentParser.h7
-rw-r--r--WebCore/html/parser/HTMLInputStream.h (renamed from WebCore/html/HTMLInputStream.h)0
-rw-r--r--WebCore/html/parser/HTMLPreloadScanner.cpp10
-rw-r--r--WebCore/html/parser/HTMLScriptRunner.cpp55
-rw-r--r--WebCore/html/parser/HTMLScriptRunner.h4
-rw-r--r--WebCore/html/parser/HTMLTokenizer.cpp4
-rw-r--r--WebCore/html/parser/HTMLTreeBuilder.cpp5
-rw-r--r--WebCore/html/parser/HTMLTreeBuilder.h2
-rw-r--r--WebCore/html/parser/HTMLViewSourceParser.h7
-rw-r--r--WebCore/html/parser/TextDocumentParser.cpp72
-rw-r--r--WebCore/html/parser/TextDocumentParser.h52
-rw-r--r--WebCore/html/parser/TextViewSourceParser.cpp43
-rw-r--r--WebCore/html/parser/TextViewSourceParser.h47
-rw-r--r--WebCore/inspector/CodeGeneratorInspector.pm2
-rw-r--r--WebCore/inspector/Inspector.idl5
-rw-r--r--WebCore/inspector/InspectorController.cpp62
-rw-r--r--WebCore/inspector/InspectorController.h67
-rw-r--r--WebCore/inspector/InspectorDOMAgent.cpp86
-rw-r--r--WebCore/inspector/InspectorDOMAgent.h8
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.cpp26
-rw-r--r--WebCore/inspector/InspectorDebuggerAgent.h3
-rw-r--r--WebCore/inspector/InspectorFrontendClient.h1
-rw-r--r--WebCore/inspector/InspectorFrontendHost.cpp8
-rw-r--r--WebCore/inspector/InspectorFrontendHost.h1
-rw-r--r--WebCore/inspector/InspectorFrontendHost.idl1
-rw-r--r--WebCore/inspector/InspectorResource.cpp6
-rw-r--r--WebCore/inspector/InspectorValues.h2
-rw-r--r--WebCore/inspector/front-end/BreakpointsSidebarPane.js12
-rw-r--r--WebCore/inspector/front-end/DOMAgent.js127
-rw-r--r--WebCore/inspector/front-end/ElementsPanel.js14
-rw-r--r--WebCore/inspector/front-end/ElementsTreeOutline.js18
-rw-r--r--WebCore/inspector/front-end/ExtensionServer.js12
-rw-r--r--WebCore/inspector/front-end/HAREntry.js6
-rw-r--r--WebCore/inspector/front-end/InspectorFrontendHostStub.js5
-rw-r--r--WebCore/inspector/front-end/Resource.js25
-rw-r--r--WebCore/inspector/front-end/Script.js3
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js12
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js4
-rw-r--r--WebCore/inspector/front-end/SourceView.js3
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc1
-rw-r--r--WebCore/inspector/front-end/heapProfiler.css136
-rw-r--r--WebCore/inspector/front-end/inspector.css109
-rw-r--r--WebCore/inspector/front-end/inspector.html1
-rw-r--r--WebCore/inspector/front-end/inspector.js8
-rw-r--r--WebCore/loader/Cache.cpp28
-rw-r--r--WebCore/loader/Cache.h14
-rw-r--r--WebCore/loader/CachedCSSStyleSheet.h2
-rw-r--r--WebCore/loader/CachedFont.cpp4
-rw-r--r--WebCore/loader/CachedFont.h6
-rw-r--r--WebCore/loader/CachedImage.cpp11
-rw-r--r--WebCore/loader/CachedImage.h4
-rw-r--r--WebCore/loader/CachedResource.cpp12
-rw-r--r--WebCore/loader/CachedResource.h10
-rw-r--r--WebCore/loader/CachedResourceLoader.cpp (renamed from WebCore/loader/DocLoader.cpp)70
-rw-r--r--WebCore/loader/CachedResourceLoader.h (renamed from WebCore/loader/DocLoader.h)12
-rw-r--r--WebCore/loader/CachedScript.h2
-rw-r--r--WebCore/loader/CachedXSLStyleSheet.h2
-rw-r--r--WebCore/loader/DocumentLoader.cpp12
-rw-r--r--WebCore/loader/EmptyClients.h10
-rw-r--r--WebCore/loader/FrameLoader.cpp31
-rw-r--r--WebCore/loader/FrameLoader.h6
-rw-r--r--WebCore/loader/FrameLoaderClient.h3
-rw-r--r--WebCore/loader/HistoryController.cpp20
-rw-r--r--WebCore/loader/ImageLoader.cpp14
-rw-r--r--WebCore/loader/PingLoader.cpp2
-rw-r--r--WebCore/loader/RedirectScheduler.cpp12
-rw-r--r--WebCore/loader/Request.cpp4
-rw-r--r--WebCore/loader/Request.h8
-rw-r--r--WebCore/loader/ResourceLoader.cpp8
-rw-r--r--WebCore/loader/SubframeLoader.cpp8
-rw-r--r--WebCore/loader/SubresourceLoader.cpp2
-rw-r--r--WebCore/loader/TextDocument.cpp219
-rw-r--r--WebCore/loader/loader.cpp92
-rw-r--r--WebCore/loader/loader.h10
-rw-r--r--WebCore/manual-tests/transition-accelerated.html46
-rw-r--r--WebCore/mathml/RenderMathMLOperator.cpp5
-rw-r--r--WebCore/mathml/RenderMathMLOperator.h9
-rw-r--r--WebCore/page/ChromeClient.h3
-rw-r--r--WebCore/page/ContextMenuController.cpp2
-rw-r--r--WebCore/page/DOMWindow.cpp12
-rw-r--r--WebCore/page/DOMWindow.h3
-rw-r--r--WebCore/page/DOMWindow.idl17
-rw-r--r--WebCore/page/DragController.cpp14
-rw-r--r--WebCore/page/EventHandler.cpp2
-rw-r--r--WebCore/page/FocusController.cpp2
-rw-r--r--WebCore/page/FocusController.h2
-rw-r--r--WebCore/page/Frame.cpp453
-rw-r--r--WebCore/page/Frame.h74
-rw-r--r--WebCore/page/FrameView.cpp44
-rw-r--r--WebCore/page/FrameView.h1
-rw-r--r--WebCore/page/Page.cpp8
-rw-r--r--WebCore/page/PageGroupLoadDeferrer.cpp13
-rw-r--r--WebCore/page/SecurityOrigin.cpp2
-rw-r--r--WebCore/page/SecurityOrigin.h9
-rw-r--r--WebCore/page/Settings.cpp4
-rw-r--r--WebCore/page/animation/AnimationBase.cpp31
-rw-r--r--WebCore/page/animation/KeyframeAnimation.cpp8
-rw-r--r--WebCore/page/mac/FrameMac.mm102
-rw-r--r--WebCore/platform/ScrollAnimator.cpp76
-rw-r--r--WebCore/platform/ScrollAnimator.h65
-rw-r--r--WebCore/platform/ScrollAnimatorWin.cpp296
-rw-r--r--WebCore/platform/ScrollAnimatorWin.h71
-rw-r--r--WebCore/platform/ScrollView.cpp25
-rw-r--r--WebCore/platform/ScrollView.h11
-rw-r--r--WebCore/platform/Scrollbar.cpp21
-rw-r--r--WebCore/platform/Scrollbar.h9
-rw-r--r--WebCore/platform/ScrollbarClient.cpp57
-rw-r--r--WebCore/platform/ScrollbarClient.h21
-rw-r--r--WebCore/platform/ScrollbarThemeComposite.cpp7
-rw-r--r--WebCore/platform/UUID.cpp7
-rw-r--r--WebCore/platform/android/TemporaryLinkStubs.cpp2
-rw-r--r--WebCore/platform/animation/Animation.cpp34
-rw-r--r--WebCore/platform/animation/Animation.h9
-rw-r--r--WebCore/platform/animation/TimingFunction.h123
-rw-r--r--WebCore/platform/audio/AudioArray.h71
-rw-r--r--WebCore/platform/audio/AudioBus.cpp363
-rw-r--r--WebCore/platform/audio/AudioBus.h139
-rw-r--r--WebCore/platform/audio/AudioChannel.cpp102
-rw-r--r--WebCore/platform/audio/AudioChannel.h112
-rw-r--r--WebCore/platform/audio/AudioDSPKernel.h65
-rw-r--r--WebCore/platform/audio/AudioDSPKernelProcessor.cpp116
-rw-r--r--WebCore/platform/audio/AudioDSPKernelProcessor.h76
-rw-r--r--WebCore/platform/audio/AudioProcessor.h75
-rw-r--r--WebCore/platform/audio/AudioSourceProvider.h46
-rw-r--r--WebCore/platform/audio/Biquad.cpp280
-rw-r--r--WebCore/platform/audio/Biquad.h99
-rw-r--r--WebCore/platform/audio/Distance.cpp93
-rw-r--r--WebCore/platform/audio/Distance.h80
-rw-r--r--WebCore/platform/audio/FFTFrame.cpp269
-rw-r--r--WebCore/platform/audio/FFTFrame.h102
-rw-r--r--WebCore/platform/audio/Panner.cpp71
-rw-r--r--WebCore/platform/audio/Panner.h69
-rw-r--r--WebCore/platform/audio/mac/FFTFrameMac.cpp191
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h3
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.cpp2
-rw-r--r--WebCore/platform/chromium/PasteboardChromium.cpp2
-rw-r--r--WebCore/platform/efl/ScrollbarEfl.cpp2
-rw-r--r--WebCore/platform/graphics/Font.cpp10
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp29
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h8
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h12
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp6
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h6
-rw-r--r--WebCore/platform/graphics/Path.cpp2
-rw-r--r--WebCore/platform/graphics/Path.h5
-rw-r--r--WebCore/platform/graphics/cairo/FontCacheCairo.cpp8
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp2
-rw-r--r--WebCore/platform/graphics/cairo/OwnPtrCairo.cpp (renamed from WebCore/platform/graphics/cairo/GOwnPtrCairo.cpp)8
-rw-r--r--WebCore/platform/graphics/cairo/OwnPtrCairo.h (renamed from WebCore/platform/graphics/cairo/GOwnPtrCairo.h)12
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp1
-rw-r--r--WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp112
-rw-r--r--WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h65
-rw-r--r--WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp43
-rw-r--r--WebCore/platform/graphics/chromium/CanvasLayerChromium.h28
-rw-r--r--WebCore/platform/graphics/chromium/ContentLayerChromium.cpp35
-rw-r--r--WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp142
-rw-r--r--WebCore/platform/graphics/chromium/FontChromiumWin.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp33
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.cpp166
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.h29
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp13
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.h2
-rw-r--r--WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp10
-rw-r--r--WebCore/platform/graphics/chromium/ImageLayerChromium.cpp10
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp18
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.cpp7
-rw-r--r--WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp85
-rw-r--r--WebCore/platform/graphics/chromium/WebGLLayerChromium.h60
-rw-r--r--WebCore/platform/graphics/gpu/DrawingBuffer.cpp60
-rw-r--r--WebCore/platform/graphics/gpu/DrawingBuffer.h84
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnClassifier.cpp122
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnClassifier.h84
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnConstants.h40
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp565
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h108
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.cpp171
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.h82
-rw-r--r--WebCore/platform/graphics/gpu/PODArena.h211
-rw-r--r--WebCore/platform/graphics/gpu/PODInterval.h155
-rw-r--r--WebCore/platform/graphics/gpu/PODIntervalTree.h217
-rw-r--r--WebCore/platform/graphics/gpu/PODRedBlackTree.h750
-rw-r--r--WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp296
-rw-r--r--WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h124
-rw-r--r--WebCore/platform/graphics/gpu/Texture.cpp68
-rw-r--r--WebCore/platform/graphics/gpu/Texture.h3
-rw-r--r--WebCore/platform/graphics/gpu/TilingData.h1
-rw-r--r--WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp3
-rw-r--r--WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h3
-rw-r--r--WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp2
-rw-r--r--WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h2
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.h3
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm3
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp6
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp36
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp3
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp3
-rw-r--r--WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp2
-rw-r--r--WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h3
-rw-r--r--WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp3
-rw-r--r--WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h2
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.mm31
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm43
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.cpp37
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp8
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h1
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp30
-rw-r--r--WebCore/platform/graphics/skia/FontCustomPlatformData.cpp (renamed from WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp)0
-rw-r--r--WebCore/platform/graphics/skia/FontCustomPlatformData.h (renamed from WebCore/platform/graphics/chromium/FontCustomPlatformData.h)0
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp29
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp22
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp5
-rwxr-xr-x[-rw-r--r--]WebCore/platform/graphics/skia/PlatformContextSkia.cpp139
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h28
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp56
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp3
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/IconWin.cpp8
-rwxr-xr-xWebCore/platform/graphics/win/LocalWindowsContext.h61
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp1
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp5
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.cpp2
-rw-r--r--WebCore/platform/gtk/GeolocationServiceGtk.cpp2
-rw-r--r--WebCore/platform/gtk/GeolocationServiceGtk.h2
-rw-r--r--WebCore/platform/gtk/MainFrameScrollbarGtk.cpp118
-rw-r--r--WebCore/platform/gtk/MainFrameScrollbarGtk.h52
-rw-r--r--WebCore/platform/gtk/PasteboardGtk.cpp2
-rw-r--r--WebCore/platform/gtk/ScrollViewGtk.cpp106
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.cpp253
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.h71
-rw-r--r--WebCore/platform/gtk/ScrollbarThemeGtk.cpp66
-rw-r--r--WebCore/platform/gtk/ScrollbarThemeGtk.h2
-rw-r--r--WebCore/platform/gtk/gtk2drawing.c2
-rw-r--r--WebCore/platform/gtk/gtkdrawing.h2
-rw-r--r--WebCore/platform/network/FormData.cpp2
-rw-r--r--WebCore/platform/network/android/ResourceHandleAndroid.cpp8
-rw-r--r--WebCore/platform/network/cf/ResourceHandleCFNet.cpp2
-rw-r--r--WebCore/platform/network/curl/ResourceHandleCurl.cpp2
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp3
-rw-r--r--WebCore/platform/network/curl/ResourceRequest.h5
-rw-r--r--WebCore/platform/network/curl/ResourceResponse.h5
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm2
-rw-r--r--WebCore/platform/network/qt/ResourceHandleQt.cpp2
-rw-r--r--WebCore/platform/network/qt/ResourceRequestQt.cpp5
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp2
-rw-r--r--WebCore/platform/network/soup/SocketStreamHandle.h13
-rw-r--r--WebCore/platform/network/soup/SocketStreamHandleSoup.cpp209
-rw-r--r--WebCore/platform/network/win/ResourceHandleWin.cpp2
-rw-r--r--WebCore/platform/qt/ClipboardQt.cpp2
-rw-r--r--WebCore/platform/qt/PasteboardQt.cpp2
-rw-r--r--WebCore/platform/qt/ScrollbarQt.cpp6
-rw-r--r--WebCore/platform/text/CharacterNames.h1
-rw-r--r--WebCore/platform/text/wince/TextCodecWinCE.cpp86
-rw-r--r--WebCore/platform/win/ClipboardWin.cpp2
-rw-r--r--WebCore/platform/win/PasteboardWin.cpp2
-rw-r--r--WebCore/platform/win/PopupMenuWin.cpp15
-rw-r--r--WebCore/platform/win/PopupMenuWin.h2
-rw-r--r--WebCore/platform/win/ScrollbarThemeWin.cpp16
-rw-r--r--WebCore/plugins/PluginDatabase.cpp2
-rw-r--r--WebCore/plugins/PluginPackage.cpp7
-rw-r--r--WebCore/plugins/PluginView.cpp6
-rw-r--r--WebCore/plugins/gtk/PluginViewGtk.cpp10
-rw-r--r--WebCore/plugins/qt/PluginViewQt.cpp7
-rw-r--r--WebCore/plugins/win/PluginViewWin.cpp16
-rw-r--r--WebCore/rendering/ColumnInfo.h64
-rw-r--r--WebCore/rendering/InlineTextBox.cpp2
-rw-r--r--WebCore/rendering/RenderBlock.cpp164
-rw-r--r--WebCore/rendering/RenderBlock.h4
-rw-r--r--WebCore/rendering/RenderDataGrid.cpp11
-rw-r--r--WebCore/rendering/RenderDataGrid.h2
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.cpp278
-rw-r--r--WebCore/rendering/RenderEmbeddedObject.h3
-rw-r--r--WebCore/rendering/RenderIndicator.cpp21
-rw-r--r--WebCore/rendering/RenderIndicator.h5
-rw-r--r--WebCore/rendering/RenderLayer.cpp35
-rw-r--r--WebCore/rendering/RenderLayer.h2
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp17
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp2
-rw-r--r--WebCore/rendering/RenderListBox.cpp15
-rw-r--r--WebCore/rendering/RenderListBox.h2
-rw-r--r--WebCore/rendering/RenderObject.h7
-rw-r--r--WebCore/rendering/RenderSVGAllInOne.cpp1
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.cpp6
-rw-r--r--WebCore/rendering/RenderSVGResourceFilterPrimitive.cpp41
-rw-r--r--WebCore/rendering/RenderSVGResourceFilterPrimitive.h49
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp12
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.cpp2
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp26
-rw-r--r--WebCore/rendering/RenderTextFragment.cpp8
-rw-r--r--WebCore/rendering/RenderThemeChromiumWin.cpp12
-rw-r--r--WebCore/rendering/RenderThemeWin.cpp7
-rw-r--r--WebCore/rendering/RenderView.cpp2
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp3
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp6
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h2
-rw-r--r--WebCore/storage/DatabaseAuthorizer.cpp4
-rw-r--r--WebCore/storage/IDBAny.cpp11
-rw-r--r--WebCore/storage/IDBAny.h14
-rw-r--r--WebCore/storage/IDBCursor.cpp13
-rw-r--r--WebCore/storage/IDBCursor.h24
-rw-r--r--WebCore/storage/IDBCursor.idl2
-rw-r--r--WebCore/storage/IDBDatabaseBackendImpl.cpp2
-rw-r--r--WebCore/storage/IDBFactoryBackendImpl.cpp17
-rw-r--r--WebCore/storage/IDBIndex.idl9
-rw-r--r--WebCore/storage/IDBIndexBackendImpl.cpp27
-rw-r--r--WebCore/storage/IDBIndexBackendImpl.h4
-rw-r--r--WebCore/storage/IDBKey.cpp58
-rw-r--r--WebCore/storage/IDBKey.h5
-rw-r--r--WebCore/storage/IDBKeyRange.idl9
-rw-r--r--WebCore/storage/IDBObjectStore.idl4
-rwxr-xr-xWebCore/storage/IDBObjectStoreBackendImpl.cpp202
-rw-r--r--WebCore/storage/IDBObjectStoreBackendImpl.h3
-rw-r--r--WebCore/storage/IDBRequest.cpp78
-rw-r--r--WebCore/storage/IDBRequest.h15
-rw-r--r--WebCore/storage/IDBRequest.idl5
-rw-r--r--WebCore/storage/IDBTransaction.h3
-rw-r--r--WebCore/storage/IDBTransaction.idl2
-rw-r--r--WebCore/svg/SVGAnimateMotionElement.cpp7
-rw-r--r--WebCore/svg/SVGDocumentExtensions.cpp8
-rw-r--r--WebCore/svg/SVGDocumentExtensions.h7
-rw-r--r--WebCore/svg/SVGElement.cpp6
-rw-r--r--WebCore/svg/SVGFEDiffuseLightingElement.cpp2
-rw-r--r--WebCore/svg/SVGFEImageElement.cpp4
-rw-r--r--WebCore/svg/SVGFELightElement.cpp19
-rw-r--r--WebCore/svg/SVGFEOffsetElement.cpp2
-rw-r--r--WebCore/svg/SVGFilterElement.h16
-rw-r--r--WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp10
-rw-r--r--WebCore/svg/SVGFilterPrimitiveStandardAttributes.h10
-rw-r--r--WebCore/svg/SVGFontFaceUriElement.cpp8
-rw-r--r--WebCore/svg/SVGUseElement.cpp17
-rw-r--r--WebCore/thirdparty/README.txt12
-rw-r--r--WebCore/thirdparty/glu/LICENSE.txt31
-rw-r--r--WebCore/thirdparty/glu/README.webkit33
-rw-r--r--WebCore/thirdparty/glu/gluos.h45
-rw-r--r--WebCore/thirdparty/glu/internal_glu.h141
-rw-r--r--WebCore/thirdparty/glu/libtess/GNUmakefile110
-rw-r--r--WebCore/thirdparty/glu/libtess/Imakefile61
-rw-r--r--WebCore/thirdparty/glu/libtess/README447
-rw-r--r--WebCore/thirdparty/glu/libtess/alg-outline229
-rw-r--r--WebCore/thirdparty/glu/libtess/dict-list.h107
-rw-r--r--WebCore/thirdparty/glu/libtess/dict.c117
-rw-r--r--WebCore/thirdparty/glu/libtess/dict.h107
-rw-r--r--WebCore/thirdparty/glu/libtess/geom.c271
-rw-r--r--WebCore/thirdparty/glu/libtess/geom.h90
-rw-r--r--WebCore/thirdparty/glu/libtess/memalloc.c62
-rw-r--r--WebCore/thirdparty/glu/libtess/memalloc.h61
-rw-r--r--WebCore/thirdparty/glu/libtess/mesh.c796
-rw-r--r--WebCore/thirdparty/glu/libtess/mesh.h273
-rw-r--r--WebCore/thirdparty/glu/libtess/normal.c259
-rw-r--r--WebCore/thirdparty/glu/libtess/normal.h52
-rw-r--r--WebCore/thirdparty/glu/libtess/priorityq-heap.c260
-rw-r--r--WebCore/thirdparty/glu/libtess/priorityq-heap.h114
-rw-r--r--WebCore/thirdparty/glu/libtess/priorityq-sort.h124
-rw-r--r--WebCore/thirdparty/glu/libtess/priorityq.c267
-rw-r--r--WebCore/thirdparty/glu/libtess/priorityq.h124
-rw-r--r--WebCore/thirdparty/glu/libtess/render.c505
-rw-r--r--WebCore/thirdparty/glu/libtess/render.h59
-rw-r--r--WebCore/thirdparty/glu/libtess/sweep.c1359
-rw-r--r--WebCore/thirdparty/glu/libtess/sweep.h84
-rw-r--r--WebCore/thirdparty/glu/libtess/tess.c639
-rw-r--r--WebCore/thirdparty/glu/libtess/tess.h173
-rw-r--r--WebCore/thirdparty/glu/libtess/tessmono.c209
-rw-r--r--WebCore/thirdparty/glu/libtess/tessmono.h78
-rw-r--r--WebCore/webaudio/AudioBuffer.cpp110
-rw-r--r--WebCore/webaudio/AudioBuffer.h81
-rw-r--r--WebCore/webaudio/AudioBuffer.idl43
-rw-r--r--WebCore/webaudio/AudioListener.cpp51
-rw-r--r--WebCore/webaudio/AudioListener.h94
-rw-r--r--WebCore/webaudio/AudioListener.idl40
-rw-r--r--WebCore/webaudio/AudioParam.h115
-rw-r--r--WebCore/webaudio/AudioParam.idl43
-rw-r--r--WebCore/webaudio/AudioSourceNode.h46
-rw-r--r--WebCore/webaudio/AudioSourceNode.idl34
-rw-r--r--WebCore/websockets/WebSocketChannel.cpp3
-rw-r--r--WebCore/wml/WMLDocument.h2
-rw-r--r--WebCore/wml/WMLFormControlElement.h7
-rw-r--r--WebCore/wml/WMLImageElement.cpp5
-rw-r--r--WebCore/wml/WMLInputElement.h1
-rw-r--r--WebCore/wml/WMLIntrinsicEvent.cpp5
-rw-r--r--WebCore/wml/WMLIntrinsicEvent.h4
-rw-r--r--WebCore/wml/WMLSelectElement.cpp3
-rw-r--r--WebCore/wml/WMLSelectElement.h2
-rw-r--r--WebCore/wml/WMLTaskElement.cpp5
-rw-r--r--WebCore/wml/WMLTaskElement.h8
-rw-r--r--WebCore/workers/Worker.cpp2
-rw-r--r--WebCore/workers/WorkerMessagingProxy.cpp4
-rw-r--r--WebCore/xml/XSLImportRule.cpp8
-rw-r--r--WebCore/xml/XSLStyleSheet.h4
-rw-r--r--WebCore/xml/XSLStyleSheetLibxslt.cpp8
-rw-r--r--WebCore/xml/XSLStyleSheetQt.cpp4
-rw-r--r--WebCore/xml/XSLTProcessor.cpp2
-rw-r--r--WebCore/xml/XSLTProcessorLibxslt.cpp28
-rw-r--r--WebKit/ChangeLog9
-rw-r--r--WebKit/WebKit.xcodeproj/project.pbxproj36
-rw-r--r--WebKit/chromium/ChangeLog434
-rw-r--r--WebKit/chromium/DEPS2
-rw-r--r--WebKit/chromium/WebKit.gyp6
-rw-r--r--WebKit/chromium/public/WebAccessibilityObject.h5
-rw-r--r--WebKit/chromium/public/WebDevToolsAgentClient.h3
-rw-r--r--WebKit/chromium/public/WebDeviceOrientationClientMock.h3
-rw-r--r--WebKit/chromium/public/WebGeolocationServiceBridge.h4
-rw-r--r--WebKit/chromium/public/WebKit.h5
-rw-r--r--WebKit/chromium/public/WebKitClient.h3
-rw-r--r--WebKit/chromium/public/WebSpeechInputController.h5
-rw-r--r--WebKit/chromium/public/WebVector.h12
-rw-r--r--WebKit/chromium/src/ChromeClientImpl.cpp11
-rw-r--r--WebKit/chromium/src/ChromeClientImpl.h5
-rw-r--r--WebKit/chromium/src/ChromiumBridge.cpp5
-rw-r--r--WebKit/chromium/src/ContextMenuClientImpl.cpp6
-rw-r--r--WebKit/chromium/src/DebuggerAgentImpl.cpp1
-rw-r--r--WebKit/chromium/src/FrameLoaderClientImpl.cpp6
-rw-r--r--WebKit/chromium/src/FrameLoaderClientImpl.h2
-rw-r--r--WebKit/chromium/src/GraphicsContext3D.cpp21
-rw-r--r--WebKit/chromium/src/InspectorFrontendClientImpl.cpp5
-rw-r--r--WebKit/chromium/src/InspectorFrontendClientImpl.h1
-rw-r--r--WebKit/chromium/src/WebAccessibilityObject.cpp45
-rw-r--r--WebKit/chromium/src/WebDevToolsAgentImpl.cpp5
-rw-r--r--WebKit/chromium/src/WebDevToolsAgentImpl.h2
-rw-r--r--WebKit/chromium/src/WebDeviceOrientationClientMock.cpp6
-rw-r--r--WebKit/chromium/src/WebFrameImpl.cpp8
-rw-r--r--WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp5
-rw-r--r--WebKit/chromium/src/WebIDBCallbacksImpl.cpp8
-rw-r--r--WebKit/chromium/src/WebKit.cpp5
-rw-r--r--WebKit/chromium/src/WebScrollbarImpl.cpp14
-rw-r--r--WebKit/chromium/src/WebScrollbarImpl.h2
-rw-r--r--WebKit/chromium/src/WebViewImpl.cpp35
-rw-r--r--WebKit/chromium/src/WebViewImpl.h6
-rw-r--r--WebKit/chromium/src/js/Tests.js239
-rw-r--r--[-rwxr-xr-x]WebKit/chromium/src/js/devTools.css0
-rw-r--r--WebKit/chromium/src/mac/WebInputEventFactory.mm21
-rw-r--r--WebKit/chromium/src/win/WebInputEventFactory.cpp3
-rw-r--r--WebKit/chromium/tests/ArenaTestHelpers.h78
-rw-r--r--WebKit/chromium/tests/PODArenaTest.cpp106
-rw-r--r--WebKit/chromium/tests/PODIntervalTreeTest.cpp323
-rw-r--r--WebKit/chromium/tests/PODRedBlackTreeTest.cpp213
-rw-r--r--WebKit/chromium/tests/TreeTestHelpers.cpp60
-rw-r--r--WebKit/chromium/tests/TreeTestHelpers.h53
-rw-r--r--WebKit/efl/CMakeListsEfl.txt62
-rw-r--r--WebKit/efl/ChangeLog135
-rw-r--r--WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp6
-rw-r--r--WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h2
-rw-r--r--WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h54
-rw-r--r--WebKit/efl/ewebkit.pc.in3
-rw-r--r--WebKit/efl/ewk/ewk_frame.cpp14
-rw-r--r--WebKit/efl/ewk/ewk_view.cpp2
-rw-r--r--WebKit/gtk/ChangeLog87
-rw-r--r--WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp6
-rw-r--r--WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h3
-rw-r--r--WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp14
-rw-r--r--WebKit/gtk/WebCoreSupport/InspectorClientGtk.h3
-rw-r--r--WebKit/gtk/tests/testatk.c78
-rw-r--r--WebKit/gtk/tests/testmimehandling.c4
-rw-r--r--WebKit/gtk/webkit/webkitprivate.h2
-rw-r--r--WebKit/gtk/webkit/webkitsoupauthdialog.c2
-rw-r--r--WebKit/gtk/webkit/webkitwebview.cpp6
-rw-r--r--WebKit/mac/ChangeLog242
-rw-r--r--WebKit/mac/Configurations/Base.xcconfig4
-rw-r--r--WebKit/mac/Configurations/Version.xcconfig2
-rw-r--r--WebKit/mac/Misc/WebCoreStatistics.mm6
-rw-r--r--WebKit/mac/Misc/WebLocalizableStrings.h2
-rw-r--r--WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm2
-rw-r--r--WebKit/mac/Plugins/WebNetscapePluginStream.mm2
-rw-r--r--WebKit/mac/Plugins/WebNetscapePluginView.mm2
-rw-r--r--WebKit/mac/Plugins/WebPluginContainerCheck.mm2
-rw-r--r--WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.h57
-rw-r--r--WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm71
-rw-r--r--WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h2
-rw-r--r--WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm6
-rw-r--r--WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm29
-rw-r--r--WebKit/mac/WebCoreSupport/WebInspectorClient.h1
-rw-r--r--WebKit/mac/WebCoreSupport/WebInspectorClient.mm21
-rw-r--r--WebKit/mac/WebKit.exp2
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientation.h35
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientation.mm78
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientationInternal.h45
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientationProvider.h32
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientationProviderMock.h38
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientationProviderMock.mm116
-rw-r--r--WebKit/mac/WebView/WebDeviceOrientationProviderMockInternal.h48
-rw-r--r--WebKit/mac/WebView/WebFrame.mm46
-rw-r--r--WebKit/mac/WebView/WebFramePrivate.h3
-rw-r--r--WebKit/mac/WebView/WebHTMLRepresentation.mm2
-rw-r--r--WebKit/mac/WebView/WebHTMLView.mm12
-rw-r--r--WebKit/mac/WebView/WebUIDelegatePrivate.h8
-rw-r--r--WebKit/mac/WebView/WebView.mm36
-rw-r--r--WebKit/mac/WebView/WebViewData.h2
-rw-r--r--WebKit/mac/WebView/WebViewPrivate.h7
-rw-r--r--WebKit/qt/Api/qwebframe.cpp2
-rw-r--r--WebKit/qt/Api/qwebpage.cpp4
-rw-r--r--WebKit/qt/ChangeLog131
-rw-r--r--WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp2
-rw-r--r--WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp7
-rw-r--r--WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h4
-rw-r--r--WebKit/qt/WebCoreSupport/FrameNetworkingContextQt.cpp36
-rw-r--r--WebKit/qt/WebCoreSupport/InspectorClientQt.cpp60
-rw-r--r--WebKit/qt/WebCoreSupport/InspectorClientQt.h7
-rw-r--r--WebKit/qt/tests/qwebframe/tst_qwebframe.cpp74
-rw-r--r--WebKit/win/ChangeLog139
-rw-r--r--WebKit/win/FullscreenVideoController.cpp3
-rw-r--r--WebKit/win/Interfaces/WebKit.idl1
-rw-r--r--WebKit/win/WebCoreSupport/WebChromeClient.cpp11
-rw-r--r--WebKit/win/WebCoreSupport/WebContextMenuClient.cpp2
-rw-r--r--WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp22
-rw-r--r--WebKit/win/WebCoreSupport/WebInspectorClient.cpp21
-rw-r--r--WebKit/win/WebCoreSupport/WebInspectorClient.h3
-rw-r--r--WebKit/win/WebDataSource.cpp4
-rw-r--r--WebKit/win/WebFrame.cpp9
-rw-r--r--WebKit/win/WebFrame.h2
-rw-r--r--WebKit/win/WebScrollBar.cpp12
-rw-r--r--WebKit/win/WebScrollBar.h2
-rw-r--r--WebKit/win/WebView.cpp12
-rw-r--r--WebKit/wx/ChangeLog11
-rw-r--r--WebKit/wx/WebFrame.cpp2
-rw-r--r--WebKitTools/CMakeListsEfl.txt56
-rw-r--r--WebKitTools/ChangeLog891
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityTextMarker.cpp134
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityTextMarker.h105
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp98
-rw-r--r--WebKitTools/DumpRenderTree/AccessibilityUIElement.h11
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.gypi2
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.sln9
-rw-r--r--WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj12
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp4
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp20
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h22
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.cpp10
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.h15
-rw-r--r--WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp3
-rw-r--r--WebKitTools/DumpRenderTree/chromium/EventSender.cpp35
-rw-r--r--WebKitTools/DumpRenderTree/chromium/EventSender.h6
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp47
-rw-r--r--WebKitTools/DumpRenderTree/chromium/LayoutTestController.h28
-rw-r--r--WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp13
-rw-r--r--WebKitTools/DumpRenderTree/chromium/Task.cpp72
-rw-r--r--WebKitTools/DumpRenderTree/chromium/Task.h83
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.cpp12
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShell.h1
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShellMac.mm6
-rw-r--r--WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp88
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/chromium/WebViewHost.h2
-rw-r--r--WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp88
-rw-r--r--WebKitTools/DumpRenderTree/gtk/EventSender.cpp42
-rw-r--r--WebKitTools/DumpRenderTree/gtk/ImageDiff.cpp11
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityTextMarkerMac.mm81
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm67
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm2
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm12
-rw-r--r--WebKitTools/DumpRenderTree/mac/ObjCController.m19
-rw-r--r--WebKitTools/DumpRenderTree/mac/TextInputController.m11
-rw-r--r--WebKitTools/DumpRenderTree/qt/ImageDiff.cpp5
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj8
-rw-r--r--WebKitTools/EWebLauncher/main.c (renamed from WebKit/efl/EWebLauncher/main.c)0
-rw-r--r--WebKitTools/GNUmakefile.am2
-rw-r--r--WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m2
-rw-r--r--WebKitTools/MiniBrowser/qt/BrowserView.cpp75
-rw-r--r--WebKitTools/MiniBrowser/qt/BrowserView.h54
-rw-r--r--WebKitTools/MiniBrowser/qt/BrowserWindow.cpp56
-rw-r--r--WebKitTools/MiniBrowser/qt/BrowserWindow.h30
-rw-r--r--WebKitTools/MiniBrowser/qt/MiniBrowser.pro2
-rw-r--r--WebKitTools/MiniBrowser/qt/main.cpp12
-rw-r--r--WebKitTools/MiniBrowser/win/BrowserWindow.cpp4
-rw-r--r--WebKitTools/Scripts/VCSUtils.pm8
-rwxr-xr-xWebKitTools/Scripts/do-webcore-rename2
-rwxr-xr-xWebKitTools/Scripts/svn-apply2
-rwxr-xr-xWebKitTools/Scripts/validate-committer-lists2
-rw-r--r--WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl49
-rw-r--r--WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnProperty.pl100
-rw-r--r--WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnPropertyValue.pl59
-rw-r--r--WebKitTools/Scripts/webkitpy/common/config/committers.py22
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html1
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py33
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py49
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py42
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread_unittest.py49
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py50
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/base.py119
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py135
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py45
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py20
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py10
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py10
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py56
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf2
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py23
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py88
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py6
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py11
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/test.py10
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py89
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py68
-rwxr-xr-xWebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py51
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py50
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queries.py26
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queries_unittest.py10
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py26
-rwxr-xr-xWebKitTools/Scripts/webkitpy/tool/main.py2
-rw-r--r--WebKitTools/Scripts/webkitpy/tool/mocktool.py19
-rwxr-xr-xWebKitTools/TestResultServer/model/datastorefile.py31
-rwxr-xr-xWebKitTools/TestResultServer/model/jsonresults.py1
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp13
-rw-r--r--WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h4
950 files changed, 42549 insertions, 8983 deletions
diff --git a/ANGLE/ANGLE.xcodeproj/project.pbxproj b/ANGLE/ANGLE.xcodeproj/project.pbxproj
index 67b6c3f..95f41c3 100644
--- a/ANGLE/ANGLE.xcodeproj/project.pbxproj
+++ b/ANGLE/ANGLE.xcodeproj/project.pbxproj
@@ -35,7 +35,6 @@
FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */; };
FB39D7231201032000088E69 /* glslang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D7201201032000088E69 /* glslang.cpp */; };
FB39D7241201032000088E69 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D7221201032000088E69 /* glslang_tab.cpp */; };
- FB39D76D120110FC00088E69 /* ResourceLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = FB39D2BE1200F3E600088E69 /* ResourceLimits.h */; settings = {ATTRIBUTES = (Public, ); }; };
FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */ = {isa = PBXBuildFile; fileRef = FB39D2BF1200F3E600088E69 /* ShaderLang.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
@@ -177,7 +176,6 @@
FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; };
FB39D26E1200F35A00088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = UnfoldSelect.h; sourceTree = "<group>"; };
FB39D26F1200F35A00088E69 /* unistd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
- FB39D2BE1200F3E600088E69 /* ResourceLimits.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ResourceLimits.h; sourceTree = "<group>"; };
FB39D2BF1200F3E600088E69 /* ShaderLang.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ShaderLang.h; sourceTree = "<group>"; };
FB39D7201201032000088E69 /* glslang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = glslang.cpp; path = DerivedSources/ANGLE/glslang.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
FB39D7211201032000088E69 /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glslang_tab.h; path = DerivedSources/ANGLE/glslang_tab.h; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -413,7 +411,6 @@
FB39D2BD1200F3E600088E69 /* GLSLANG */ = {
isa = PBXGroup;
children = (
- FB39D2BE1200F3E600088E69 /* ResourceLimits.h */,
FB39D2BF1200F3E600088E69 /* ShaderLang.h */,
);
name = GLSLANG;
@@ -427,7 +424,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- FB39D76D120110FC00088E69 /* ResourceLimits.h in Headers */,
FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -461,7 +457,6 @@
isa = PBXProject;
buildConfigurationList = FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "ANGLE" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
diff --git a/ANGLE/ChangeLog b/ANGLE/ChangeLog
index 44234a8..e886a42 100644
--- a/ANGLE/ChangeLog
+++ b/ANGLE/ChangeLog
@@ -1,3 +1,461 @@
+2010-09-01 Zhenyao Mo <zmo@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Roll ANGLE under webkit to r402
+ https://bugs.webkit.org/show_bug.cgi?id=45004
+
+ * ANGLE.xcodeproj/project.pbxproj:
+ * include/GLES2/gl2ext.h:
+ * include/GLSLANG/ResourceLimits.h: Removed.
+ * include/GLSLANG/ShaderLang.h:
+ * src/compiler/BaseTypes.h:
+ (getPrecisionString):
+ (getBasicString):
+ (IsSampler):
+ (getQualifierString):
+ * src/compiler/Initialize.cpp:
+ (BuiltInConstants):
+ (IdentifyBuiltIns):
+ * src/compiler/Initialize.h:
+ * src/compiler/InitializeDll.cpp:
+ (InitProcess):
+ (DetachProcess):
+ (InitThread):
+ (DetachThread):
+ * src/compiler/InitializeDll.h:
+ * src/compiler/InitializeParseContext.h:
+ * src/compiler/Intermediate.cpp:
+ (GetHigherPrecision):
+ (TIntermediate::addBinaryMath):
+ (TIntermediate::setAggregateOperator):
+ (TIntermediate::addComma):
+ (TIntermediate::postProcess):
+ (TIntermBinary::promote):
+ (CompareStruct):
+ * src/compiler/OutputGLSL.cpp:
+ (TOutputGLSL::writeFunctionParameters):
+ (TOutputGLSL::visitUnary):
+ (TOutputGLSL::visitBranch):
+ * src/compiler/OutputHLSL.cpp:
+ (sh::OutputHLSL::header):
+ (sh::OutputHLSL::visitBinary):
+ (sh::OutputHLSL::visitAggregate):
+ (sh::OutputHLSL::handleExcessiveLoop):
+ (sh::OutputHLSL::addConstructor):
+ * src/compiler/ParseHelper.cpp:
+ (TParseContext::constructorErrorCheck):
+ (TParseContext::samplerErrorCheck):
+ (TParseContext::paramErrorCheck):
+ (TParseContext::findFunction):
+ (TParseContext::executeInitializer):
+ (TParseContext::addConstructor):
+ (TParseContext::addConstStruct):
+ (FreeParseContextIndex):
+ (GetGlobalParseContext):
+ * src/compiler/PoolAlloc.h:
+ (TPoolAllocator::tHeader::tHeader):
+ (pool_allocator::allocate):
+ (pool_allocator::deallocate):
+ * src/compiler/ShaderLang.cpp:
+ (ShInitialize):
+ (ShFinalize):
+ (ShInitBuiltInResource):
+ * src/compiler/SymbolTable.cpp:
+ (TType::getStructSize):
+ * src/compiler/SymbolTable.h:
+ (TVariable::setQualifier):
+ * src/compiler/Types.h:
+ (TType::TType):
+ (TType::getBasicType):
+ (TType::setBasicType):
+ (TType::getPrecision):
+ (TType::setPrecision):
+ (TType::getQualifier):
+ (TType::setQualifier):
+ (TType::getNominalSize):
+ (TType::setNominalSize):
+ (TType::isMatrix):
+ (TType::setMatrix):
+ (TType::isArray):
+ (TType::getArraySize):
+ (TType::setArraySize):
+ (TType::getMaxArraySize):
+ (TType::setMaxArraySize):
+ (TType::clearArrayness):
+ (TType::setArrayInformationType):
+ (TType::getArrayInformationType):
+ (TType::isVector):
+ (TType::isScalar):
+ (TType::setStruct):
+ (TType::getTypeName):
+ (TType::setTypeName):
+ (TType::isField):
+ (TType::getFieldName):
+ (TType::setFieldName):
+ (TType::getBasicString):
+ (TType::getPrecisionString):
+ (TType::getQualifierString):
+ * src/compiler/glslang.l:
+ * src/compiler/glslang.y:
+ * src/compiler/intermediate.h:
+ (TIntermNode::getLine):
+ (TIntermNode::setLine):
+ (TIntermTyped::getAsTyped):
+ (TIntermTyped::setType):
+ (TIntermTyped::getType):
+ (TIntermTyped::getTypePointer):
+ (TIntermTyped::getBasicType):
+ (TIntermTyped::getQualifier):
+ (TIntermTyped::getPrecision):
+ (TIntermTyped::getNominalSize):
+ (TIntermTyped::isMatrix):
+ (TIntermTyped::isArray):
+ (TIntermTyped::isVector):
+ (TIntermTyped::isScalar):
+ (TIntermTyped::getBasicString):
+ (TIntermTyped::getQualifierString):
+ (TIntermSymbol::getId):
+ (TIntermSymbol::getSymbol):
+ (TIntermOperator::setOp):
+ (TIntermBinary::setLeft):
+ (TIntermBinary::setRight):
+ (TIntermBinary::getLeft):
+ (TIntermBinary::getRight):
+ (TIntermUnary::setOperand):
+ (TIntermUnary::getOperand):
+ (TIntermAggregate::getAsAggregate):
+ (TIntermAggregate::getSequence):
+ (TIntermAggregate::setName):
+ (TIntermAggregate::getName):
+ (TIntermAggregate::setUserDefined):
+ (TIntermAggregate::isUserDefined):
+ (TIntermAggregate::getQualifier):
+ (TIntermAggregate::setOptimize):
+ (TIntermAggregate::setDebug):
+ (TIntermSelection::getCondition):
+ (TIntermSelection::getTrueBlock):
+ (TIntermSelection::getFalseBlock):
+ (TIntermSelection::getAsSelectionNode):
+ * src/compiler/parseConst.cpp:
+ (TConstTraverser::TConstTraverser):
+ * src/compiler/preprocessor/atom.c:
+ (InitAtomTable):
+ * src/compiler/preprocessor/atom.h:
+ * src/compiler/preprocessor/compile.h:
+ * src/compiler/preprocessor/cpp.c:
+ * src/compiler/preprocessor/cpp.h:
+ * src/compiler/preprocessor/cppstruct.c:
+ * src/compiler/preprocessor/memory.c:
+ * src/compiler/preprocessor/memory.h:
+ * src/compiler/preprocessor/parser.h:
+ * src/compiler/preprocessor/preprocess.h:
+ * src/compiler/preprocessor/scanner.c:
+ * src/compiler/preprocessor/scanner.h:
+ * src/compiler/preprocessor/slglobals.h:
+ * src/compiler/preprocessor/symbols.c:
+ (NewSymbol):
+ * src/compiler/preprocessor/symbols.h:
+ * src/compiler/preprocessor/tokens.c:
+ (RecordToken):
+ * src/compiler/preprocessor/tokens.h:
+ * src/libEGL/Display.cpp:
+ (egl::Display::Display):
+ (egl::Display::initialize):
+ (egl::Display::terminate):
+ (egl::Display::createDevice):
+ (egl::Display::createWindowSurface):
+ (egl::Display::createContext):
+ (egl::Display::getMultiSampleSupport):
+ (egl::Display::getCompressedTextureSupport):
+ * src/libEGL/Display.h:
+ * src/libEGL/Surface.cpp:
+ (egl::Surface::Surface):
+ (egl::Surface::resetSwapChain):
+ (egl::Surface::getWindowHandle):
+ (egl::Surface::writeRecordableFlipState):
+ (egl::Surface::applyFlipState):
+ (egl::Surface::releaseRecordedState):
+ (egl::Surface::checkForWindowResize):
+ (egl::Surface::swap):
+ * src/libEGL/Surface.h:
+ * src/libEGL/libEGL.cpp:
+ * src/libEGL/libEGL.vcproj:
+ * src/libGLESv2/Blit.cpp:
+ (gl::Blit::setVertexShader):
+ (gl::Blit::setPixelShader):
+ (gl::Blit::setFormatConvertShaders):
+ * src/libGLESv2/Buffer.cpp:
+ (gl::Buffer::Buffer):
+ * src/libGLESv2/Buffer.h:
+ * src/libGLESv2/Context.cpp:
+ (gl::Context::Context):
+ (gl::Context::~Context):
+ (gl::Context::makeCurrent):
+ (gl::Context::markAllStateDirty):
+ (gl::Context::getReadFramebufferHandle):
+ (gl::Context::getDrawFramebufferHandle):
+ (gl::Context::getRenderbufferHandle):
+ (gl::Context::getArrayBufferHandle):
+ (gl::Context::setVertexAttribState):
+ (gl::Context::createBuffer):
+ (gl::Context::createProgram):
+ (gl::Context::createShader):
+ (gl::Context::createTexture):
+ (gl::Context::createRenderbuffer):
+ (gl::Context::deleteBuffer):
+ (gl::Context::deleteShader):
+ (gl::Context::deleteProgram):
+ (gl::Context::deleteTexture):
+ (gl::Context::deleteRenderbuffer):
+ (gl::Context::getBuffer):
+ (gl::Context::getShader):
+ (gl::Context::getProgram):
+ (gl::Context::getTexture):
+ (gl::Context::getRenderbuffer):
+ (gl::Context::getReadFramebuffer):
+ (gl::Context::getDrawFramebuffer):
+ (gl::Context::bindArrayBuffer):
+ (gl::Context::bindElementArrayBuffer):
+ (gl::Context::bindTexture2D):
+ (gl::Context::bindTextureCubeMap):
+ (gl::Context::bindReadFramebuffer):
+ (gl::Context::bindDrawFramebuffer):
+ (gl::Context::bindRenderbuffer):
+ (gl::Context::useProgram):
+ (gl::Context::setFramebufferZero):
+ (gl::Context::setRenderbufferStorage):
+ (gl::Context::getFramebuffer):
+ (gl::Context::getArrayBuffer):
+ (gl::Context::getElementArrayBuffer):
+ (gl::Context::getCurrentProgram):
+ (gl::Context::getTexture2D):
+ (gl::Context::getTextureCubeMap):
+ (gl::Context::getSamplerTexture):
+ (gl::Context::getFloatv):
+ (gl::Context::getIntegerv):
+ (gl::Context::getQueryParameterInfo):
+ (gl::Context::applyRenderTarget):
+ (gl::Context::applyState):
+ (gl::Context::applyIndexBuffer):
+ (gl::Context::readPixels):
+ (gl::Context::clear):
+ (gl::Context::finish):
+ (gl::Context::flush):
+ (gl::Context::supportsShaderModel3):
+ (gl::Context::getMaxSupportedSamples):
+ (gl::Context::getNearestSupportedSamples):
+ (gl::Context::supportsCompressedTextures):
+ (gl::Context::detachBuffer):
+ (gl::Context::detachTexture):
+ (gl::Context::detachFramebuffer):
+ (gl::Context::detachRenderbuffer):
+ (gl::Context::getIncompleteTexture):
+ (gl::Context::initExtensionString):
+ (gl::Context::blitFramebuffer):
+ * src/libGLESv2/Context.h:
+ (gl::AttributeState::AttributeState):
+ * src/libGLESv2/Framebuffer.cpp:
+ (gl::Framebuffer::Framebuffer):
+ (gl::Framebuffer::~Framebuffer):
+ (gl::Framebuffer::lookupRenderbuffer):
+ (gl::Framebuffer::setColorbuffer):
+ (gl::Framebuffer::setDepthbuffer):
+ (gl::Framebuffer::setStencilbuffer):
+ (gl::Framebuffer::detachTexture):
+ (gl::Framebuffer::detachRenderbuffer):
+ (gl::Framebuffer::getRenderTargetSerial):
+ (gl::Framebuffer::getRenderTarget):
+ (gl::Framebuffer::getDepthStencil):
+ (gl::Framebuffer::getDepthbufferSerial):
+ (gl::Framebuffer::getStencilbufferSerial):
+ (gl::Framebuffer::getColorbuffer):
+ (gl::Framebuffer::getDepthbuffer):
+ (gl::Framebuffer::getStencilbuffer):
+ (gl::Framebuffer::getColorbufferHandle):
+ (gl::Framebuffer::getDepthbufferHandle):
+ (gl::Framebuffer::getStencilbufferHandle):
+ (gl::Framebuffer::hasStencil):
+ (gl::Framebuffer::isMultisample):
+ (gl::Framebuffer::completeness):
+ (gl::DefaultFramebuffer::DefaultFramebuffer):
+ (gl::Framebuffer::getSamples):
+ (gl::DefaultFramebuffer::completeness):
+ * src/libGLESv2/Framebuffer.h:
+ * src/libGLESv2/Program.cpp:
+ (gl::Program::Program):
+ (gl::Program::~Program):
+ (gl::Program::attachShader):
+ (gl::Program::detachShader):
+ (gl::Program::linkVaryings):
+ (gl::Program::link):
+ (gl::Program::unlink):
+ (gl::Program::release):
+ (gl::Program::addRef):
+ (gl::Program::getRefCount):
+ (gl::Program::getDxViewportLocation):
+ * src/libGLESv2/Program.h:
+ * src/libGLESv2/RefCountObject.cpp: Added.
+ (gl::RefCountObject::RefCountObject):
+ (gl::RefCountObject::~RefCountObject):
+ (gl::RefCountObject::addRef):
+ (gl::RefCountObject::release):
+ (gl::RefCountObjectBindingPointer::set):
+ * src/libGLESv2/RefCountObject.h: Added.
+ (gl::RefCountObject::id):
+ (gl::RefCountObjectBindingPointer::RefCountObjectBindingPointer):
+ (gl::RefCountObjectBindingPointer::~RefCountObjectBindingPointer):
+ (gl::RefCountObjectBindingPointer::get):
+ (gl::RefCountObjectBindingPointer::id):
+ (gl::RefCountObjectBindingPointer::operator ! ):
+ (gl::BindingPointer::set):
+ (gl::BindingPointer::get):
+ (gl::BindingPointer::operator -> ):
+ * src/libGLESv2/Renderbuffer.cpp:
+ (gl::Renderbuffer::Renderbuffer):
+ (gl::Renderbuffer::~Renderbuffer):
+ (gl::Renderbuffer::isColorbuffer):
+ (gl::Renderbuffer::isDepthbuffer):
+ (gl::Renderbuffer::isStencilbuffer):
+ (gl::Renderbuffer::getRenderTarget):
+ (gl::Renderbuffer::getDepthStencil):
+ (gl::Renderbuffer::getWidth):
+ (gl::Renderbuffer::getHeight):
+ (gl::Renderbuffer::getFormat):
+ (gl::Renderbuffer::getD3DFormat):
+ (gl::Renderbuffer::getSerial):
+ (gl::Renderbuffer::setStorage):
+ (gl::RenderbufferStorage::RenderbufferStorage):
+ (gl::RenderbufferStorage::~RenderbufferStorage):
+ (gl::RenderbufferStorage::isColorbuffer):
+ (gl::RenderbufferStorage::isDepthbuffer):
+ (gl::RenderbufferStorage::isStencilbuffer):
+ (gl::RenderbufferStorage::getRenderTarget):
+ (gl::RenderbufferStorage::getDepthStencil):
+ (gl::RenderbufferStorage::getWidth):
+ (gl::RenderbufferStorage::getHeight):
+ (gl::RenderbufferStorage::setSize):
+ (gl::RenderbufferStorage::getFormat):
+ (gl::RenderbufferStorage::getD3DFormat):
+ (gl::RenderbufferStorage::getSamples):
+ (gl::RenderbufferStorage::getSerial):
+ (gl::RenderbufferStorage::issueSerial):
+ (gl::Colorbuffer::Colorbuffer):
+ (gl::Colorbuffer::isColorbuffer):
+ (gl::Colorbuffer::getRedSize):
+ (gl::Colorbuffer::getGreenSize):
+ (gl::Colorbuffer::getBlueSize):
+ (gl::Colorbuffer::getAlphaSize):
+ (gl::DepthStencilbuffer::DepthStencilbuffer):
+ (gl::DepthStencilbuffer::~DepthStencilbuffer):
+ (gl::DepthStencilbuffer::isDepthbuffer):
+ (gl::DepthStencilbuffer::isStencilbuffer):
+ (gl::DepthStencilbuffer::getDepthSize):
+ (gl::DepthStencilbuffer::getStencilSize):
+ (gl::DepthStencilbuffer::getDepthStencil):
+ (gl::Depthbuffer::Depthbuffer):
+ (gl::Depthbuffer::~Depthbuffer):
+ (gl::Depthbuffer::isDepthbuffer):
+ (gl::Depthbuffer::isStencilbuffer):
+ (gl::Stencilbuffer::Stencilbuffer):
+ (gl::Stencilbuffer::~Stencilbuffer):
+ (gl::Stencilbuffer::isDepthbuffer):
+ (gl::Stencilbuffer::isStencilbuffer):
+ * src/libGLESv2/Renderbuffer.h:
+ (gl::Renderbuffer::getStorage):
+ * src/libGLESv2/ResourceManager.cpp: Added.
+ (gl::ResourceManager::ResourceManager):
+ (gl::ResourceManager::~ResourceManager):
+ (gl::ResourceManager::addRef):
+ (gl::ResourceManager::release):
+ (gl::ResourceManager::createBuffer):
+ (gl::ResourceManager::createShader):
+ (gl::ResourceManager::createProgram):
+ (gl::ResourceManager::createTexture):
+ (gl::ResourceManager::createRenderbuffer):
+ (gl::ResourceManager::deleteBuffer):
+ (gl::ResourceManager::deleteShader):
+ (gl::ResourceManager::deleteProgram):
+ (gl::ResourceManager::deleteTexture):
+ (gl::ResourceManager::deleteRenderbuffer):
+ (gl::ResourceManager::getBuffer):
+ (gl::ResourceManager::getShader):
+ (gl::ResourceManager::getTexture):
+ (gl::ResourceManager::getProgram):
+ (gl::ResourceManager::getRenderbuffer):
+ (gl::ResourceManager::setRenderbuffer):
+ (gl::ResourceManager::checkBufferAllocation):
+ (gl::ResourceManager::checkTextureAllocation):
+ (gl::ResourceManager::checkRenderbufferAllocation):
+ * src/libGLESv2/ResourceManager.h: Added.
+ * src/libGLESv2/Shader.cpp:
+ (gl::Shader::Shader):
+ (gl::Shader::addRef):
+ (gl::Shader::release):
+ (gl::Shader::getRefCount):
+ (gl::Shader::parseVaryings):
+ (gl::VertexShader::VertexShader):
+ (gl::FragmentShader::FragmentShader):
+ * src/libGLESv2/Shader.h:
+ * src/libGLESv2/Texture.cpp:
+ (gl::Texture::Image::Image):
+ (gl::Texture::Texture):
+ (gl::Texture::getBlitter):
+ (gl::Texture::selectFormat):
+ (gl::Texture::loadImageData):
+ (gl::Texture::loadAlphaImageData):
+ (gl::Texture::loadLuminanceImageData):
+ (gl::Texture::loadLuminanceAlphaImageData):
+ (gl::Texture::loadRGBUByteImageData):
+ (gl::Texture::loadRGB565ImageData):
+ (gl::Texture::loadRGBAUByteImageData):
+ (gl::Texture::loadRGBA4444ImageData):
+ (gl::Texture::loadRGBA5551ImageData):
+ (gl::Texture::loadBGRAImageData):
+ (gl::Texture::createSurface):
+ (gl::Texture::setImage):
+ (gl::Texture::setCompressedImage):
+ (gl::Texture::subImage):
+ (gl::Texture::subImageCompressed):
+ (gl::Texture2D::Texture2D):
+ (gl::Texture2D::getFormat):
+ (gl::Texture2D::setCompressedImage):
+ (gl::Texture2D::subImage):
+ (gl::Texture2D::subImageCompressed):
+ (gl::Texture2D::copyImage):
+ (gl::Texture2D::copySubImage):
+ (gl::Texture2D::isCompressed):
+ (gl::Texture2D::getColorbuffer):
+ (gl::TextureCubeMap::TextureCubeMap):
+ (gl::TextureCubeMap::getFormat):
+ (gl::TextureCubeMap::setCompressedImage):
+ (gl::TextureCubeMap::subImage):
+ (gl::TextureCubeMap::subImageCompressed):
+ (gl::TextureCubeMap::isCompressed):
+ (gl::TextureCubeMap::copyImage):
+ (gl::TextureCubeMap::copySubImage):
+ (gl::TextureCubeMap::getColorbuffer):
+ (gl::Texture::TextureColorbufferProxy::addRef):
+ (gl::Texture::TextureColorbufferProxy::release):
+ (gl::Texture::TextureColorbufferProxy::getWidth):
+ (gl::Texture::TextureColorbufferProxy::getHeight):
+ (gl::Texture::TextureColorbufferProxy::getFormat):
+ * src/libGLESv2/Texture.h:
+ * src/libGLESv2/libGLESv2.cpp:
+ * src/libGLESv2/libGLESv2.def:
+ * src/libGLESv2/libGLESv2.vcproj:
+ * src/libGLESv2/main.h:
+ * src/libGLESv2/utilities.cpp:
+ (gl::ComputeCompressedPitch):
+ (gl::ComputeCompressedSize):
+ (gl::IsCompressed):
+ (gl::ComputePixelSize):
+ (gl::CheckTextureFormatType):
+ (es2dx::ConvertRenderbufferFormat):
+ (es2dx::GetSamplesFromMultisampleType):
+ (es2dx::GetMultisampleTypeFromSamples):
+ * src/libGLESv2/utilities.h:
+
2010-08-17 Chris Marrin <cmarrin@apple.com>
Unreviewed.
diff --git a/ANGLE/include/GLES2/gl2ext.h b/ANGLE/include/GLES2/gl2ext.h
index 80a6820..01844de 100644
--- a/ANGLE/include/GLES2/gl2ext.h
+++ b/ANGLE/include/GLES2/gl2ext.h
@@ -222,6 +222,12 @@ typedef void* GLeglImageOES;
#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
#endif
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension tokens
*------------------------------------------------------------------------*/
@@ -351,6 +357,25 @@ typedef void* GLeglImageOES;
#endif
/*------------------------------------------------------------------------*
+ * ANGLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 // alias GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+#endif
+
+/*------------------------------------------------------------------------*
* End of extension tokens, start of corresponding extension functions
*------------------------------------------------------------------------*/
@@ -623,6 +648,11 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
#define GL_EXT_texture_type_2_10_10_10_REV 1
#endif
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension functions
*------------------------------------------------------------------------*/
@@ -766,6 +796,34 @@ typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint
typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
#endif
+/*------------------------------------------------------------------------*
+ * ANGLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/ANGLE/include/GLSLANG/ResourceLimits.h b/ANGLE/include/GLSLANG/ResourceLimits.h
deleted file mode 100644
index 7b7a4b7..0000000
--- a/ANGLE/include/GLSLANG/ResourceLimits.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project 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 _RESOURCE_LIMITS_INCLUDED_
-#define _RESOURCE_LIMITS_INCLUDED_
-
-struct TBuiltInResource
-{
- int maxVertexAttribs;
- int maxVertexUniformVectors;
- int maxVaryingVectors;
- int maxVertexTextureImageUnits;
- int maxCombinedTextureImageUnits;
- int maxTextureImageUnits;
- int maxFragmentUniformVectors;
- int maxDrawBuffers;
-};
-#endif // _RESOURCE_LIMITS_INCLUDED_
diff --git a/ANGLE/include/GLSLANG/ShaderLang.h b/ANGLE/include/GLSLANG/ShaderLang.h
index 19e6df0..e0a5cc8 100644
--- a/ANGLE/include/GLSLANG/ShaderLang.h
+++ b/ANGLE/include/GLSLANG/ShaderLang.h
@@ -6,8 +6,6 @@
#ifndef _COMPILER_INTERFACE_INCLUDED_
#define _COMPILER_INTERFACE_INCLUDED_
-#include "ResourceLimits.h"
-
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@@ -19,10 +17,12 @@ extern "C" {
//
// Driver must call this first, once, before doing any other
// compiler operations.
+// If the function succeeds, the return value is nonzero, else zero.
//
int ShInitialize();
//
// Driver should call this at shutdown.
+// If the function succeeds, the return value is nonzero, else zero.
//
int ShFinalize();
//
@@ -44,6 +44,32 @@ typedef enum {
} EShSpec;
//
+// Implementation dependent built-in resources (constants and extensions).
+// The names for these resources has been obtained by stripping gl_/GL_.
+//
+typedef struct
+{
+ // Constants.
+ int MaxVertexAttribs;
+ int MaxVertexUniformVectors;
+ int MaxVaryingVectors;
+ int MaxVertexTextureImageUnits;
+ int MaxCombinedTextureImageUnits;
+ int MaxTextureImageUnits;
+ int MaxFragmentUniformVectors;
+ int MaxDrawBuffers;
+
+ // Extensions.
+ // Set to 1 to enable the extension, else 0.
+ int OES_standard_derivatives;
+} TBuiltInResource;
+
+//
+// Initialize built-in resources with minimum expected values.
+//
+void ShInitBuiltInResource(TBuiltInResource* resources);
+
+//
// Optimization level for the compiler.
//
typedef enum {
diff --git a/ANGLE/src/compiler/BaseTypes.h b/ANGLE/src/compiler/BaseTypes.h
index cb646fc..9f4a860 100644
--- a/ANGLE/src/compiler/BaseTypes.h
+++ b/ANGLE/src/compiler/BaseTypes.h
@@ -19,7 +19,7 @@ enum TPrecision
EbpHigh,
};
-__inline const char* getPrecisionString(TPrecision p)
+inline const char* getPrecisionString(TPrecision p)
{
switch(p)
{
@@ -47,7 +47,22 @@ enum TBasicType
EbtAddress, // should be deprecated??
};
-__inline bool IsSampler(TBasicType type)
+inline const char* getBasicString(TBasicType t)
+{
+ switch (t)
+ {
+ case EbtVoid: return "void"; break;
+ case EbtFloat: return "float"; break;
+ case EbtInt: return "int"; break;
+ case EbtBool: return "bool"; break;
+ case EbtSampler2D: return "sampler2D"; break;
+ case EbtSamplerCube: return "samplerCube"; break;
+ case EbtStruct: return "structure"; break;
+ default: return "unknown type";
+ }
+}
+
+inline bool IsSampler(TBasicType type)
{
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
}
@@ -100,7 +115,7 @@ enum TQualifier
//
// This is just for debug print out, carried along with the definitions above.
//
-__inline const char* getQualifierString(TQualifier q)
+inline const char* getQualifierString(TQualifier q)
{
switch(q)
{
diff --git a/ANGLE/src/compiler/Initialize.cpp b/ANGLE/src/compiler/Initialize.cpp
index 58c6162..6bfcf4f 100644
--- a/ANGLE/src/compiler/Initialize.cpp
+++ b/ANGLE/src/compiler/Initialize.cpp
@@ -472,15 +472,15 @@ static TString BuiltInConstants(const TBuiltInResource &resources)
{
TStringStream s;
- s << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";";
- s << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";";
+ s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";";
+ s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";";
- s << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";";
- s << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";";
- s << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
- s << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
- s << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
- s << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
+ s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";";
+ s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";";
+ s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";";
+ s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";";
+ s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";";
+ s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";";
return s.str();
}
@@ -591,23 +591,23 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
symbolTable.relateToOperator("all", EOpAll);
// Map language-specific operators.
- switch(language) {
- case EShLangVertex:
- break;
- case EShLangFragment:
- //symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
- //symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
- //symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
- break;
- default: break;
- }
+ switch(language) {
+ case EShLangVertex:
+ break;
+ case EShLangFragment:
+ //symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
+ //symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
+ //symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
+ break;
+ default: break;
+ }
// Finally add resource-specific variables.
switch(language) {
case EShLangFragment: {
// Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true);
- fragData.setArraySize(resources.maxDrawBuffers);
+ fragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
}
break;
diff --git a/ANGLE/src/compiler/Initialize.h b/ANGLE/src/compiler/Initialize.h
index 03c9937..c078659 100644
--- a/ANGLE/src/compiler/Initialize.h
+++ b/ANGLE/src/compiler/Initialize.h
@@ -7,8 +7,6 @@
#ifndef _INITIALIZE_INCLUDED_
#define _INITIALIZE_INCLUDED_
-#include "GLSLANG/ResourceLimits.h"
-
#include "compiler/Common.h"
#include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h"
diff --git a/ANGLE/src/compiler/InitializeDll.cpp b/ANGLE/src/compiler/InitializeDll.cpp
index 06f8384..8763cfe 100644
--- a/ANGLE/src/compiler/InitializeDll.cpp
+++ b/ANGLE/src/compiler/InitializeDll.cpp
@@ -6,72 +6,88 @@
#include "compiler/InitializeDll.h"
-#include "GLSLANG/ShaderLang.h"
-
#include "compiler/InitializeGlobals.h"
#include "compiler/InitializeParseContext.h"
+#include "compiler/osinclude.h"
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
bool InitProcess()
{
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
- //
- // Function is re-entrant.
- //
+ //
+ // Function is re-entrant.
+ //
return true;
- }
+ }
ThreadInitializeIndex = OS_AllocTLSIndex();
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
return false;
- }
+ }
if (!InitializePoolIndex()) {
assert(0 && "InitProcess(): Failed to initalize global pool");
return false;
- }
+ }
if (!InitializeParseContextIndex()) {
assert(0 && "InitProcess(): Failed to initalize parse context");
return false;
- }
+ }
- InitThread();
- return true;
+ return InitThread();
}
+bool DetachProcess()
+{
+ bool success = true;
+
+ if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
+ return true;
+
+ success = DetachThread();
+
+ if (!FreeParseContextIndex())
+ success = false;
+
+ FreePoolIndex();
+
+ OS_FreeTLSIndex(ThreadInitializeIndex);
+ ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
+
+ return success;
+}
bool InitThread()
{
- //
+ //
// This function is re-entrant
- //
+ //
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitThread(): Process hasn't been initalised.");
+ assert(0 && "InitThread(): Process hasn't been initalised.");
return false;
- }
+ }
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
return true;
- InitializeGlobalPools();
+ InitializeGlobalPools();
- if (!InitializeGlobalParseContext())
+ if (!InitializeGlobalParseContext())
return false;
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
- assert(0 && "InitThread(): Unable to set init flag.");
+ assert(0 && "InitThread(): Unable to set init flag.");
return false;
- }
+ }
return true;
}
-
bool DetachThread()
{
bool success = true;
@@ -79,42 +95,21 @@ bool DetachThread()
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
return true;
- //
- // Function is re-entrant and this thread may not have been initalised.
- //
+ //
+ // Function is re-entrant and this thread may not have been initalised.
+ //
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
- assert(0 && "DetachThread(): Unable to clear init flag.");
+ assert(0 && "DetachThread(): Unable to clear init flag.");
success = false;
- }
+ }
- FreeGlobalPools();
-
- if (!FreeParseContext())
+ if (!FreeParseContext())
success = false;
- }
-
- return success;
-}
-
-bool DetachProcess()
-{
- bool success = true;
-
- if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
- return true;
-
- ShFinalize();
-
- success = DetachThread();
-
- FreePoolIndex();
- if (!FreeParseContextIndex())
- success = false;
-
- OS_FreeTLSIndex(ThreadInitializeIndex);
- ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
+ FreeGlobalPools();
+ }
return success;
}
+
diff --git a/ANGLE/src/compiler/InitializeDll.h b/ANGLE/src/compiler/InitializeDll.h
index bb17540..857238e 100644
--- a/ANGLE/src/compiler/InitializeDll.h
+++ b/ANGLE/src/compiler/InitializeDll.h
@@ -6,14 +6,11 @@
#ifndef __INITIALIZEDLL_H
#define __INITIALIZEDLL_H
-
-#include "compiler/osinclude.h"
-
-
bool InitProcess();
+bool DetachProcess();
+
bool InitThread();
bool DetachThread();
-bool DetachProcess();
#endif // __INITIALIZEDLL_H
diff --git a/ANGLE/src/compiler/InitializeParseContext.h b/ANGLE/src/compiler/InitializeParseContext.h
index 68295d0..760fd09 100644
--- a/ANGLE/src/compiler/InitializeParseContext.h
+++ b/ANGLE/src/compiler/InitializeParseContext.h
@@ -6,12 +6,11 @@
#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
-#include "compiler/osinclude.h"
bool InitializeParseContextIndex();
-bool InitializeGlobalParseContext();
-bool FreeParseContext();
bool FreeParseContextIndex();
+bool InitializeGlobalParseContext();
+bool FreeParseContext();
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/ANGLE/src/compiler/Intermediate.cpp b/ANGLE/src/compiler/Intermediate.cpp
index f65bc80..5ebd919 100644
--- a/ANGLE/src/compiler/Intermediate.cpp
+++ b/ANGLE/src/compiler/Intermediate.cpp
@@ -10,6 +10,7 @@
#include <float.h>
#include <limits.h>
+#include <algorithm>
#include "compiler/localintermediate.h"
#include "compiler/QualifierAlive.h"
@@ -17,9 +18,10 @@
bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
-TPrecision GetHighestPrecision( TPrecision left, TPrecision right ){
+static TPrecision GetHigherPrecision( TPrecision left, TPrecision right ){
return left > right ? left : right;
}
+
////////////////////////////////////////////////////////////////////////////
//
// First set of functions are to help build the intermediate representation.
@@ -111,12 +113,6 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
- if (leftTempConstant)
- leftTempConstant = left->getAsConstantUnion();
-
- if (rightTempConstant)
- rightTempConstant = right->getAsConstantUnion();
-
//
// See if we can fold constants.
//
@@ -307,7 +303,7 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
//
// Set the operator.
//
- aggNode->setOperator(op);
+ aggNode->setOp(op);
if (line != 0)
aggNode->setLine(line);
@@ -519,9 +515,9 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
return right;
} else {
TIntermTyped *commaAggregate = growAggregate(left, right, line);
- commaAggregate->getAsAggregate()->setOperator(EOpComma);
+ commaAggregate->getAsAggregate()->setOp(EOpComma);
commaAggregate->setType(right->getType());
- commaAggregate->getTypePointer()->changeQualifier(EvqTemporary);
+ commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
return commaAggregate;
}
}
@@ -644,7 +640,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
//
TIntermAggregate* aggRoot = root->getAsAggregate();
if (aggRoot && aggRoot->getOp() == EOpNull)
- aggRoot->setOperator(EOpSequence);
+ aggRoot->setOp(EOpSequence);
return true;
}
@@ -764,16 +760,9 @@ bool TIntermUnary::promote(TInfoSink&)
//
bool TIntermBinary::promote(TInfoSink& infoSink)
{
- int size = left->getNominalSize();
- if (right->getNominalSize() > size)
- size = right->getNominalSize();
-
- TBasicType type = left->getBasicType();
-
- //
- // Arrays have to be exact matches.
- //
- if ((left->isArray() || right->isArray()) && (left->getType() != right->getType()))
+ // GLSL ES 2.0 does not support implicit type casting.
+ // So the basic type should always match.
+ if (left->getBasicType() != right->getBasicType())
return false;
//
@@ -782,16 +771,27 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
//
setType(left->getType());
- TPrecision highestPrecision = GetHighestPrecision(left->getPrecision(), right->getPrecision());
- getTypePointer()->changePrecision(highestPrecision);
+ // The result gets promoted to the highest precision.
+ TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
+ getTypePointer()->setPrecision(higherPrecision);
+
+ // Binary operations results in temporary variables unless both
+ // operands are const.
+ if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) {
+ getTypePointer()->setQualifier(EvqTemporary);
+ }
//
// Array operations.
//
- if (left->isArray()) {
+ if (left->isArray() || right->isArray()) {
+ //
+ // Arrays types have to be exact matches.
+ //
+ if (left->getType() != right->getType())
+ return false;
switch (op) {
-
//
// Promote to conditional
//
@@ -812,17 +812,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
default:
return false;
}
-
return true;
}
+ int size = std::max(left->getNominalSize(), right->getNominalSize());
+
//
- // All scalars. Code after this test assumes this case is removed!
+ // All scalars. Code after this test assumes this case is removed!
//
if (size == 1) {
-
switch (op) {
-
//
// Promote to conditional
//
@@ -840,33 +839,36 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
//
case EOpLogicalAnd:
case EOpLogicalOr:
+ // Both operands must be of type bool.
if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
return false;
setType(TType(EbtBool, EbpUndefined));
break;
- //
- // Everything else should have matching types
- //
default:
- if (left->getBasicType() != right->getBasicType() ||
- left->isMatrix() != right->isMatrix())
- return false;
+ break;
}
-
return true;
}
- //
+ // If we reach here, at least one of the operands is vector or matrix.
+ // The other operand could be a scalar, vector, or matrix.
// Are the sizes compatible?
//
- if ( left->getNominalSize() != size && left->getNominalSize() != 1 ||
- right->getNominalSize() != size && right->getNominalSize() != 1)
- return false;
+ if (left->getNominalSize() != right->getNominalSize()) {
+ // If the nominal size of operands do not match:
+ // One of them must be scalar.
+ if (left->getNominalSize() != 1 && right->getNominalSize() != 1)
+ return false;
+ // Operator cannot be of type pure assignment.
+ if (op == EOpAssign || op == EOpInitialize)
+ return false;
+ }
//
// Can these two operands be combined?
//
+ TBasicType basicType = left->getBasicType();
switch (op) {
case EOpMul:
if (!left->isMatrix() && right->isMatrix()) {
@@ -874,12 +876,12 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
op = EOpVectorTimesMatrix;
else {
op = EOpMatrixTimesScalar;
- setType(TType(type, highestPrecision, EvqTemporary, size, true));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, true));
}
} else if (left->isMatrix() && !right->isMatrix()) {
if (right->isVector()) {
op = EOpMatrixTimesVector;
- setType(TType(type, highestPrecision, EvqTemporary, size, false));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
} else {
op = EOpMatrixTimesScalar;
}
@@ -890,7 +892,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// leave as component product
} else if (left->isVector() || right->isVector()) {
op = EOpVectorTimesScalar;
- setType(TType(type, highestPrecision, EvqTemporary, size, false));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
}
} else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
@@ -919,18 +921,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
if (! left->isVector())
return false;
op = EOpVectorTimesScalarAssign;
- setType(TType(type, highestPrecision, EvqTemporary, size, false));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
}
} else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
return false;
}
break;
+
case EOpAssign:
case EOpInitialize:
- if (left->getNominalSize() != right->getNominalSize())
- return false;
- // fall through
case EOpAdd:
case EOpSub:
case EOpDiv:
@@ -938,10 +938,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
case EOpSubAssign:
case EOpDivAssign:
if (left->isMatrix() && right->isVector() ||
- left->isVector() && right->isMatrix() ||
- left->getBasicType() != right->getBasicType())
+ left->isVector() && right->isMatrix())
return false;
- setType(TType(type, highestPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
break;
case EOpEqual:
@@ -951,8 +950,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
case EOpLessThanEqual:
case EOpGreaterThanEqual:
if (left->isMatrix() && right->isVector() ||
- left->isVector() && right->isMatrix() ||
- left->getBasicType() != right->getBasicType())
+ left->isVector() && right->isMatrix())
return false;
setType(TType(EbtBool, EbpUndefined));
break;
@@ -960,30 +958,13 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
default:
return false;
}
-
- //
- // One more check for assignment. The Resulting type has to match the left operand.
- //
- switch (op) {
- case EOpAssign:
- case EOpInitialize:
- case EOpAddAssign:
- case EOpSubAssign:
- case EOpMulAssign:
- case EOpDivAssign:
- if (getType() != left->getType())
- return false;
- break;
- default:
- break;
- }
-
+
return true;
}
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{
- TTypeList* fields = leftNodeType.getStruct();
+ const TTypeList* fields = leftNodeType.getStruct();
size_t structSize = fields->size();
int index = 0;
diff --git a/ANGLE/src/compiler/OutputGLSL.cpp b/ANGLE/src/compiler/OutputGLSL.cpp
index 486a27a..fd263b6 100644
--- a/ANGLE/src/compiler/OutputGLSL.cpp
+++ b/ANGLE/src/compiler/OutputGLSL.cpp
@@ -147,7 +147,7 @@ void TOutputGLSL::writeFunctionParameters(const TIntermSequence& args)
out << arrayBrackets(type);
// Put a comma if this is not the last argument.
- if (iter != --args.end())
+ if (iter != args.end() - 1)
out << ", ";
}
}
@@ -304,8 +304,6 @@ bool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node)
bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node)
{
- TInfoSinkBase& out = objSink();
-
switch (node->getOp())
{
case EOpNegative: writeTriplet(visit, "(-", NULL, ")"); break;
@@ -650,8 +648,6 @@ bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
bool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node)
{
- TInfoSinkBase &out = objSink();
-
switch (node->getFlowOp())
{
case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
diff --git a/ANGLE/src/compiler/OutputHLSL.cpp b/ANGLE/src/compiler/OutputHLSL.cpp
index 36f527c..8b8a4e6 100644
--- a/ANGLE/src/compiler/OutputHLSL.cpp
+++ b/ANGLE/src/compiler/OutputHLSL.cpp
@@ -181,7 +181,7 @@ void OutputHLSL::header()
if (mUsesFragCoord)
{
- out << "uniform float4 dx_Window;\n"
+ out << "uniform float4 dx_Viewport;\n"
"uniform float2 dx_Depth;\n";
}
@@ -791,11 +791,11 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{
if (node->getLeft()->isMatrix())
{
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
- case 2 * 2: mUsesEqualMat2 = true; break;
- case 3 * 3: mUsesEqualMat3 = true; break;
- case 4 * 4: mUsesEqualMat4 = true; break;
+ case 2: mUsesEqualMat2 = true; break;
+ case 3: mUsesEqualMat3 = true; break;
+ case 4: mUsesEqualMat4 = true; break;
default: UNREACHABLE();
}
}
@@ -804,7 +804,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
switch (node->getLeft()->getBasicType())
{
case EbtFloat:
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
case 2: mUsesEqualVec2 = true; break;
case 3: mUsesEqualVec3 = true; break;
@@ -813,7 +813,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
}
break;
case EbtInt:
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
case 2: mUsesEqualIVec2 = true; break;
case 3: mUsesEqualIVec3 = true; break;
@@ -822,7 +822,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
}
break;
case EbtBool:
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
case 2: mUsesEqualBVec2 = true; break;
case 3: mUsesEqualBVec3 = true; break;
@@ -1288,7 +1288,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break;
case EOpMod:
{
- switch (node->getSequence()[0]->getAsTyped()->getSize()) // Number of components in the first argument
+ switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
{
case 1: mUsesMod1 = true; break;
case 2: mUsesMod2 = true; break;
@@ -1317,7 +1317,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break;
case EOpFaceForward:
{
- switch (node->getSequence()[0]->getAsTyped()->getSize()) // Number of components in the first argument
+ switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
{
case 1: mUsesFaceforward1 = true; break;
case 2: mUsesFaceforward2 = true; break;
@@ -1553,7 +1553,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (symbol && constant)
{
- if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
+ if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
index = symbol;
initial = constant->getUnionArrayPointer()[0].getIConst();
@@ -1575,7 +1575,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (constant)
{
- if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
+ if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
comparator = test->getOp();
limit = constant->getUnionArrayPointer()[0].getIConst();
@@ -1597,7 +1597,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (constant)
{
- if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
+ if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
int value = constant->getUnionArrayPointer()[0].getIConst();
@@ -1848,8 +1848,8 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
TType ctorType = type;
ctorType.clearArrayness();
- ctorType.changePrecision(EbpHigh);
- ctorType.changeQualifier(EvqTemporary);
+ ctorType.setPrecision(EbpHigh);
+ ctorType.setQualifier(EvqTemporary);
TString ctorName = type.getStruct() ? decorate(name) : name;
diff --git a/ANGLE/src/compiler/ParseHelper.cpp b/ANGLE/src/compiler/ParseHelper.cpp
index f1ab572..407226b 100644
--- a/ANGLE/src/compiler/ParseHelper.cpp
+++ b/ANGLE/src/compiler/ParseHelper.cpp
@@ -486,7 +486,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
}
if (constType)
- type->changeQualifier(EvqConst);
+ type->setQualifier(EvqConst);
if (type->isArray() && type->getArraySize() != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor", "");
@@ -586,14 +586,14 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
{
if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) {
- error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)");
+ error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
return true;
}
return false;
} else if (IsSampler(pType.type)) {
- error(line, reason, TType::getBasicString(pType.type), "");
+ error(line, reason, getBasicString(pType.type), "");
return true;
}
@@ -879,9 +879,9 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
}
if (qualifier == EvqConst)
- type->changeQualifier(EvqConstReadOnly);
+ type->setQualifier(EvqConstReadOnly);
else
- type->changeQualifier(paramQualifier);
+ type->setQualifier(paramQualifier);
return false;
}
@@ -913,21 +913,24 @@ bool TParseContext::extensionErrorCheck(int line, const char* extension)
//
const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
{
- const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
+ // First find by unmangled name to check whether the function name has been
+ // hidden by a variable name or struct typename.
+ const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
+ if (symbol == 0) {
+ symbol = symbolTable.find(call->getMangledName(), builtIn);
+ }
- if (symbol == 0) {
+ if (symbol == 0) {
error(line, "no matching overloaded function found", call->getName().c_str(), "");
return 0;
}
- if (! symbol->isFunction()) {
+ if (!symbol->isFunction()) {
error(line, "function name expected", call->getName().c_str(), "");
return 0;
}
-
- const TFunction* function = static_cast<const TFunction*>(symbol);
-
- return function;
+
+ return static_cast<const TFunction*>(symbol);
}
//
@@ -973,13 +976,13 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
if (qualifier == EvqConst) {
if (qualifier != initializer->getType().getQualifier()) {
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
- variable->getType().changeQualifier(EvqTemporary);
+ variable->getType().setQualifier(EvqTemporary);
return true;
}
if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString(), "");
- variable->getType().changeQualifier(EvqTemporary);
+ variable->getType().setQualifier(EvqTemporary);
return true;
}
if (initializer->getAsConstantUnion()) {
@@ -998,7 +1001,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
variable->shareConstPointer(constArray);
} else {
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
- variable->getType().changeQualifier(EvqTemporary);
+ variable->getType().setQualifier(EvqTemporary);
return true;
}
}
@@ -1049,7 +1052,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
TIntermAggregate* aggrNode = node->getAsAggregate();
- TTypeList::iterator memberTypes;
+ TTypeList::const_iterator memberTypes;
if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin();
@@ -1347,7 +1350,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
//
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
{
- TTypeList* fields = node->getType().getStruct();
+ const TTypeList* fields = node->getType().getStruct();
TIntermTyped *typedNode;
int instanceSize = 0;
unsigned int index = 0;
@@ -1410,6 +1413,20 @@ bool InitializeParseContextIndex()
return true;
}
+bool FreeParseContextIndex()
+{
+ OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+
+ if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+ assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
+ return false;
+ }
+
+ GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+
+ return OS_FreeTLSIndex(tlsiIndex);
+}
+
bool InitializeGlobalParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
@@ -1435,17 +1452,6 @@ bool InitializeGlobalParseContext()
return true;
}
-TParseContextPointer& GetGlobalParseContext()
-{
- //
- // Minimal error checking for speed
- //
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
- return lpParseContext->lpGlobalParseContext;
-}
-
bool FreeParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
@@ -1460,16 +1466,14 @@ bool FreeParseContext()
return true;
}
-bool FreeParseContextIndex()
+TParseContextPointer& GetGlobalParseContext()
{
- OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
-
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
- return false;
- }
+ //
+ // Minimal error checking for speed
+ //
- GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+ TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
- return OS_FreeTLSIndex(tlsiIndex);
+ return lpParseContext->lpGlobalParseContext;
}
+
diff --git a/ANGLE/src/compiler/PoolAlloc.h b/ANGLE/src/compiler/PoolAlloc.h
index 0fa3194..645db78 100644
--- a/ANGLE/src/compiler/PoolAlloc.h
+++ b/ANGLE/src/compiler/PoolAlloc.h
@@ -157,11 +157,12 @@ protected:
struct tHeader {
tHeader(tHeader* nextPage, size_t pageCount) :
+ nextPage(nextPage),
+ pageCount(pageCount)
#ifdef GUARD_BLOCKS
- lastAllocation(0),
+ , lastAllocation(0)
#endif
- nextPage(nextPage),
- pageCount(pageCount) { }
+ { }
~tHeader() {
#ifdef GUARD_BLOCKS
@@ -263,19 +264,26 @@ public:
template<class Other>
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
+#if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR)
+ // libCStd on some platforms have a different allocate/deallocate interface.
+ // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
+ // allocated, not the number of elements.
+ void* allocate(size_type n) {
+ return getAllocator().allocate(n);
+ }
+ void* allocate(size_type n, const void*) {
+ return getAllocator().allocate(n);
+ }
+ void deallocate(void*, size_type) {}
+#else
pointer allocate(size_type n) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
}
pointer allocate(size_type n, const void*) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
}
-
- void deallocate(void*, size_type) { }
- void deallocate(pointer, size_type) { }
-
- pointer _Charalloc(size_t n) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n));
- }
+ void deallocate(pointer, size_type) {}
+#endif // _RWSTD_ALLOCATOR
void construct(pointer p, const T& val) { new ((void *)p) T(val); }
void destroy(pointer p) { p->T::~T(); }
diff --git a/ANGLE/src/compiler/ShaderLang.cpp b/ANGLE/src/compiler/ShaderLang.cpp
index 3c36ef8..e0c646a 100644
--- a/ANGLE/src/compiler/ShaderLang.cpp
+++ b/ANGLE/src/compiler/ShaderLang.cpp
@@ -90,15 +90,45 @@ static bool GenerateBuiltInSymbolTable(
//
int ShInitialize()
{
- bool ret = InitProcess();
+ if (!InitProcess())
+ return 0;
- return ret ? 1 : 0;
+ return 1;
}
//
-// Driver calls these to create and destroy compiler objects.
+// Cleanup symbol tables
+//
+int ShFinalize()
+{
+ if (!DetachProcess())
+ return 0;
+
+ return 1;
+}
+
+//
+// Initialize built-in resources with minimum expected values.
//
+void ShInitBuiltInResource(TBuiltInResource* resources)
+{
+ // Constants.
+ resources->MaxVertexAttribs = 8;
+ resources->MaxVertexUniformVectors = 128;
+ resources->MaxVaryingVectors = 8;
+ resources->MaxVertexTextureImageUnits = 0;
+ resources->MaxCombinedTextureImageUnits = 8;
+ resources->MaxTextureImageUnits = 8;
+ resources->MaxFragmentUniformVectors = 16;
+ resources->MaxDrawBuffers = 1;
+
+ // Extensions.
+ resources->OES_standard_derivatives = 0;
+}
+//
+// Driver calls these to create and destroy compiler objects.
+//
ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
{
if (!InitThread())
@@ -130,14 +160,6 @@ void ShDestruct(ShHandle handle)
}
//
-// Cleanup symbol tables
-//
-int ShFinalize()
-{
- return 1;
-}
-
-//
// Do an actual compile on the given strings. The result is left
// in the given compile object.
//
diff --git a/ANGLE/src/compiler/SymbolTable.cpp b/ANGLE/src/compiler/SymbolTable.cpp
index d97f0ec..1b08667 100644
--- a/ANGLE/src/compiler/SymbolTable.cpp
+++ b/ANGLE/src/compiler/SymbolTable.cpp
@@ -65,7 +65,7 @@ int TType::getStructSize() const
}
if (structureSize == 0)
- for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
+ for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
structureSize += ((*tl).type)->getObjectSize();
return structureSize;
diff --git a/ANGLE/src/compiler/SymbolTable.h b/ANGLE/src/compiler/SymbolTable.h
index 07c81d1..b1a80b5 100644
--- a/ANGLE/src/compiler/SymbolTable.h
+++ b/ANGLE/src/compiler/SymbolTable.h
@@ -76,7 +76,7 @@ public:
TType& getType() { return type; }
const TType& getType() const { return type; }
bool isUserType() const { return userType; }
- void changeQualifier(TQualifier qualifier) { type.changeQualifier(qualifier); }
+ void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
void updateArrayInformationType(TType *t) { arrayInformationType = t; }
TType* getArrayInformationType() { return arrayInformationType; }
diff --git a/ANGLE/src/compiler/Types.h b/ANGLE/src/compiler/Types.h
index 44511b4..897b28f 100644
--- a/ANGLE/src/compiler/Types.h
+++ b/ANGLE/src/compiler/Types.h
@@ -82,28 +82,27 @@ typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
class TType {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- explicit TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
- type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
- { }
+ TType() {}
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
+ type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
+ structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+ {
+ }
explicit TType(const TPublicType &p) :
- type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
- {
- if (p.userDef) {
- structure = p.userDef->getStruct();
- typeName = NewPoolTString(p.userDef->getTypeName().c_str());
- }
- }
- explicit TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
- structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
- typeName = NewPoolTString(n.c_str());
- }
- explicit TType() {}
- virtual ~TType() {}
-
- TType(const TType& type) { *this = type; }
+ type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
+ structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+ {
+ if (p.userDef) {
+ structure = p.userDef->getStruct();
+ typeName = NewPoolTString(p.userDef->getTypeName().c_str());
+ }
+ }
+ TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
+ type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
+ structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
+ {
+ typeName = NewPoolTString(n.c_str());
+ }
void copyType(const TType& copyOf, TStructureMap& remapper)
{
@@ -157,77 +156,19 @@ public:
return newType;
}
- virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
- { type = t; size = s; matrix = m; array = a; arraySize = aS; }
- virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
- { type = t;
- size = s;
- matrix = m;
- if (userDef)
- structure = userDef->getStruct();
- // leave array information intact.
- }
- virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
- virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
- virtual const TString& getTypeName() const
- {
- assert(typeName);
- return *typeName;
- }
+ TBasicType getBasicType() const { return type; }
+ void setBasicType(TBasicType t) { type = t; }
- virtual const TString& getFieldName() const
- {
- assert(fieldName);
- return *fieldName;
- }
+ TPrecision getPrecision() const { return precision; }
+ void setPrecision(TPrecision p) { precision = p; }
- virtual TBasicType getBasicType() const { return type; }
- virtual TPrecision getPrecision() const { return precision; }
- virtual TQualifier getQualifier() const { return qualifier; }
- virtual void changePrecision(TPrecision p) { precision = p; }
- virtual void changeQualifier(TQualifier q) { qualifier = q; }
+ TQualifier getQualifier() const { return qualifier; }
+ void setQualifier(TQualifier q) { qualifier = q; }
// One-dimensional size of single instance type
- virtual int getNominalSize() const { return size; }
-
- // Full-dimensional size of single instance of type
- virtual int getInstanceSize() const
- {
- if (matrix)
- return size * size;
- else
- return size;
- }
-
- virtual bool isMatrix() const { return matrix ? true : false; }
- virtual bool isArray() const { return array ? true : false; }
- bool isField() const { return fieldName != 0; }
- int getArraySize() const { return arraySize; }
- void setArraySize(int s) { array = true; arraySize = s; }
- void setMaxArraySize (int s) { maxArraySize = s; }
- int getMaxArraySize () const { return maxArraySize; }
- void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
- void setArrayInformationType(TType* t) { arrayInformationType = t; }
- TType* getArrayInformationType() const { return arrayInformationType; }
- virtual bool isVector() const { return size > 1 && !matrix; }
- virtual bool isScalar() const { return size == 1 && !matrix && !structure; }
- static const char* getBasicString(TBasicType t) {
- switch (t) {
- case EbtVoid: return "void"; break;
- case EbtFloat: return "float"; break;
- case EbtInt: return "int"; break;
- case EbtBool: return "bool"; break;
- case EbtSampler2D: return "sampler2D"; break;
- case EbtSamplerCube: return "samplerCube"; break;
- case EbtStruct: return "structure"; break;
- default: return "unknown type";
- }
- }
- const char* getBasicString() const { return TType::getBasicString(type); }
- const char* getPrecisionString() const { return ::getPrecisionString(precision); }
- const char* getQualifierString() const { return ::getQualifierString(qualifier); }
- TTypeList* getStruct() { return structure; }
-
+ int getNominalSize() const { return size; }
+ void setNominalSize(int s) { size = s; }
+ // Full size of single instance of type
int getObjectSize() const
{
int totalSize;
@@ -245,7 +186,45 @@ public:
return totalSize;
}
+ bool isMatrix() const { return matrix ? true : false; }
+ void setMatrix(bool m) { matrix = m; }
+
+ bool isArray() const { return array ? true : false; }
+ int getArraySize() const { return arraySize; }
+ void setArraySize(int s) { array = true; arraySize = s; }
+ int getMaxArraySize () const { return maxArraySize; }
+ void setMaxArraySize (int s) { maxArraySize = s; }
+ void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
+ void setArrayInformationType(TType* t) { arrayInformationType = t; }
+ TType* getArrayInformationType() const { return arrayInformationType; }
+
+ bool isVector() const { return size > 1 && !matrix; }
+ bool isScalar() const { return size == 1 && !matrix && !structure; }
+
TTypeList* getStruct() const { return structure; }
+ void setStruct(TTypeList* s) { structure = s; }
+
+ const TString& getTypeName() const
+ {
+ assert(typeName);
+ return *typeName;
+ }
+ void setTypeName(const TString& n)
+ {
+ typeName = NewPoolTString(n.c_str());
+ }
+
+ bool isField() const { return fieldName != 0; }
+ const TString& getFieldName() const
+ {
+ assert(fieldName);
+ return *fieldName;
+ }
+ void setFieldName(const TString& n)
+ {
+ fieldName = NewPoolTString(n.c_str());
+ }
+
TString& getMangledName() {
if (!mangled) {
mangled = NewPoolTString("");
@@ -255,6 +234,7 @@ public:
return *mangled;
}
+
bool sameElementType(const TType& right) const {
return type == right.type &&
size == right.size &&
@@ -282,6 +262,10 @@ public:
return false;
}
+
+ const char* getBasicString() const { return ::getBasicString(type); }
+ const char* getPrecisionString() const { return ::getPrecisionString(precision); }
+ const char* getQualifierString() const { return ::getQualifierString(qualifier); }
TString getCompleteString() const;
protected:
@@ -295,11 +279,12 @@ protected:
unsigned int matrix : 1;
unsigned int array : 1;
int arraySize;
+ int maxArraySize;
+ TType* arrayInformationType;
TTypeList* structure; // 0 unless this is a struct
mutable int structureSize;
- int maxArraySize;
- TType* arrayInformationType;
+
TString *fieldName; // for structure field names
TString *mangled;
TString *typeName; // for structure field type name
diff --git a/ANGLE/src/compiler/glslang.l b/ANGLE/src/compiler/glslang.l
index 395c0bf..02c226f 100644
--- a/ANGLE/src/compiler/glslang.l
+++ b/ANGLE/src/compiler/glslang.l
@@ -309,7 +309,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon
if (*cpp->PaStrLen >= 0) {
int ret = yyparse((void*)(&parseContextLocal));
- if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
+ if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
return 1;
else
return 0;
@@ -318,7 +318,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon
return 0;
}
-void yyerror(char *s)
+void yyerror(const char *s)
{
if (((TParseContext *)cpp->pC)->AfterEOF) {
if (cpp->tokensBeforeEOF == 1) {
diff --git a/ANGLE/src/compiler/glslang.y b/ANGLE/src/compiler/glslang.y
index a297ad2..d0d29df 100644
--- a/ANGLE/src/compiler/glslang.y
+++ b/ANGLE/src/compiler/glslang.y
@@ -38,7 +38,7 @@ compiler/tools. Remove it when we can exclusively use the newer version.
#define parseContext ((TParseContext*)(parseContextLocal))
#define YYLEX_PARAM parseContextLocal
#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-extern void yyerror(char*);
+extern void yyerror(const char*);
#define FRAG_VERT_ONLY(S, L) { \
if (parseContext->language != EShLangFragment && \
@@ -311,7 +311,7 @@ postfix_expression
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
if ($1->getType().getQualifier() == EvqConst)
- $$->getTypePointer()->changeQualifier(EvqConst);
+ $$->getTypePointer()->setQualifier(EvqConst);
} else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, $1->getNominalSize()));
else if ($1->isMatrix())
@@ -389,7 +389,7 @@ postfix_expression
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
- TTypeList* fields = $1->getType().getStruct();
+ const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) {
parseContext->error($2.line, "structure has no fields", "Internal Error", "");
parseContext->recover();
@@ -413,7 +413,7 @@ postfix_expression
$$->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
- $$->getTypePointer()->changeQualifier(EvqConst);
+ $$->getTypePointer()->setQualifier(EvqConst);
}
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
@@ -673,7 +673,7 @@ function_identifier
break;
}
if (op == EOpNull) {
- parseContext->error($1.line, "cannot construct this type", TType::getBasicString($1.type), "");
+ parseContext->error($1.line, "cannot construct this type", getBasicString($1.type), "");
parseContext->recover();
$1.type = EbtFloat;
op = EOpConstructFloat;
@@ -1007,12 +1007,12 @@ declaration
}
}
- prototype->setOperator(EOpPrototype);
+ prototype->setOp(EOpPrototype);
$$ = prototype;
}
| init_declarator_list SEMICOLON {
if ($1.intermAggregate)
- $1.intermAggregate->setOperator(EOpDeclaration);
+ $1.intermAggregate->setOp(EOpDeclaration);
$$ = $1.intermAggregate;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
@@ -1795,19 +1795,24 @@ struct_declaration
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
- // Careful not to replace already know aspects of type, like array-ness
+ // Careful not to replace already known aspects of type, like array-ness
//
- (*$$)[i].type->setType($1.type, $1.size, $1.matrix, $1.userDef);
+ TType* type = (*$$)[i].type;
+ type->setBasicType($1.type);
+ type->setNominalSize($1.size);
+ type->setMatrix($1.matrix);
// don't allow arrays of arrays
- if ((*$$)[i].type->isArray()) {
+ if (type->isArray()) {
if (parseContext->arrayTypeErrorCheck($1.line, $1))
parseContext->recover();
}
if ($1.array)
- (*$$)[i].type->setArraySize($1.arraySize);
- if ($1.userDef)
- (*$$)[i].type->setTypeName($1.userDef->getTypeName());
+ type->setArraySize($1.arraySize);
+ if ($1.userDef) {
+ type->setStruct($1.userDef->getStruct());
+ type->setTypeName($1.userDef->getTypeName());
+ }
}
}
;
@@ -1873,7 +1878,7 @@ compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { parseContext->symbolTable.push(); } statement_list { parseContext->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0)
- $3->setOperator(EOpSequence);
+ $3->setOp(EOpSequence);
$$ = $3;
}
;
@@ -1890,7 +1895,7 @@ compound_statement_no_new_scope
}
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2)
- $2->setOperator(EOpSequence);
+ $2->setOp(EOpSequence);
$$ = $2;
}
;
diff --git a/ANGLE/src/compiler/intermediate.h b/ANGLE/src/compiler/intermediate.h
index c83fc48..d262905 100644
--- a/ANGLE/src/compiler/intermediate.h
+++ b/ANGLE/src/compiler/intermediate.h
@@ -203,8 +203,10 @@ public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TIntermNode() : line(0) {}
- virtual TSourceLoc getLine() const { return line; }
- virtual void setLine(TSourceLoc l) { line = l; }
+
+ TSourceLoc getLine() const { return line; }
+ void setLine(TSourceLoc l) { line = l; }
+
virtual void traverse(TIntermTraverser*) = 0;
virtual TIntermTyped* getAsTyped() { return 0; }
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
@@ -215,6 +217,7 @@ public:
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual TIntermLoop* getAsLoopNode() { return 0; }
virtual ~TIntermNode() { }
+
protected:
TSourceLoc line;
};
@@ -233,22 +236,23 @@ struct TIntermNodePair {
class TIntermTyped : public TIntermNode {
public:
TIntermTyped(const TType& t) : type(t) { }
- virtual TIntermTyped* getAsTyped() { return this; }
- virtual void setType(const TType& t) { type = t; }
- virtual const TType& getType() const { return type; }
- virtual TType* getTypePointer() { return &type; }
-
- virtual TBasicType getBasicType() const { return type.getBasicType(); }
- virtual TQualifier getQualifier() const { return type.getQualifier(); }
- virtual TPrecision getPrecision() const { return type.getPrecision(); }
- virtual int getNominalSize() const { return type.getNominalSize(); }
- virtual int getSize() const { return type.getInstanceSize(); }
- virtual bool isMatrix() const { return type.isMatrix(); }
- virtual bool isArray() const { return type.isArray(); }
- virtual bool isVector() const { return type.isVector(); }
- virtual bool isScalar() const { return type.isScalar(); }
- const char* getBasicString() const { return type.getBasicString(); }
- const char* getQualifierString() const { return type.getQualifierString(); }
+ virtual TIntermTyped* getAsTyped() { return this; }
+
+ void setType(const TType& t) { type = t; }
+ const TType& getType() const { return type; }
+ TType* getTypePointer() { return &type; }
+
+ TBasicType getBasicType() const { return type.getBasicType(); }
+ TQualifier getQualifier() const { return type.getQualifier(); }
+ TPrecision getPrecision() const { return type.getPrecision(); }
+ int getNominalSize() const { return type.getNominalSize(); }
+
+ bool isMatrix() const { return type.isMatrix(); }
+ bool isArray() const { return type.isArray(); }
+ bool isVector() const { return type.isVector(); }
+ bool isScalar() const { return type.isScalar(); }
+ const char* getBasicString() const { return type.getBasicString(); }
+ const char* getQualifierString() const { return type.getQualifierString(); }
TString getCompleteString() const { return type.getCompleteString(); }
protected:
@@ -266,13 +270,16 @@ public:
test(aTest),
terminal(aTerminal),
first(testFirst) { }
+
virtual TIntermLoop* getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser*);
+
TIntermNode *getInit() { return init; }
TIntermNode *getBody() { return body; }
TIntermTyped *getTest() { return test; }
TIntermTyped *getTerminal() { return terminal; }
bool testFirst() { return first; }
+
protected:
TIntermNode *init;
TIntermNode *body; // code to loop over
@@ -289,9 +296,12 @@ public:
TIntermBranch(TOperator op, TIntermTyped* e) :
flowOp(op),
expression(e) { }
+
virtual void traverse(TIntermTraverser*);
+
TOperator getFlowOp() { return flowOp; }
TIntermTyped* getExpression() { return expression; }
+
protected:
TOperator flowOp;
TIntermTyped* expression; // non-zero except for "return exp;" statements
@@ -307,10 +317,13 @@ public:
// it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int i, const TString& sym, const TType& t) :
TIntermTyped(t), id(i) { symbol = sym;}
- virtual int getId() const { return id; }
- virtual const TString& getSymbol() const { return symbol; }
+
+ int getId() const { return id; }
+ const TString& getSymbol() const { return symbol; }
+
virtual void traverse(TIntermTraverser*);
virtual TIntermSymbol* getAsSymbolNode() { return this; }
+
protected:
int id;
TString symbol;
@@ -319,11 +332,15 @@ protected:
class TIntermConstantUnion : public TIntermTyped {
public:
TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
+
ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
+
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
- virtual void traverse(TIntermTraverser* );
- virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+ virtual void traverse(TIntermTraverser*);
+
+ TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+
protected:
ConstantUnion *unionArrayPointer;
};
@@ -334,9 +351,11 @@ protected:
class TIntermOperator : public TIntermTyped {
public:
TOperator getOp() const { return op; }
+ void setOp(TOperator o) { op = o; }
+
bool modifiesState() const;
bool isConstructor() const;
- virtual bool promote(TInfoSink&) { return true; }
+
protected:
TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
@@ -349,13 +368,16 @@ protected:
class TIntermBinary : public TIntermOperator {
public:
TIntermBinary(TOperator o) : TIntermOperator(o) {}
- virtual void traverse(TIntermTraverser*);
- virtual void setLeft(TIntermTyped* n) { left = n; }
- virtual void setRight(TIntermTyped* n) { right = n; }
- virtual TIntermTyped* getLeft() const { return left; }
- virtual TIntermTyped* getRight() const { return right; }
+
virtual TIntermBinary* getAsBinaryNode() { return this; }
- virtual bool promote(TInfoSink&);
+ virtual void traverse(TIntermTraverser*);
+
+ void setLeft(TIntermTyped* n) { left = n; }
+ void setRight(TIntermTyped* n) { right = n; }
+ TIntermTyped* getLeft() const { return left; }
+ TIntermTyped* getRight() const { return right; }
+ bool promote(TInfoSink&);
+
protected:
TIntermTyped* left;
TIntermTyped* right;
@@ -368,11 +390,14 @@ class TIntermUnary : public TIntermOperator {
public:
TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
+
virtual void traverse(TIntermTraverser*);
- virtual void setOperand(TIntermTyped* o) { operand = o; }
- virtual TIntermTyped* getOperand() { return operand; }
virtual TIntermUnary* getAsUnaryNode() { return this; }
- virtual bool promote(TInfoSink&);
+
+ void setOperand(TIntermTyped* o) { operand = o; }
+ TIntermTyped* getOperand() { return operand; }
+ bool promote(TInfoSink&);
+
protected:
TIntermTyped* operand;
};
@@ -387,21 +412,24 @@ public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
~TIntermAggregate() { delete pragmaTable; }
+
virtual TIntermAggregate* getAsAggregate() { return this; }
- virtual void setOperator(TOperator o) { op = o; }
- virtual TIntermSequence& getSequence() { return sequence; }
- virtual void setName(const TString& n) { name = n; }
- virtual const TString& getName() const { return name; }
virtual void traverse(TIntermTraverser*);
- virtual void setUserDefined() { userDefined = true; }
- virtual bool isUserDefined() { return userDefined; }
- virtual TQualifierList& getQualifier() { return qualifier; }
+
+ TIntermSequence& getSequence() { return sequence; }
+ void setName(const TString& n) { name = n; }
+ const TString& getName() const { return name; }
+
+ void setUserDefined() { userDefined = true; }
+ bool isUserDefined() { return userDefined; }
+ TQualifierList& getQualifier() { return qualifier; }
void setOptimize(bool o) { optimize = o; }
- void setDebug(bool d) { debug = d; }
bool getOptimize() { return optimize; }
+ void setDebug(bool d) { debug = d; }
bool getDebug() { return debug; }
void addToPragmaTable(const TPragmaTable& pTable);
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
+
protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
@@ -423,12 +451,15 @@ public:
TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+
virtual void traverse(TIntermTraverser*);
+
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
- virtual TIntermNode* getCondition() const { return condition; }
- virtual TIntermNode* getTrueBlock() const { return trueBlock; }
- virtual TIntermNode* getFalseBlock() const { return falseBlock; }
- virtual TIntermSelection* getAsSelectionNode() { return this; }
+ TIntermNode* getCondition() const { return condition; }
+ TIntermNode* getTrueBlock() const { return trueBlock; }
+ TIntermNode* getFalseBlock() const { return falseBlock; }
+ TIntermSelection* getAsSelectionNode() { return this; }
+
protected:
TIntermTyped* condition;
TIntermNode* trueBlock;
diff --git a/ANGLE/src/compiler/parseConst.cpp b/ANGLE/src/compiler/parseConst.cpp
index 833d429..9a8a50c 100644
--- a/ANGLE/src/compiler/parseConst.cpp
+++ b/ANGLE/src/compiler/parseConst.cpp
@@ -12,23 +12,31 @@
//
class TConstTraverser : public TIntermTraverser {
public:
- TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
- constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0)
- {
- index = 0;
- }
+ TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t)
+ : error(false),
+ index(0),
+ unionArray(cUnion),
+ type(t),
+ constructorType(constructType),
+ singleConstantParam(singleConstParam),
+ infoSink(sink),
+ symbolTable(symTable),
+ size(0),
+ isMatrix(false),
+ matrixSize(0) {
+ }
- bool error;
+ bool error;
protected:
- void visitSymbol(TIntermSymbol*);
- void visitConstantUnion(TIntermConstantUnion*);
- bool visitBinary(Visit visit, TIntermBinary*);
- bool visitUnary(Visit visit, TIntermUnary*);
- bool visitSelection(Visit visit, TIntermSelection*);
- bool visitAggregate(Visit visit, TIntermAggregate*);
- bool visitLoop(Visit visit, TIntermLoop*);
- bool visitBranch(Visit visit, TIntermBranch*);
+ void visitSymbol(TIntermSymbol*);
+ void visitConstantUnion(TIntermConstantUnion*);
+ bool visitBinary(Visit visit, TIntermBinary*);
+ bool visitUnary(Visit visit, TIntermUnary*);
+ bool visitSelection(Visit visit, TIntermSelection*);
+ bool visitAggregate(Visit visit, TIntermAggregate*);
+ bool visitLoop(Visit visit, TIntermLoop*);
+ bool visitBranch(Visit visit, TIntermBranch*);
int index;
ConstantUnion *unionArray;
diff --git a/ANGLE/src/compiler/preprocessor/atom.c b/ANGLE/src/compiler/preprocessor/atom.c
index 32b9c74..c5636b7 100644
--- a/ANGLE/src/compiler/preprocessor/atom.c
+++ b/ANGLE/src/compiler/preprocessor/atom.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
@@ -624,7 +619,7 @@ static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
int InitAtomTable(AtomTable *atable, int htsize)
{
- int ii;
+ unsigned int ii;
htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
if (!InitStringTable(&atable->stable))
diff --git a/ANGLE/src/compiler/preprocessor/atom.h b/ANGLE/src/compiler/preprocessor/atom.h
index 9d42037..1d84c32 100644
--- a/ANGLE/src/compiler/preprocessor/atom.h
+++ b/ANGLE/src/compiler/preprocessor/atom.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/compile.h b/ANGLE/src/compiler/preprocessor/compile.h
index a40b99e..5bfa902 100644
--- a/ANGLE/src/compiler/preprocessor/compile.h
+++ b/ANGLE/src/compiler/preprocessor/compile.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/cpp.c b/ANGLE/src/compiler/preprocessor/cpp.c
index 6bf8e65..f15c56d 100644
--- a/ANGLE/src/compiler/preprocessor/cpp.c
+++ b/ANGLE/src/compiler/preprocessor/cpp.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/cpp.h b/ANGLE/src/compiler/preprocessor/cpp.h
index 658475e..db4c184 100644
--- a/ANGLE/src/compiler/preprocessor/cpp.h
+++ b/ANGLE/src/compiler/preprocessor/cpp.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/cppstruct.c b/ANGLE/src/compiler/preprocessor/cppstruct.c
index afbc477..8e142bc 100644
--- a/ANGLE/src/compiler/preprocessor/cppstruct.c
+++ b/ANGLE/src/compiler/preprocessor/cppstruct.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/memory.c b/ANGLE/src/compiler/preprocessor/memory.c
index 393a0d0..e6fea7a 100644
--- a/ANGLE/src/compiler/preprocessor/memory.c
+++ b/ANGLE/src/compiler/preprocessor/memory.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/memory.h b/ANGLE/src/compiler/preprocessor/memory.h
index e7f5b75..b3ae2f9 100644
--- a/ANGLE/src/compiler/preprocessor/memory.h
+++ b/ANGLE/src/compiler/preprocessor/memory.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/parser.h b/ANGLE/src/compiler/preprocessor/parser.h
index 91a6200..f67342b 100644
--- a/ANGLE/src/compiler/preprocessor/parser.h
+++ b/ANGLE/src/compiler/preprocessor/parser.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/preprocess.h b/ANGLE/src/compiler/preprocessor/preprocess.h
index 3dd605b..0602c91 100644
--- a/ANGLE/src/compiler/preprocessor/preprocess.h
+++ b/ANGLE/src/compiler/preprocessor/preprocess.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/scanner.c b/ANGLE/src/compiler/preprocessor/scanner.c
index 0944da5..c77d271 100644
--- a/ANGLE/src/compiler/preprocessor/scanner.c
+++ b/ANGLE/src/compiler/preprocessor/scanner.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/scanner.h b/ANGLE/src/compiler/preprocessor/scanner.h
index c422b3a..571fe57 100644
--- a/ANGLE/src/compiler/preprocessor/scanner.h
+++ b/ANGLE/src/compiler/preprocessor/scanner.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/slglobals.h b/ANGLE/src/compiler/preprocessor/slglobals.h
index a535180..4634626 100644
--- a/ANGLE/src/compiler/preprocessor/slglobals.h
+++ b/ANGLE/src/compiler/preprocessor/slglobals.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/symbols.c b/ANGLE/src/compiler/preprocessor/symbols.c
index 1193abb..5baedf5 100644
--- a/ANGLE/src/compiler/preprocessor/symbols.c
+++ b/ANGLE/src/compiler/preprocessor/symbols.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
@@ -157,7 +152,7 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
{
Symbol *lSymb;
char *pch;
- int ii;
+ unsigned int ii;
lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
lSymb->left = NULL;
diff --git a/ANGLE/src/compiler/preprocessor/symbols.h b/ANGLE/src/compiler/preprocessor/symbols.h
index 41e0778..c19f79c 100644
--- a/ANGLE/src/compiler/preprocessor/symbols.h
+++ b/ANGLE/src/compiler/preprocessor/symbols.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/tokens.c b/ANGLE/src/compiler/preprocessor/tokens.c
index 7cfc73d..057cce8 100644
--- a/ANGLE/src/compiler/preprocessor/tokens.c
+++ b/ANGLE/src/compiler/preprocessor/tokens.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
@@ -210,7 +205,7 @@ void DeleteTokenStream(TokenStream *pTok)
void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
{
const char *s;
- unsigned char *str=NULL;
+ char *str=NULL;
if (token > 256)
lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
diff --git a/ANGLE/src/compiler/preprocessor/tokens.h b/ANGLE/src/compiler/preprocessor/tokens.h
index 8d7e712..8766df9 100644
--- a/ANGLE/src/compiler/preprocessor/tokens.h
+++ b/ANGLE/src/compiler/preprocessor/tokens.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/libEGL/Display.cpp b/ANGLE/src/libEGL/Display.cpp
index 287d8da..e2802da 100644
--- a/ANGLE/src/libEGL/Display.cpp
+++ b/ANGLE/src/libEGL/Display.cpp
@@ -23,8 +23,12 @@ namespace egl
{
Display::Display(HDC deviceContext) : mDc(deviceContext)
{
+ mD3d9Module = NULL;
+
mD3d9 = NULL;
+ mD3d9ex = NULL;
mDevice = NULL;
+ mDeviceWindow = NULL;
mAdapter = D3DADAPTER_DEFAULT;
@@ -51,7 +55,38 @@ bool Display::initialize()
return true;
}
- mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+ mD3d9Module = LoadLibrary(TEXT("d3d9.dll"));
+ if (mD3d9Module == NULL)
+ {
+ terminate();
+ return false;
+ }
+
+ typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT);
+ Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9"));
+
+ if (Direct3DCreate9Ptr == NULL)
+ {
+ terminate();
+ return false;
+ }
+
+ typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
+ Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
+
+ // Use Direct3D9Ex if available. Among other things, this version is less
+ // inclined to report a lost context, for example when the user switches
+ // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
+ if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+ {
+ ASSERT(mD3d9ex);
+ mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+ ASSERT(mD3d9);
+ }
+ else
+ {
+ mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION);
+ }
if (mD3d9)
{
@@ -69,86 +104,91 @@ bool Display::initialize()
if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
{
- mD3d9->Release();
- mD3d9 = NULL;
+ terminate();
+ return error(EGL_NOT_INITIALIZED, false);
}
- else
- {
- mMinSwapInterval = 4;
- mMaxSwapInterval = 0;
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
+ mMinSwapInterval = 4;
+ mMaxSwapInterval = 0;
- const D3DFORMAT renderTargetFormats[] =
- {
- D3DFMT_A1R5G5B5,
- // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
- D3DFMT_A8R8G8B8,
- D3DFMT_R5G6B5,
- D3DFMT_X1R5G5B5,
- D3DFMT_X8R8G8B8
- };
-
- const D3DFORMAT depthStencilFormats[] =
- {
- // D3DFMT_D16_LOCKABLE,
- D3DFMT_D32,
- // D3DFMT_D15S1,
- D3DFMT_D24S8,
- D3DFMT_D24X8,
- // D3DFMT_D24X4S4,
- D3DFMT_D16,
- // D3DFMT_D32F_LOCKABLE,
- // D3DFMT_D24FS8
- };
-
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- ConfigSet configSet;
-
- for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
- {
- D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
+
+ const D3DFORMAT renderTargetFormats[] =
+ {
+ D3DFMT_A1R5G5B5,
+ // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
+ D3DFMT_A8R8G8B8,
+ D3DFMT_R5G6B5,
+ D3DFMT_X1R5G5B5,
+ D3DFMT_X8R8G8B8
+ };
+
+ const D3DFORMAT depthStencilFormats[] =
+ {
+ // D3DFMT_D16_LOCKABLE,
+ D3DFMT_D32,
+ // D3DFMT_D15S1,
+ D3DFMT_D24S8,
+ D3DFMT_D24X8,
+ // D3DFMT_D24X4S4,
+ D3DFMT_D16,
+ // D3DFMT_D32F_LOCKABLE,
+ // D3DFMT_D24FS8
+ };
+
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ ConfigSet configSet;
+
+ for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
+ {
+ D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
- HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
+ HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
- if (SUCCEEDED(result))
+ if (SUCCEEDED(result))
+ {
+ for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
{
- for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
+ D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
+ HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+
+ if (SUCCEEDED(result))
{
- D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
- HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+ HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
if (SUCCEEDED(result))
{
- HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+ // FIXME: enumerate multi-sampling
- if (SUCCEEDED(result))
- {
- // FIXME: Enumerate multi-sampling
-
- configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
- }
+ configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
}
}
}
}
+ }
- // Give the sorted configs a unique ID and store them internally
- EGLint index = 1;
- for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
- {
- Config configuration = *config;
- configuration.mConfigID = index;
- index++;
+ // Give the sorted configs a unique ID and store them internally
+ EGLint index = 1;
+ for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
+ {
+ Config configuration = *config;
+ configuration.mConfigID = index;
+ index++;
- mConfigSet.mSet.insert(configuration);
- }
+ mConfigSet.mSet.insert(configuration);
+ }
+
+ if (!createDevice())
+ {
+ terminate();
+
+ return false;
}
}
@@ -185,6 +225,24 @@ void Display::terminate()
mD3d9->Release();
mD3d9 = NULL;
}
+
+ if (mDeviceWindow)
+ {
+ DestroyWindow(mDeviceWindow);
+ mDeviceWindow = NULL;
+ }
+
+ if (mD3d9ex)
+ {
+ mD3d9ex->Release();
+ mD3d9ex = NULL;
+ }
+
+ if (mD3d9Module)
+ {
+ FreeLibrary(mD3d9Module);
+ mD3d9Module = NULL;
+ }
}
void Display::startScene()
@@ -254,132 +312,74 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
return true;
}
-Surface *Display::createWindowSurface(HWND window, EGLConfig config)
+bool Display::createDevice()
{
- const Config *configuration = mConfigSet.get(config);
+ static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
+ static const TCHAR className[] = TEXT("STATIC");
+
+ mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
D3DPRESENT_PARAMETERS presentParameters = {0};
- presentParameters.AutoDepthStencilFormat = configuration->mDepthStencilFormat;
+ // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
+ presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
presentParameters.BackBufferCount = 1;
- presentParameters.BackBufferFormat = configuration->mRenderTargetFormat;
- presentParameters.BackBufferWidth = 0;
- presentParameters.BackBufferHeight = 0;
- presentParameters.EnableAutoDepthStencil = configuration->mDepthSize ? TRUE : FALSE;
+ presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+ presentParameters.BackBufferWidth = 1;
+ presentParameters.BackBufferHeight = 1;
+ presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = window;
- presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
- presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
+ presentParameters.hDeviceWindow = mDeviceWindow;
+ presentParameters.MultiSampleQuality = 0;
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
- presentParameters.SwapEffect = D3DSWAPEFFECT_COPY;
- presentParameters.Windowed = TRUE; // FIXME
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
- IDirect3DSwapChain9 *swapChain = NULL;
- IDirect3DSurface9 *depthStencilSurface = NULL;
+ DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
- if (!mDevice)
+ HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
+ return error(EGL_BAD_ALLOC, false);
+ }
- HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, window, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
+ if (FAILED(result))
+ {
+ result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
-
- if (FAILED(result))
- {
- result = mD3d9->CreateDevice(mAdapter, mDeviceType, window, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
- }
-
- ASSERT(SUCCEEDED(result));
-
- if (mDevice)
- {
- mSceneStarted = false;
- mDevice->GetSwapChain(0, &swapChain);
- mDevice->GetDepthStencilSurface(&depthStencilSurface);
+ return error(EGL_BAD_ALLOC, false);
}
}
- else
- {
- if (!mSurfaceSet.empty())
- {
- // if the device already exists, and there are other surfaces/windows currently in use, we need to create
- // a separate swap chain for the new draw surface.
- HRESULT result = mDevice->CreateAdditionalSwapChain(&presentParameters, &swapChain);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- ERR("Could not create additional swap chains. Out of memory.");
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
-
- ASSERT(SUCCEEDED(result));
- // CreateAdditionalSwapChain does not automatically generate a depthstencil surface, unlike
- // CreateDevice, so we must do so explicitly.
- result = mDevice->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
- presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
- presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+ ASSERT(SUCCEEDED(result));
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- swapChain->Release();
- ERR("Could not create depthstencil surface for new swap chain. Out of memory.");
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
+ // Permanent non-default states
+ mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
- ASSERT(SUCCEEDED(result));
- }
- else
- {
- // if the device already exists, but there are no surfaces in use, then all the surfaces/windows
- // have been destroyed, and we should repurpose the originally created depthstencil surface for
- // use with the new surface we are creating.
- HRESULT result = mDevice->Reset(&presentParameters);
+ mSceneStarted = false;
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- ERR("Could not reset presentation parameters for device. Out of memory.");
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
-
- ASSERT(SUCCEEDED(result));
-
- if (mDevice)
- {
- mSceneStarted = false;
- mDevice->GetSwapChain(0, &swapChain);
- mDevice->GetDepthStencilSurface(&depthStencilSurface);
- }
- }
- }
-
- Surface *surface = NULL;
+ return true;
+}
- if (swapChain)
- {
- surface = new Surface(this, swapChain, depthStencilSurface, configuration);
- mSurfaceSet.insert(surface);
+Surface *Display::createWindowSurface(HWND window, EGLConfig config)
+{
+ const Config *configuration = mConfigSet.get(config);
- swapChain->Release();
- }
+ Surface *surface = new Surface(this, configuration, window);
+ mSurfaceSet.insert(surface);
return surface;
}
-EGLContext Display::createContext(EGLConfig configHandle)
+EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
{
const egl::Config *config = mConfigSet.get(configHandle);
- gl::Context *context = glCreateContext(config);
+ gl::Context *context = glCreateContext(config, shareContext);
mContextSet.insert(context);
return context;
@@ -468,4 +468,23 @@ D3DCAPS9 Display::getDeviceCaps()
{
return mDeviceCaps;
}
+
+void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
+{
+ for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
+ {
+ HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
+ TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
+
+ multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
+ }
+}
+
+bool Display::getCompressedTextureSupport()
+{
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
+}
}
diff --git a/ANGLE/src/libEGL/Display.h b/ANGLE/src/libEGL/Display.h
index 02c9fde..bd33012 100644
--- a/ANGLE/src/libEGL/Display.h
+++ b/ANGLE/src/libEGL/Display.h
@@ -43,7 +43,7 @@ class Display
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
egl::Surface *createWindowSurface(HWND window, EGLConfig config);
- EGLContext createContext(EGLConfig configHandle);
+ EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
void destroySurface(egl::Surface *surface);
void destroyContext(gl::Context *context);
@@ -60,16 +60,22 @@ class Display
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
+ virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
+ virtual bool getCompressedTextureSupport();
private:
DISALLOW_COPY_AND_ASSIGN(Display);
const HDC mDc;
+ HMODULE mD3d9Module;
+
UINT mAdapter;
D3DDEVTYPE mDeviceType;
- IDirect3D9 *mD3d9;
+ IDirect3D9 *mD3d9; // Always valid after successful initialization.
+ IDirect3D9Ex *mD3d9ex; // Might be null if D3D9Ex is not supported.
IDirect3DDevice9 *mDevice;
D3DCAPS9 mDeviceCaps;
+ HWND mDeviceWindow;
bool mSceneStarted;
GLint mSwapInterval;
@@ -84,6 +90,8 @@ class Display
typedef std::set<gl::Context*> ContextSet;
ContextSet mContextSet;
+
+ bool createDevice();
};
}
diff --git a/ANGLE/src/libEGL/Surface.cpp b/ANGLE/src/libEGL/Surface.cpp
index ef5c6c7..a5638d4 100644
--- a/ANGLE/src/libEGL/Surface.cpp
+++ b/ANGLE/src/libEGL/Surface.cpp
@@ -17,9 +17,11 @@
namespace egl
{
-Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, const Config *config)
- : mDisplay(display), mSwapChain(swapChain), mDepthStencil(depthStencil), mConfig(config)
+Surface::Surface(Display *display, const Config *config, HWND window)
+ : mDisplay(display), mConfig(config), mWindow(window)
{
+ mSwapChain = NULL;
+ mDepthStencil = NULL;
mBackBuffer = NULL;
mRenderTarget = NULL;
mFlipTexture = NULL;
@@ -30,42 +32,7 @@ Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurf
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
- if (mSwapChain)
- {
- mSwapChain->AddRef();
- mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
-
- D3DSURFACE_DESC description;
- mBackBuffer->GetDesc(&description);
-
- mWidth = description.Width;
- mHeight = description.Height;
-
- IDirect3DDevice9 *device = display->getDevice();
- HRESULT result = device->CreateRenderTarget(mWidth, mHeight, description.Format, description.MultiSampleType, description.MultiSampleQuality, FALSE, &mRenderTarget, NULL);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- error(EGL_BAD_ALLOC);
-
- return;
- }
-
- ASSERT(SUCCEEDED(result));
-
- result = device->CreateTexture(mWidth, mHeight, 1, D3DUSAGE_RENDERTARGET, description.Format, D3DPOOL_DEFAULT, &mFlipTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-
- error(EGL_BAD_ALLOC);
-
- mRenderTarget->Release();
-
- return;
- }
- }
+ resetSwapChain();
}
Surface::~Surface()
@@ -106,20 +73,121 @@ Surface::~Surface()
}
}
-HWND Surface::getWindowHandle()
+void Surface::resetSwapChain()
{
- if (mSwapChain)
+ IDirect3DDevice9 *device = mDisplay->getDevice();
+
+ D3DPRESENT_PARAMETERS presentParameters = {0};
+
+ presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
+ presentParameters.BackBufferCount = 1;
+ presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
+ presentParameters.EnableAutoDepthStencil = FALSE;
+ presentParameters.Flags = 0;
+ presentParameters.hDeviceWindow = getWindowHandle();
+ presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
+ presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval);
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
+
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+ ASSERT(false);
+ return;
+ }
+
+ presentParameters.BackBufferWidth = windowRect.right - windowRect.left;
+ presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top;
+
+ IDirect3DSwapChain9 *swapChain = NULL;
+ HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &swapChain);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ ERR("Could not create additional swap chains: %08lX", result);
+ return error(EGL_BAD_ALLOC);
+ }
+
+ IDirect3DSurface9 *depthStencilSurface = NULL;
+ result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
+ presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
+ presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ swapChain->Release();
+
+ ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
+ return error(EGL_BAD_ALLOC);
+ }
+
+ IDirect3DSurface9 *renderTarget = NULL;
+ result = device->CreateRenderTarget(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.BackBufferFormat,
+ presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &renderTarget, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ swapChain->Release();
+ depthStencilSurface->Release();
+
+ ERR("Could not create render target surface for new swap chain: %08lX", result);
+ return error(EGL_BAD_ALLOC);
+ }
+
+ ASSERT(SUCCEEDED(result));
+
+ IDirect3DTexture9 *flipTexture = NULL;
+ result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
+ presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &flipTexture, NULL);
+
+ if (FAILED(result))
{
- D3DPRESENT_PARAMETERS presentParameters;
- mSwapChain->GetPresentParameters(&presentParameters);
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ swapChain->Release();
+ depthStencilSurface->Release();
+ renderTarget->Release();
- return presentParameters.hDeviceWindow;
+ ERR("Could not create flip texture for new swap chain: %08lX", result);
+ return error(EGL_BAD_ALLOC);
}
- return NULL;
+ IDirect3DSurface9 *backBuffer = NULL;
+ swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
+
+ if (mSwapChain) mSwapChain->Release();
+ if (mDepthStencil) mDepthStencil->Release();
+ if (mBackBuffer) mBackBuffer->Release();
+ if (mRenderTarget) mRenderTarget->Release();
+ if (mFlipTexture) mFlipTexture->Release();
+
+ mWidth = presentParameters.BackBufferWidth;
+ mHeight = presentParameters.BackBufferHeight;
+
+ mSwapChain = swapChain;
+ mDepthStencil = depthStencilSurface;
+ mBackBuffer = backBuffer;
+ mRenderTarget = renderTarget;
+ mFlipTexture = flipTexture;
+
+ // The flip state block recorded mFlipTexture so it is now invalid.
+ releaseRecordedState(device);
+}
+
+HWND Surface::getWindowHandle()
+{
+ return mWindow;
}
-void Surface::writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source)
+void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
{
// Disable all pipeline operations
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
@@ -138,16 +206,18 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTextur
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- device->SetTexture(0, source);
+ device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
device->SetStreamSourceFreq(0, 1); // DrawPrimitiveUP only cares about stream 0, not the rest.
}
-void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source)
+void Surface::applyFlipState(IDirect3DDevice9 *device)
{
HRESULT hr;
@@ -158,7 +228,7 @@ void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source
// mPreFlipState will record the original state each entry.
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr));
- writeRecordableFlipState(device, source);
+ writeRecordableFlipState(device);
hr = device->EndStateBlock(&mPreFlipState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -171,7 +241,7 @@ void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr));
- writeRecordableFlipState(device, source);
+ writeRecordableFlipState(device);
hr = device->EndStateBlock(&mFlipState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -223,29 +293,88 @@ void Surface::restoreState(IDirect3DDevice9 *device)
}
}
+// On the next flip, this will cause the state to be recorded from scratch.
+// In particular we need to do this if the flip texture changes.
+void Surface::releaseRecordedState(IDirect3DDevice9 *device)
+{
+ if (mFlipState)
+ {
+ mFlipState->Release();
+ mFlipState = NULL;
+ }
+
+ if (mPreFlipState)
+ {
+ mPreFlipState->Release();
+ mPreFlipState = NULL;
+ }
+}
+
+bool Surface::checkForWindowResize()
+{
+ RECT client;
+ if (!GetClientRect(getWindowHandle(), &client))
+ {
+ ASSERT(false);
+ return false;
+ }
+
+ if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top)
+ {
+ resetSwapChain();
+
+ if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
+ {
+ glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
bool Surface::swap()
{
if (mSwapChain)
{
+ IDirect3DTexture9 *flipTexture = mFlipTexture;
+ flipTexture->AddRef();
+
+ IDirect3DSurface9 *renderTarget = mRenderTarget;
+ renderTarget->AddRef();
+
+ EGLint oldWidth = mWidth;
+ EGLint oldHeight = mHeight;
+
+ checkForWindowResize();
+
IDirect3DDevice9 *device = mDisplay->getDevice();
IDirect3DSurface9 *textureSurface;
- mFlipTexture->GetSurfaceLevel(0, &textureSurface);
+ flipTexture->GetSurfaceLevel(0, &textureSurface);
mDisplay->endScene();
- device->StretchRect(mRenderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
+ device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
+ renderTarget->Release();
- applyFlipState(device, mFlipTexture);
+ applyFlipState(device);
+ device->SetTexture(0, flipTexture);
+
+ float xscale = (float)mWidth / oldWidth;
+ float yscale = (float)mHeight / oldHeight;
// Render the texture upside down into the back buffer
- float quad[4][6] = {{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
- {mWidth - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
- {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
- { 0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}}; // x, y, z, rhw, u, v
+ // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling.
+ float quad[4][6] = {{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
+ {mWidth - 0.5f, 0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f },
+ {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale},
+ { 0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f-yscale}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
+ flipTexture->Release();
textureSurface->Release();
restoreState(device);
@@ -264,6 +393,7 @@ bool Surface::swap()
}
ASSERT(SUCCEEDED(result));
+
}
return true;
diff --git a/ANGLE/src/libEGL/Surface.h b/ANGLE/src/libEGL/Surface.h
index 8c684a0..5bc912c 100644
--- a/ANGLE/src/libEGL/Surface.h
+++ b/ANGLE/src/libEGL/Surface.h
@@ -25,7 +25,7 @@ class Config;
class Surface
{
public:
- Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9* depthStencil, const egl::Config *config);
+ Surface(Display *display, const egl::Config *config, HWND window);
~Surface();
@@ -42,20 +42,25 @@ class Surface
DISALLOW_COPY_AND_ASSIGN(Surface);
Display *const mDisplay;
- IDirect3DSwapChain9 *const mSwapChain;
+ IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
IDirect3DSurface9 *mRenderTarget;
IDirect3DSurface9 *mDepthStencil;
IDirect3DTexture9 *mFlipTexture;
- void applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source);
+ void resetSwapChain();
+ bool checkForWindowResize();
+
+ void applyFlipState(IDirect3DDevice9 *device);
void restoreState(IDirect3DDevice9 *device);
- void writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source);
+ void writeRecordableFlipState(IDirect3DDevice9 *device);
+ void releaseRecordedState(IDirect3DDevice9 *device);
IDirect3DStateBlock9 *mFlipState;
IDirect3DStateBlock9 *mPreFlipState;
IDirect3DSurface9 *mPreFlipBackBuffer;
IDirect3DSurface9 *mPreFlipDepthStencil;
+ const HWND mWindow; // Window that the surface is created for.
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
EGLint mWidth; // Width of surface
diff --git a/ANGLE/src/libEGL/libEGL.cpp b/ANGLE/src/libEGL/libEGL.cpp
index 5c2cc1d..5ceb6ef 100644
--- a/ANGLE/src/libEGL/libEGL.cpp
+++ b/ANGLE/src/libEGL/libEGL.cpp
@@ -772,7 +772,7 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return EGL_NO_CONTEXT;
}
- EGLContext context = display->createContext(config);
+ EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
return success(context);
}
@@ -824,9 +824,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx);
IDirect3DDevice9 *device = display->getDevice();
- DWORD passes;
- if (!device || device->ValidateDevice(&passes) == D3DERR_DEVICELOST)
+ if (!device || device->TestCooperativeLevel() != D3D_OK)
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
diff --git a/ANGLE/src/libEGL/libEGL.vcproj b/ANGLE/src/libEGL/libEGL.vcproj
index 30e6183..505f4d9 100644
--- a/ANGLE/src/libEGL/libEGL.vcproj
+++ b/ANGLE/src/libEGL/libEGL.vcproj
@@ -62,7 +62,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="d3d9.lib"
+ AdditionalDependencies="dxguid.lib"
LinkIncremental="2"
ModuleDefinitionFile="libEGL.def"
GenerateDebugInformation="true"
@@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="d3d9.lib"
+ AdditionalDependencies="dxguid.lib"
LinkIncremental="1"
ModuleDefinitionFile="libEGL.def"
GenerateDebugInformation="true"
diff --git a/ANGLE/src/libGLESv2/Blit.cpp b/ANGLE/src/libGLESv2/Blit.cpp
index 92bde05..00c878f 100644
--- a/ANGLE/src/libGLESv2/Blit.cpp
+++ b/ANGLE/src/libGLESv2/Blit.cpp
@@ -232,12 +232,12 @@ bool Blit::setShader(ShaderId source, const char *profile,
bool Blit::setVertexShader(ShaderId shader)
{
- return setShader<IDirect3DVertexShader9>(shader, mContext->getVertexShaderProfile(), &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader);
+ return setShader<IDirect3DVertexShader9>(shader, mContext->supportsShaderModel3() ? "vs_3_0" : "vs_2_0", &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader);
}
bool Blit::setPixelShader(ShaderId shader)
{
- return setShader<IDirect3DPixelShader9>(shader, mContext->getPixelShaderProfile(), &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader);
+ return setShader<IDirect3DPixelShader9>(shader, mContext->supportsShaderModel3() ? "ps_3_0" : "ps_2_0", &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader);
}
RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
@@ -325,6 +325,7 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
{
default: UNREACHABLE();
case GL_RGBA:
+ case GL_BGRA_EXT:
case GL_RGB:
case GL_ALPHA:
okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
@@ -351,6 +352,7 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
{
default: UNREACHABLE();
case GL_RGBA:
+ case GL_BGRA_EXT:
psConst0[X] = 1;
psConst0[Z] = 1;
break;
diff --git a/ANGLE/src/libGLESv2/Buffer.cpp b/ANGLE/src/libGLESv2/Buffer.cpp
index 87d4185..43993e7 100644
--- a/ANGLE/src/libGLESv2/Buffer.cpp
+++ b/ANGLE/src/libGLESv2/Buffer.cpp
@@ -13,7 +13,7 @@
namespace gl
{
-Buffer::Buffer()
+Buffer::Buffer(GLuint id) : RefCountObject(id)
{
mContents = NULL;
mSize = 0;
diff --git a/ANGLE/src/libGLESv2/Buffer.h b/ANGLE/src/libGLESv2/Buffer.h
index 5fe0d75..5611cc9 100644
--- a/ANGLE/src/libGLESv2/Buffer.h
+++ b/ANGLE/src/libGLESv2/Buffer.h
@@ -18,14 +18,15 @@
#include <GLES2/gl2.h>
#include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
namespace gl
{
-class Buffer
+class Buffer : public RefCountObject
{
public:
- Buffer();
+ explicit Buffer(GLuint id);
virtual ~Buffer();
diff --git a/ANGLE/src/libGLESv2/Context.cpp b/ANGLE/src/libGLESv2/Context.cpp
index 55a83ff..48ef8fc 100644
--- a/ANGLE/src/libGLESv2/Context.cpp
+++ b/ANGLE/src/libGLESv2/Context.cpp
@@ -17,6 +17,7 @@
#include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/Blit.h"
+#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/FrameBuffer.h"
#include "libGLESv2/Program.h"
@@ -33,7 +34,7 @@
namespace gl
{
-Context::Context(const egl::Config *config)
+Context::Context(const egl::Config *config, const gl::Context *shareContext)
: mConfig(config)
{
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -103,37 +104,39 @@ Context::Context(const egl::Config *config)
mState.colorMaskAlpha = true;
mState.depthMask = true;
+ if (shareContext != NULL)
+ {
+ mResourceManager = shareContext->mResourceManager;
+ mResourceManager->addRef();
+ }
+ else
+ {
+ mResourceManager = new ResourceManager();
+ }
+
// [OpenGL ES 2.0.24] section 3.7 page 83:
// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
// and cube map texture state vectors respectively associated with them.
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mTexture2DZero = new Texture2D(this);
- mTextureCubeMapZero = new TextureCubeMap(this);
+ mTexture2DZero = new Texture2D(0);
+ mTextureCubeMapZero = new TextureCubeMap(0);
mColorbufferZero = NULL;
- mDepthbufferZero = NULL;
- mStencilbufferZero = NULL;
+ mDepthStencilbufferZero = NULL;
mState.activeSampler = 0;
- mState.arrayBuffer = 0;
- mState.elementArrayBuffer = 0;
+ bindArrayBuffer(0);
+ bindElementArrayBuffer(0);
bindTextureCubeMap(0);
bindTexture2D(0);
- bindFramebuffer(0);
+ bindReadFramebuffer(0);
+ bindDrawFramebuffer(0);
bindRenderbuffer(0);
for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
- {
- mState.samplerTexture[type][sampler] = 0;
- }
- }
-
- for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
- {
mIncompleteTextures[type] = NULL;
}
@@ -155,65 +158,72 @@ Context::Context(const egl::Config *config)
mHasBeenCurrent = false;
+ mMaxSupportedSamples = 0;
mMaskedClearSavedState = NULL;
markAllStateDirty();
}
Context::~Context()
{
- mState.currentProgram = 0;
-
- for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
+ if (mState.currentProgram != 0)
{
- delete mIncompleteTextures[type];
+ Program *programObject = mResourceManager->getProgram(mState.currentProgram);
+ if (programObject)
+ {
+ programObject->release();
+ }
+ mState.currentProgram = 0;
}
- delete mTexture2DZero;
- delete mTextureCubeMapZero;
-
- delete mColorbufferZero;
- delete mDepthbufferZero;
- delete mStencilbufferZero;
-
- delete mBufferBackEnd;
- delete mVertexDataManager;
- delete mIndexDataManager;
- delete mBlit;
-
- while (!mBufferMap.empty())
+ while (!mFramebufferMap.empty())
{
- deleteBuffer(mBufferMap.begin()->first);
+ deleteFramebuffer(mFramebufferMap.begin()->first);
}
- while (!mProgramMap.empty())
+ while (!mMultiSampleSupport.empty())
{
- deleteProgram(mProgramMap.begin()->first);
+ delete [] mMultiSampleSupport.begin()->second;
+ mMultiSampleSupport.erase(mMultiSampleSupport.begin());
}
- while (!mShaderMap.empty())
+ for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- deleteShader(mShaderMap.begin()->first);
+ for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
+ {
+ mState.samplerTexture[type][sampler].set(NULL);
+ }
}
- while (!mFramebufferMap.empty())
+ for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- deleteFramebuffer(mFramebufferMap.begin()->first);
+ delete mIncompleteTextures[type];
}
- while (!mRenderbufferMap.empty())
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- deleteRenderbuffer(mRenderbufferMap.begin()->first);
+ mState.vertexAttribute[i].mBoundBuffer.set(NULL);
}
- while (!mTextureMap.empty())
- {
- deleteTexture(mTextureMap.begin()->first);
- }
+ mState.arrayBuffer.set(NULL);
+ mState.elementArrayBuffer.set(NULL);
+ mState.texture2D.set(NULL);
+ mState.textureCubeMap.set(NULL);
+ mState.renderbuffer.set(NULL);
+
+ delete mTexture2DZero;
+ delete mTextureCubeMapZero;
+
+ delete mBufferBackEnd;
+ delete mVertexDataManager;
+ delete mIndexDataManager;
+ delete mBlit;
if (mMaskedClearSavedState)
{
mMaskedClearSavedState->Release();
}
+
+ mResourceManager->release();
}
void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
@@ -229,6 +239,34 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
mBlit = new Blit(this);
+ const D3DFORMAT renderBufferFormats[] =
+ {
+ D3DFMT_A8R8G8B8,
+ D3DFMT_X8R8G8B8,
+ D3DFMT_R5G6B5,
+ D3DFMT_D24S8
+ };
+
+ int max = 0;
+ for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i)
+ {
+ bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+ display->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
+ mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray;
+
+ for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
+ {
+ if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
+ {
+ max = j;
+ }
+ }
+ }
+
+ mMaxSupportedSamples = max;
+
+ mSupportsCompressedTextures = display->getCompressedTextureSupport();
+
initExtensionString();
mState.viewportX = 0;
@@ -248,19 +286,11 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget();
IDirect3DSurface9 *depthStencil = surface->getDepthStencil();
- Framebuffer *framebufferZero = new Framebuffer();
Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
- Depthbuffer *depthbufferZero = new Depthbuffer(depthStencil);
- Stencilbuffer *stencilbufferZero = new Stencilbuffer(depthStencil);
+ DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+ Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
setFramebufferZero(framebufferZero);
- setColorbufferZero(colorbufferZero);
- setDepthbufferZero(depthbufferZero);
- setStencilbufferZero(stencilbufferZero);
-
- framebufferZero->setColorbuffer(GL_RENDERBUFFER, 0);
- framebufferZero->setDepthbuffer(GL_RENDERBUFFER, 0);
- framebufferZero->setStencilbuffer(GL_RENDERBUFFER, 0);
defaultRenderTarget->Release();
@@ -269,16 +299,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
depthStencil->Release();
}
- if (mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0))
- {
- mPsProfile = "ps_3_0";
- mVsProfile = "vs_3_0";
- }
- else // egl::Display guarantees support for at least 2.0
- {
- mPsProfile = "ps_2_0";
- mVsProfile = "vs_2_0";
- }
+ mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
markAllStateDirty();
}
@@ -300,6 +321,12 @@ void Context::markAllStateDirty()
mScissorStateDirty = true;
mSampleStateDirty = true;
mDitherStateDirty = true;
+ mFrontFaceDirty = true;
+
+ if (mBufferBackEnd != NULL)
+ {
+ mBufferBackEnd->invalidate();
+ }
}
void Context::setClearColor(float red, float green, float blue, float alpha)
@@ -671,19 +698,24 @@ void Context::setActiveSampler(int active)
mState.activeSampler = active;
}
-GLuint Context::getFramebufferHandle() const
+GLuint Context::getReadFramebufferHandle() const
{
- return mState.framebuffer;
+ return mState.readFramebuffer;
+}
+
+GLuint Context::getDrawFramebufferHandle() const
+{
+ return mState.drawFramebuffer;
}
GLuint Context::getRenderbufferHandle() const
{
- return mState.renderbuffer;
+ return mState.renderbuffer.id();
}
GLuint Context::getArrayBufferHandle() const
{
- return mState.arrayBuffer;
+ return mState.arrayBuffer.id();
}
void Context::setVertexAttribEnabled(unsigned int attribNum, bool enabled)
@@ -696,10 +728,10 @@ const AttributeState &Context::getVertexAttribState(unsigned int attribNum)
return mState.vertexAttribute[attribNum];
}
-void Context::setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type, bool normalized,
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
GLsizei stride, const void *pointer)
{
- mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
+ mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
mState.vertexAttribute[attribNum].mSize = size;
mState.vertexAttribute[attribNum].mType = type;
mState.vertexAttribute[attribNum].mNormalized = normalized;
@@ -738,72 +770,29 @@ GLint Context::getUnpackAlignment() const
return mState.unpackAlignment;
}
-// Returns an unused buffer name
GLuint Context::createBuffer()
{
- unsigned int handle = 1;
-
- while (mBufferMap.find(handle) != mBufferMap.end())
- {
- handle++;
- }
-
- mBufferMap[handle] = NULL;
-
- return handle;
+ return mResourceManager->createBuffer();
}
-// Returns an unused shader/program name
-GLuint Context::createShader(GLenum type)
+GLuint Context::createProgram()
{
- unsigned int handle = 1;
-
- while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space
- {
- handle++;
- }
-
- if (type == GL_VERTEX_SHADER)
- {
- mShaderMap[handle] = new VertexShader(this, handle);
- }
- else if (type == GL_FRAGMENT_SHADER)
- {
- mShaderMap[handle] = new FragmentShader(this, handle);
- }
- else UNREACHABLE();
-
- return handle;
+ return mResourceManager->createProgram();
}
-// Returns an unused program/shader name
-GLuint Context::createProgram()
+GLuint Context::createShader(GLenum type)
{
- unsigned int handle = 1;
-
- while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space
- {
- handle++;
- }
-
- mProgramMap[handle] = new Program();
-
- return handle;
+ return mResourceManager->createShader(type);
}
-// Returns an unused texture name
GLuint Context::createTexture()
{
- unsigned int handle = 1;
-
- while (mTextureMap.find(handle) != mTextureMap.end())
- {
- handle++;
- }
-
- mTextureMap[handle] = NULL;
+ return mResourceManager->createTexture();
+}
- return handle;
+GLuint Context::createRenderbuffer()
+{
+ return mResourceManager->createRenderbuffer();
}
// Returns an unused framebuffer name
@@ -821,85 +810,44 @@ GLuint Context::createFramebuffer()
return handle;
}
-// Returns an unused renderbuffer name
-GLuint Context::createRenderbuffer()
-{
- unsigned int handle = 1;
-
- while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
- {
- handle++;
- }
-
- mRenderbufferMap[handle] = NULL;
-
- return handle;
-}
-
void Context::deleteBuffer(GLuint buffer)
{
- BufferMap::iterator bufferObject = mBufferMap.find(buffer);
-
- if (bufferObject != mBufferMap.end())
+ if (mResourceManager->getBuffer(buffer))
{
detachBuffer(buffer);
-
- delete bufferObject->second;
- mBufferMap.erase(bufferObject);
}
+
+ mResourceManager->deleteBuffer(buffer);
}
void Context::deleteShader(GLuint shader)
{
- ShaderMap::iterator shaderObject = mShaderMap.find(shader);
-
- if (shaderObject != mShaderMap.end())
- {
- if (!shaderObject->second->isAttached())
- {
- delete shaderObject->second;
- mShaderMap.erase(shaderObject);
- }
- else
- {
- shaderObject->second->flagForDeletion();
- }
- }
+ mResourceManager->deleteShader(shader);
}
void Context::deleteProgram(GLuint program)
{
- ProgramMap::iterator programObject = mProgramMap.find(program);
-
- if (programObject != mProgramMap.end())
- {
- if (program != mState.currentProgram)
- {
- delete programObject->second;
- mProgramMap.erase(programObject);
- }
- else
- {
- programObject->second->flagForDeletion();
- }
- }
+ mResourceManager->deleteProgram(program);
}
void Context::deleteTexture(GLuint texture)
{
- TextureMap::iterator textureObject = mTextureMap.find(texture);
-
- if (textureObject != mTextureMap.end())
+ if (mResourceManager->getTexture(texture))
{
detachTexture(texture);
+ }
- if (texture != 0)
- {
- delete textureObject->second;
- }
+ mResourceManager->deleteTexture(texture);
+}
- mTextureMap.erase(textureObject);
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+ if (mResourceManager->getRenderbuffer(renderbuffer))
+ {
+ detachRenderbuffer(renderbuffer);
}
+
+ mResourceManager->deleteRenderbuffer(renderbuffer);
}
void Context::deleteFramebuffer(GLuint framebuffer)
@@ -915,307 +863,186 @@ void Context::deleteFramebuffer(GLuint framebuffer)
}
}
-void Context::deleteRenderbuffer(GLuint renderbuffer)
+Buffer *Context::getBuffer(GLuint handle)
{
- RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
-
- if (renderbufferObject != mRenderbufferMap.end())
- {
- detachRenderbuffer(renderbuffer);
-
- delete renderbufferObject->second;
- mRenderbufferMap.erase(renderbufferObject);
- }
+ return mResourceManager->getBuffer(handle);
}
-void Context::bindArrayBuffer(unsigned int buffer)
+Shader *Context::getShader(GLuint handle)
{
- if (buffer != 0 && !getBuffer(buffer))
- {
- mBufferMap[buffer] = new Buffer();
- }
-
- mState.arrayBuffer = buffer;
+ return mResourceManager->getShader(handle);
}
-void Context::bindElementArrayBuffer(unsigned int buffer)
+Program *Context::getProgram(GLuint handle)
{
- if (buffer != 0 && !getBuffer(buffer))
- {
- mBufferMap[buffer] = new Buffer();
- }
-
- mState.elementArrayBuffer = buffer;
+ return mResourceManager->getProgram(handle);
}
-void Context::bindTexture2D(GLuint texture)
+Texture *Context::getTexture(GLuint handle)
{
- if (!getTexture(texture) && texture != 0)
- {
- mTextureMap[texture] = new Texture2D(this);
- }
-
- mState.texture2D = texture;
-
- mState.samplerTexture[SAMPLER_2D][mState.activeSampler] = texture;
+ return mResourceManager->getTexture(handle);
}
-void Context::bindTextureCubeMap(GLuint texture)
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
{
- if (!getTexture(texture) && texture != 0)
- {
- mTextureMap[texture] = new TextureCubeMap(this);
- }
-
- mState.textureCubeMap = texture;
-
- mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler] = texture;
+ return mResourceManager->getRenderbuffer(handle);
}
-void Context::bindFramebuffer(GLuint framebuffer)
+Framebuffer *Context::getReadFramebuffer()
{
- if (!getFramebuffer(framebuffer))
- {
- mFramebufferMap[framebuffer] = new Framebuffer();
- }
-
- mState.framebuffer = framebuffer;
+ return getFramebuffer(mState.readFramebuffer);
}
-void Context::bindRenderbuffer(GLuint renderbuffer)
+Framebuffer *Context::getDrawFramebuffer()
{
- if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
- {
- mRenderbufferMap[renderbuffer] = new Renderbuffer();
- }
-
- mState.renderbuffer = renderbuffer;
+ return getFramebuffer(mState.drawFramebuffer);
}
-void Context::useProgram(GLuint program)
+void Context::bindArrayBuffer(unsigned int buffer)
{
- Program *programObject = getCurrentProgram();
-
- GLuint priorProgram = mState.currentProgram;
- mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
+ mResourceManager->checkBufferAllocation(buffer);
- if (programObject && programObject->isFlaggedForDeletion())
- {
- deleteProgram(priorProgram);
- }
+ mState.arrayBuffer.set(getBuffer(buffer));
}
-void Context::setFramebufferZero(Framebuffer *buffer)
+void Context::bindElementArrayBuffer(unsigned int buffer)
{
- delete mFramebufferMap[0];
- mFramebufferMap[0] = buffer;
-}
+ mResourceManager->checkBufferAllocation(buffer);
-void Context::setColorbufferZero(Colorbuffer *buffer)
-{
- delete mColorbufferZero;
- mColorbufferZero = buffer;
+ mState.elementArrayBuffer.set(getBuffer(buffer));
}
-void Context::setDepthbufferZero(Depthbuffer *buffer)
+void Context::bindTexture2D(GLuint texture)
{
- delete mDepthbufferZero;
- mDepthbufferZero = buffer;
-}
+ mResourceManager->checkTextureAllocation(texture, SAMPLER_2D);
-void Context::setStencilbufferZero(Stencilbuffer *buffer)
-{
- delete mStencilbufferZero;
- mStencilbufferZero = buffer;
-}
+ mState.texture2D.set(getTexture(texture));
-void Context::setRenderbuffer(Renderbuffer *buffer)
-{
- delete mRenderbufferMap[mState.renderbuffer];
- mRenderbufferMap[mState.renderbuffer] = buffer;
+ mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(mState.texture2D.get());
}
-Buffer *Context::getBuffer(unsigned int handle)
+void Context::bindTextureCubeMap(GLuint texture)
{
- BufferMap::iterator buffer = mBufferMap.find(handle);
+ mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE);
- if (buffer == mBufferMap.end())
- {
- return NULL;
- }
- else
- {
- return buffer->second;
- }
-}
+ mState.textureCubeMap.set(getTexture(texture));
-Shader *Context::getShader(unsigned int handle)
-{
- ShaderMap::iterator shader = mShaderMap.find(handle);
-
- if (shader == mShaderMap.end())
- {
- return NULL;
- }
- else
- {
- return shader->second;
- }
+ mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(mState.textureCubeMap.get());
}
-Program *Context::getProgram(unsigned int handle)
+void Context::bindReadFramebuffer(GLuint framebuffer)
{
- ProgramMap::iterator program = mProgramMap.find(handle);
-
- if (program == mProgramMap.end())
- {
- return NULL;
- }
- else
+ if (!getFramebuffer(framebuffer))
{
- return program->second;
+ mFramebufferMap[framebuffer] = new Framebuffer();
}
-}
-
-Texture *Context::getTexture(unsigned int handle)
-{
- if (handle == 0) return NULL;
-
- TextureMap::iterator texture = mTextureMap.find(handle);
- if (texture == mTextureMap.end())
- {
- return NULL;
- }
- else
- {
- return texture->second;
- }
+ mState.readFramebuffer = framebuffer;
}
-Framebuffer *Context::getFramebuffer(unsigned int handle)
+void Context::bindDrawFramebuffer(GLuint framebuffer)
{
- FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
-
- if (framebuffer == mFramebufferMap.end())
- {
- return NULL;
- }
- else
+ if (!getFramebuffer(framebuffer))
{
- return framebuffer->second;
+ mFramebufferMap[framebuffer] = new Framebuffer();
}
+
+ mState.drawFramebuffer = framebuffer;
}
-Renderbuffer *Context::getRenderbuffer(unsigned int handle)
+void Context::bindRenderbuffer(GLuint renderbuffer)
{
- RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
+ mResourceManager->checkRenderbufferAllocation(renderbuffer);
- if (renderbuffer == mRenderbufferMap.end())
- {
- return NULL;
- }
- else
- {
- return renderbuffer->second;
- }
+ mState.renderbuffer.set(getRenderbuffer(renderbuffer));
}
-Colorbuffer *Context::getColorbuffer(GLuint handle)
+void Context::useProgram(GLuint program)
{
- if (handle != 0)
+ GLuint priorProgram = mState.currentProgram;
+ mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
+
+ if (priorProgram != program)
{
- Renderbuffer *renderbuffer = getRenderbuffer(handle);
+ Program *newProgram = mResourceManager->getProgram(program);
+ Program *oldProgram = mResourceManager->getProgram(priorProgram);
- if (renderbuffer && renderbuffer->isColorbuffer())
+ if (newProgram)
{
- return static_cast<Colorbuffer*>(renderbuffer);
+ newProgram->addRef();
+ }
+
+ if (oldProgram)
+ {
+ oldProgram->release();
}
}
- else // Special case: 0 refers to different initial render targets based on the attachment type
- {
- return mColorbufferZero;
- }
-
- return NULL;
}
-Depthbuffer *Context::getDepthbuffer(GLuint handle)
+void Context::setFramebufferZero(Framebuffer *buffer)
{
- if (handle != 0)
- {
- Renderbuffer *renderbuffer = getRenderbuffer(handle);
-
- if (renderbuffer && renderbuffer->isDepthbuffer())
- {
- return static_cast<Depthbuffer*>(renderbuffer);
- }
- }
- else // Special case: 0 refers to different initial render targets based on the attachment type
- {
- return mDepthbufferZero;
- }
+ delete mFramebufferMap[0];
+ mFramebufferMap[0] = buffer;
+}
- return NULL;
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+{
+ Renderbuffer *renderbufferObject = mState.renderbuffer.get();
+ renderbufferObject->setStorage(renderbuffer);
}
-Stencilbuffer *Context::getStencilbuffer(GLuint handle)
+Framebuffer *Context::getFramebuffer(unsigned int handle)
{
- if (handle != 0)
- {
- Renderbuffer *renderbuffer = getRenderbuffer(handle);
+ FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
- if (renderbuffer && renderbuffer->isStencilbuffer())
- {
- return static_cast<Stencilbuffer*>(renderbuffer);
- }
+ if (framebuffer == mFramebufferMap.end())
+ {
+ return NULL;
}
else
{
- return mStencilbufferZero;
+ return framebuffer->second;
}
-
- return NULL;
}
Buffer *Context::getArrayBuffer()
{
- return getBuffer(mState.arrayBuffer);
+ return mState.arrayBuffer.get();
}
Buffer *Context::getElementArrayBuffer()
{
- return getBuffer(mState.elementArrayBuffer);
+ return mState.elementArrayBuffer.get();
}
Program *Context::getCurrentProgram()
{
- return getProgram(mState.currentProgram);
+ return mResourceManager->getProgram(mState.currentProgram);
}
Texture2D *Context::getTexture2D()
{
- if (mState.texture2D == 0) // Special case: 0 refers to different initial textures based on the target
+ if (mState.texture2D.id() == 0) // Special case: 0 refers to different initial textures based on the target
{
return mTexture2DZero;
}
- return (Texture2D*)getTexture(mState.texture2D);
+ return static_cast<Texture2D*>(mState.texture2D.get());
}
TextureCubeMap *Context::getTextureCubeMap()
{
- if (mState.textureCubeMap == 0) // Special case: 0 refers to different initial textures based on the target
+ if (mState.textureCubeMap.id() == 0) // Special case: 0 refers to different initial textures based on the target
{
return mTextureCubeMapZero;
}
- return (TextureCubeMap*)getTexture(mState.textureCubeMap);
+ return static_cast<TextureCubeMap*>(mState.textureCubeMap.get());
}
Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
{
- GLuint texid = mState.samplerTexture[type][sampler];
+ GLuint texid = mState.samplerTexture[type][sampler].id();
if (texid == 0)
{
@@ -1227,12 +1054,7 @@ Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
}
}
- return getTexture(texid);
-}
-
-Framebuffer *Context::getFramebuffer()
-{
- return getFramebuffer(mState.framebuffer);
+ return mState.samplerTexture[type][sampler].get();
}
bool Context::getBooleanv(GLenum pname, GLboolean *params)
@@ -1283,7 +1105,7 @@ bool Context::getFloatv(GLenum pname, GLfloat *params)
break;
case GL_ALIASED_POINT_SIZE_RANGE:
params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
- params[1] = gl::ALIASED_POINT_SIZE_RANGE_MAX;
+ params[1] = supportsShaderModel3() ? gl::ALIASED_POINT_SIZE_RANGE_MAX_SM3 : gl::ALIASED_POINT_SIZE_RANGE_MAX_SM2;
break;
case GL_DEPTH_RANGE:
params[0] = mState.zNear;
@@ -1326,13 +1148,13 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = gl::MAX_FRAGMENT_UNIFORM_VECTORS; break;
case GL_MAX_RENDERBUFFER_SIZE: *params = gl::MAX_RENDERBUFFER_SIZE; break;
case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = 0; break;
- case GL_COMPRESSED_TEXTURE_FORMATS: /* no compressed texture formats are supported */ break;
case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
- case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer; break;
- case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer; break;
- case GL_FRAMEBUFFER_BINDING: *params = mState.framebuffer; break;
- case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer; break;
+ case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.id(); break;
+ //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+ case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
+ case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
+ case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break;
case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
@@ -1363,8 +1185,63 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = gl::MAX_TEXTURE_SIZE; break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = gl::MAX_CUBE_MAP_TEXTURE_SIZE; break;
- case GL_SAMPLE_BUFFERS: *params = 0; break;
- case GL_SAMPLES: *params = 0; break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ {
+ if (supportsCompressedTextures())
+ {
+ // at current, only GL_COMPRESSED_RGB_S3TC_DXT1_EXT and
+ // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT are supported
+ *params = 2;
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
+ case GL_MAX_SAMPLES_ANGLE:
+ {
+ GLsizei maxSamples = getMaxSupportedSamples();
+ if (maxSamples != 0)
+ {
+ *params = maxSamples;
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ }
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ {
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ switch (pname)
+ {
+ case GL_SAMPLE_BUFFERS:
+ if (framebuffer->getSamples() != 0)
+ {
+ *params = 1;
+ }
+ else
+ {
+ *params = 0;
+ }
+ break;
+ case GL_SAMPLES:
+ *params = framebuffer->getSamples();
+ break;
+ }
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = gl::IMPLEMENTATION_COLOR_READ_TYPE; break;
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = gl::IMPLEMENTATION_COLOR_READ_FORMAT; break;
case GL_MAX_VIEWPORT_DIMS:
@@ -1374,6 +1251,15 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
params[1] = maxDimension;
}
break;
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ {
+ if (supportsCompressedTextures())
+ {
+ params[0] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ params[1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ }
+ }
+ break;
case GL_VIEWPORT:
params[0] = mState.viewportX;
params[1] = mState.viewportY;
@@ -1393,7 +1279,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
{
- gl::Framebuffer *framebuffer = getFramebuffer();
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
gl::Colorbuffer *colorbuffer = framebuffer->getColorbuffer();
if (colorbuffer)
@@ -1414,8 +1300,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_DEPTH_BITS:
{
- gl::Framebuffer *framebuffer = getFramebuffer();
- gl::Depthbuffer *depthbuffer = framebuffer->getDepthbuffer();
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ gl::DepthStencilbuffer *depthbuffer = framebuffer->getDepthbuffer();
if (depthbuffer)
{
@@ -1429,8 +1315,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_STENCIL_BITS:
{
- gl::Framebuffer *framebuffer = getFramebuffer();
- gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ gl::DepthStencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
if (stencilbuffer)
{
@@ -1450,7 +1336,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
return false;
}
- *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler];
+ *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler].id();
}
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
@@ -1461,7 +1347,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
return false;
}
- *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler];
+ *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].id();
}
break;
default:
@@ -1552,6 +1438,19 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*numParams = 1;
}
break;
+ case GL_MAX_SAMPLES_ANGLE:
+ {
+ if (getMaxSupportedSamples() != 0)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ break;
case GL_MAX_VIEWPORT_DIMS:
{
*type = GL_INT;
@@ -1626,7 +1525,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{
IDirect3DDevice9 *device = getDevice();
- Framebuffer *framebufferObject = getFramebuffer();
+ Framebuffer *framebufferObject = getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
@@ -1636,20 +1535,35 @@ bool Context::applyRenderTarget(bool ignoreViewport)
}
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
- IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();
+ IDirect3DSurface9 *depthStencil = NULL;
unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
device->SetRenderTarget(0, renderTarget);
mAppliedRenderTargetSerial = renderTargetSerial;
+ mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
}
- unsigned int depthbufferSerial = framebufferObject->getDepthbufferSerial();
- if (depthbufferSerial != mAppliedDepthbufferSerial)
+ unsigned int depthbufferSerial = 0;
+ unsigned int stencilbufferSerial = 0;
+ if (framebufferObject->getDepthbufferType() != GL_NONE)
+ {
+ depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
+ depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
+ }
+ else if (framebufferObject->getStencilbufferType() != GL_NONE)
+ {
+ depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
+ }
+
+ if (depthbufferSerial != mAppliedDepthbufferSerial ||
+ stencilbufferSerial != mAppliedStencilbufferSerial)
{
device->SetDepthStencilSurface(depthStencil);
mAppliedDepthbufferSerial = depthbufferSerial;
+ mAppliedStencilbufferSerial = stencilbufferSerial;
}
D3DVIEWPORT9 viewport;
@@ -1690,7 +1604,8 @@ bool Context::applyRenderTarget(bool ignoreViewport)
mState.scissorY,
mState.scissorX + mState.scissorWidth,
mState.scissorY + mState.scissorHeight};
-
+ rect.right = std::min(static_cast<UINT>(rect.right), desc.Width);
+ rect.bottom = std::min(static_cast<UINT>(rect.bottom), desc.Height);
device->SetScissorRect(&rect);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
}
@@ -1698,7 +1613,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
}
-
+
mScissorStateDirty = false;
}
@@ -1710,7 +1625,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height};
programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);
- GLint window = programObject->getDxWindowLocation();
+ GLint window = programObject->getDxViewportLocation();
GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f,
(float)mState.viewportX + mState.viewportWidth / 2.0f,
(float)mState.viewportY + mState.viewportHeight / 2.0f};
@@ -1748,6 +1663,8 @@ void Context::applyState(GLenum drawMode)
GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
+ Framebuffer *framebufferObject = getDrawFramebuffer();
+
if (mCullStateDirty || mFrontFaceDirty)
{
if (mState.cullFace)
@@ -1764,7 +1681,7 @@ void Context::applyState(GLenum drawMode)
if (mDepthStateDirty)
{
- if (mState.depthTest)
+ if (mState.depthTest && framebufferObject->getDepthbufferType() != GL_NONE)
{
device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
@@ -1826,7 +1743,7 @@ void Context::applyState(GLenum drawMode)
if (mStencilStateDirty || mFrontFaceDirty)
{
- if (mState.stencilTest && hasStencil())
+ if (mState.stencilTest && framebufferObject->hasStencil())
{
device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
@@ -1844,8 +1761,7 @@ void Context::applyState(GLenum drawMode)
}
// get the maximum size of the stencil ref
- gl::Framebuffer *framebuffer = getFramebuffer();
- gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+ gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
@@ -1897,7 +1813,7 @@ void Context::applyState(GLenum drawMode)
{
if (mState.polygonOffsetFill)
{
- gl::Depthbuffer *depthbuffer = getFramebuffer()->getDepthbuffer();
+ gl::DepthStencilbuffer *depthbuffer = framebufferObject->getDepthbuffer();
if (depthbuffer)
{
device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
@@ -1914,7 +1830,7 @@ void Context::applyState(GLenum drawMode)
mPolygonOffsetStateDirty = false;
}
- if (mConfig->mMultiSample != 0 && mSampleStateDirty)
+ if (framebufferObject->isMultisample() && mSampleStateDirty)
{
if (mState.sampleAlphaToCoverage)
{
@@ -1923,7 +1839,34 @@ void Context::applyState(GLenum drawMode)
if (mState.sampleCoverage)
{
- FIXME("Sample coverage is unimplemented.");
+ device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+ unsigned int mask = 0;
+ if (mState.sampleCoverageValue != 0)
+ {
+ float threshold = 0.5f;
+
+ for (int i = 0; i < framebufferObject->getSamples(); ++i)
+ {
+ mask <<= 1;
+
+ if ((i + 1) * mState.sampleCoverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
+ }
+ }
+
+ if (mState.sampleCoverageInvert)
+ {
+ mask = ~mask;
+ }
+
+ device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
+ }
+ else
+ {
+ device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
}
mSampleStateDirty = false;
@@ -2005,7 +1948,7 @@ GLenum Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
- GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(mState.elementArrayBuffer), indices, indexInfo);
+ GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
if (err == GL_NO_ERROR)
{
@@ -2092,7 +2035,18 @@ void Context::applyTextures()
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
{
- Framebuffer *framebuffer = getFramebuffer();
+ Framebuffer *framebuffer = getReadFramebuffer();
+
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
IDirect3DDevice9 *device = getDevice();
@@ -2155,6 +2109,19 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
for (int j = 0; j < rect.bottom - rect.top; j++)
{
+ if (desc.Format == D3DFMT_A8R8G8B8 &&
+ format == GL_BGRA_EXT &&
+ type == GL_UNSIGNED_BYTE)
+ {
+ // Fast path for EXT_read_format_bgra, given
+ // an RGBA source buffer. Note that buffers with no
+ // alpha go through the slow path below.
+ memcpy(dest + j * outputPitch,
+ source + j * lock.Pitch,
+ (rect.right - rect.left) * 4);
+ continue;
+ }
+
for (int i = 0; i < rect.right - rect.left; i++)
{
float r;
@@ -2243,6 +2210,46 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
default: UNREACHABLE();
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
+ dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+ dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
+ dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)(15 * a + 0.5f) << 12)|
+ ((unsigned short)(15 * r + 0.5f) << 8) |
+ ((unsigned short)(15 * g + 0.5f) << 4) |
+ ((unsigned short)(15 * b + 0.5f) << 0);
+ break;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)( a + 0.5f) << 15) |
+ ((unsigned short)(31 * r + 0.5f) << 10) |
+ ((unsigned short)(31 * g + 0.5f) << 5) |
+ ((unsigned short)(31 * b + 0.5f) << 0);
+ break;
+ default: UNREACHABLE();
+ }
+ break;
case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT
switch (type)
{
@@ -2267,7 +2274,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
void Context::clear(GLbitfield mask)
{
- Framebuffer *framebufferObject = getFramebuffer();
+ Framebuffer *framebufferObject = getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
@@ -2299,22 +2306,24 @@ void Context::clear(GLbitfield mask)
}
}
- IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();
-
GLuint stencilUnmasked = 0x0;
- if ((mask & GL_STENCIL_BUFFER_BIT) && depthStencil)
+ if (mask & GL_STENCIL_BUFFER_BIT)
{
- D3DSURFACE_DESC desc;
- depthStencil->GetDesc(&desc);
-
mask &= ~GL_STENCIL_BUFFER_BIT;
- unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
- stencilUnmasked = (0x1 << stencilSize) - 1;
-
- if (stencilUnmasked != 0x0)
+ if (framebufferObject->getStencilbufferType() != GL_NONE)
{
- flags |= D3DCLEAR_STENCIL;
+ IDirect3DSurface9 *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ D3DSURFACE_DESC desc;
+ depthStencil->GetDesc(&desc);
+
+ unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
+ stencilUnmasked = (0x1 << stencilSize) - 1;
+
+ if (stencilUnmasked != 0x0)
+ {
+ flags |= D3DCLEAR_STENCIL;
+ }
}
}
@@ -2618,7 +2627,8 @@ void Context::finish()
IDirect3DStateBlock9 *savedState = NULL;
device->CreateStateBlock(D3DSBT_ALL, &savedState);
- occlusionQuery->Issue(D3DISSUE_BEGIN);
+ HRESULT result = occlusionQuery->Issue(D3DISSUE_BEGIN);
+ ASSERT(SUCCEEDED(result));
// Render something outside the render target
device->SetStreamSourceFreq(0, 1);
@@ -2629,7 +2639,8 @@ void Context::finish()
display->startScene();
device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, data, sizeof(data));
- occlusionQuery->Issue(D3DISSUE_END);
+ result = occlusionQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
while (occlusionQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE)
{
@@ -2663,15 +2674,16 @@ void Context::flush()
if (eventQuery)
{
- eventQuery->Issue(D3DISSUE_END);
+ HRESULT result = eventQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
- while (eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE)
+ result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+ eventQuery->Release();
+
+ if (result == D3DERR_DEVICELOST)
{
- // Keep polling, but allow other threads to do something useful first
- Sleep(0);
+ error(GL_OUT_OF_MEMORY);
}
-
- eventQuery->Release();
}
}
@@ -2742,14 +2754,43 @@ GLenum Context::getError()
return GL_NO_ERROR;
}
-const char *Context::getPixelShaderProfile()
+bool Context::supportsShaderModel3() const
{
- return mPsProfile;
+ return mSupportsShaderModel3;
}
-const char *Context::getVertexShaderProfile()
+int Context::getMaxSupportedSamples() const
{
- return mVsProfile;
+ return mMaxSupportedSamples;
+}
+
+int Context::getNearestSupportedSamples(D3DFORMAT format, int requested) const
+{
+ if (requested == 0)
+ {
+ return requested;
+ }
+
+ std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
+ if (itr == mMultiSampleSupport.end())
+ {
+ return -1;
+ }
+
+ for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
+ {
+ if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+bool Context::supportsCompressedTextures() const
+{
+ return mSupportsCompressedTextures;
}
void Context::detachBuffer(GLuint buffer)
@@ -2758,21 +2799,21 @@ void Context::detachBuffer(GLuint buffer)
// If a buffer object is deleted while it is bound, all bindings to that object in the current context
// (i.e. in the thread that called Delete-Buffers) are reset to zero.
- if (mState.arrayBuffer == buffer)
+ if (mState.arrayBuffer.id() == buffer)
{
- mState.arrayBuffer = 0;
+ mState.arrayBuffer.set(NULL);
}
- if (mState.elementArrayBuffer == buffer)
+ if (mState.elementArrayBuffer.id() == buffer)
{
- mState.elementArrayBuffer = 0;
+ mState.elementArrayBuffer.set(NULL);
}
for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
{
- if (mState.vertexAttribute[attribute].mBoundBuffer == buffer)
+ if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
{
- mState.vertexAttribute[attribute].mBoundBuffer = 0;
+ mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
}
}
}
@@ -2787,9 +2828,9 @@ void Context::detachTexture(GLuint texture)
{
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
{
- if (mState.samplerTexture[type][sampler] == texture)
+ if (mState.samplerTexture[type][sampler].id() == texture)
{
- mState.samplerTexture[type][sampler] = 0;
+ mState.samplerTexture[type][sampler].set(NULL);
}
}
}
@@ -2799,11 +2840,17 @@ void Context::detachTexture(GLuint texture)
// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
// image was attached in the currently bound framebuffer.
- Framebuffer *framebuffer = getFramebuffer();
+ Framebuffer *readFramebuffer = getReadFramebuffer();
+ Framebuffer *drawFramebuffer = getDrawFramebuffer();
- if (framebuffer)
+ if (readFramebuffer)
{
- framebuffer->detachTexture(texture);
+ readFramebuffer->detachTexture(texture);
+ }
+
+ if (drawFramebuffer && drawFramebuffer != readFramebuffer)
+ {
+ drawFramebuffer->detachTexture(texture);
}
}
@@ -2813,9 +2860,14 @@ void Context::detachFramebuffer(GLuint framebuffer)
// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
- if (mState.framebuffer == framebuffer)
+ if (mState.readFramebuffer == framebuffer)
+ {
+ bindReadFramebuffer(0);
+ }
+
+ if (mState.drawFramebuffer == framebuffer)
{
- bindFramebuffer(0);
+ bindDrawFramebuffer(0);
}
}
@@ -2825,7 +2877,7 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
// had been executed with the target RENDERBUFFER and name of zero.
- if (mState.renderbuffer == renderbuffer)
+ if (mState.renderbuffer.id() == renderbuffer)
{
bindRenderbuffer(0);
}
@@ -2835,11 +2887,17 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
// point to which this image was attached in the currently bound framebuffer.
- Framebuffer *framebuffer = getFramebuffer();
+ Framebuffer *readFramebuffer = getReadFramebuffer();
+ Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+ if (readFramebuffer)
+ {
+ readFramebuffer->detachRenderbuffer(renderbuffer);
+ }
- if (framebuffer)
+ if (drawFramebuffer && drawFramebuffer != readFramebuffer)
{
- framebuffer->detachRenderbuffer(renderbuffer);
+ drawFramebuffer->detachRenderbuffer(renderbuffer);
}
}
@@ -2859,7 +2917,7 @@ Texture *Context::getIncompleteTexture(SamplerType type)
case SAMPLER_2D:
{
- Texture2D *incomplete2d = new Texture2D(this);
+ Texture2D *incomplete2d = new Texture2D(Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
t = incomplete2d;
}
@@ -2867,7 +2925,7 @@ Texture *Context::getIncompleteTexture(SamplerType type)
case SAMPLER_CUBE:
{
- TextureCubeMap *incompleteCube = new TextureCubeMap(this);
+ TextureCubeMap *incompleteCube = new TextureCubeMap(Texture::INCOMPLETE_TEXTURE_ID);
incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
@@ -2911,23 +2969,6 @@ bool Context::isTriangleMode(GLenum drawMode)
return false;
}
-bool Context::hasStencil()
-{
- Framebuffer *framebufferObject = getFramebuffer();
-
- if (framebufferObject)
- {
- Stencilbuffer *stencilbufferObject = framebufferObject->getStencilbuffer();
-
- if (stencilbufferObject)
- {
- return stencilbufferObject->getStencilSize() > 0;
- }
- }
-
- return false;
-}
-
void Context::setVertexAttrib(GLuint index, const GLfloat *values)
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
@@ -2942,6 +2983,22 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
void Context::initExtensionString()
{
+ mExtensionString += "GL_OES_packed_depth_stencil ";
+ mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
+ mExtensionString += "GL_EXT_read_format_bgra ";
+ mExtensionString += "GL_ANGLE_framebuffer_blit ";
+ mExtensionString += "GL_OES_rgb8_rgba8 ";
+
+ if (supportsCompressedTextures())
+ {
+ mExtensionString += "GL_EXT_texture_compression_dxt1 ";
+ }
+
+ if (getMaxSupportedSamples() != 0)
+ {
+ mExtensionString += "GL_ANGLE_framebuffer_multisample ";
+ }
+
if (mBufferBackEnd->supportIntIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
@@ -2959,13 +3016,285 @@ const char *Context::getExtensionString() const
return mExtensionString.c_str();
}
+void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask)
+{
+ IDirect3DDevice9 *device = getDevice();
+
+ Framebuffer *readFramebuffer = getReadFramebuffer();
+ Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+ if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
+ !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (drawFramebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ RECT sourceRect;
+ RECT destRect;
+
+ if (srcX0 < srcX1)
+ {
+ sourceRect.left = srcX0;
+ sourceRect.right = srcX1;
+ destRect.left = dstX0;
+ destRect.right = dstX1;
+ }
+ else
+ {
+ sourceRect.left = srcX1;
+ destRect.left = dstX1;
+ sourceRect.right = srcX0;
+ destRect.right = dstX0;
+ }
+
+ // Arguments to StretchRect must be in D3D-style (0-top) coordinates, so we must
+ // flip our Y-values here
+ if (srcY0 < srcY1)
+ {
+ sourceRect.bottom = srcY1;
+ destRect.bottom = dstY1;
+ sourceRect.top = srcY0;
+ destRect.top = dstY0;
+ }
+ else
+ {
+ sourceRect.bottom = srcY0;
+ destRect.bottom = dstY0;
+ sourceRect.top = srcY1;
+ destRect.top = dstY1;
+ }
+
+ RECT sourceScissoredRect = sourceRect;
+ RECT destScissoredRect = destRect;
+
+ if (mState.scissorTest)
+ {
+ // Only write to parts of the destination framebuffer which pass the scissor test
+ // Please note: the destRect is now in D3D-style coordinates, so the *top* of the
+ // rect will be checked against scissorY, rather than the bottom.
+ if (destRect.left < mState.scissorX)
+ {
+ int xDiff = mState.scissorX - destRect.left;
+ destScissoredRect.left = mState.scissorX;
+ sourceScissoredRect.left += xDiff;
+ }
+
+ if (destRect.right > mState.scissorX + mState.scissorWidth)
+ {
+ int xDiff = destRect.right - (mState.scissorX + mState.scissorWidth);
+ destScissoredRect.right = mState.scissorX + mState.scissorWidth;
+ sourceScissoredRect.right -= xDiff;
+ }
+
+ if (destRect.top < mState.scissorY)
+ {
+ int yDiff = mState.scissorY - destRect.top;
+ destScissoredRect.top = mState.scissorY;
+ sourceScissoredRect.top += yDiff;
+ }
+
+ if (destRect.bottom > mState.scissorY + mState.scissorHeight)
+ {
+ int yDiff = destRect.bottom - (mState.scissorY + mState.scissorHeight);
+ destScissoredRect.bottom = mState.scissorY + mState.scissorHeight;
+ sourceScissoredRect.bottom -= yDiff;
+ }
+ }
+
+ bool blitRenderTarget = false;
+ bool blitDepthStencil = false;
+
+ RECT sourceTrimmedRect = sourceScissoredRect;
+ RECT destTrimmedRect = destScissoredRect;
+
+ // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
+ // the actual draw and read surfaces.
+ if (sourceTrimmedRect.left < 0)
+ {
+ int xDiff = 0 - sourceTrimmedRect.left;
+ sourceTrimmedRect.left = 0;
+ destTrimmedRect.left += xDiff;
+ }
+
+ int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth();
+ int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight();
+ int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth();
+ int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight();
+
+ if (sourceTrimmedRect.right > readBufferWidth)
+ {
+ int xDiff = sourceTrimmedRect.right - readBufferWidth;
+ sourceTrimmedRect.right = readBufferWidth;
+ destTrimmedRect.right -= xDiff;
+ }
+
+ if (sourceTrimmedRect.top < 0)
+ {
+ int yDiff = 0 - sourceTrimmedRect.top;
+ sourceTrimmedRect.top = 0;
+ destTrimmedRect.top += yDiff;
+ }
+
+ if (sourceTrimmedRect.bottom > readBufferHeight)
+ {
+ int yDiff = sourceTrimmedRect.bottom - readBufferHeight;
+ sourceTrimmedRect.bottom = readBufferHeight;
+ destTrimmedRect.bottom -= yDiff;
+ }
+
+ if (destTrimmedRect.left < 0)
+ {
+ int xDiff = 0 - destTrimmedRect.left;
+ destTrimmedRect.left = 0;
+ sourceTrimmedRect.left += xDiff;
+ }
+
+ if (destTrimmedRect.right > drawBufferWidth)
+ {
+ int xDiff = destTrimmedRect.right - drawBufferWidth;
+ destTrimmedRect.right = drawBufferWidth;
+ sourceTrimmedRect.right -= xDiff;
+ }
+
+ if (destTrimmedRect.top < 0)
+ {
+ int yDiff = 0 - destTrimmedRect.top;
+ destTrimmedRect.top = 0;
+ sourceTrimmedRect.top += yDiff;
+ }
+
+ if (destTrimmedRect.bottom > drawBufferHeight)
+ {
+ int yDiff = destTrimmedRect.bottom - drawBufferHeight;
+ destTrimmedRect.bottom = drawBufferHeight;
+ sourceTrimmedRect.bottom -= yDiff;
+ }
+
+ bool partialBufferCopy = false;
+ if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readFramebuffer->getColorbuffer()->getHeight() ||
+ sourceTrimmedRect.right - sourceTrimmedRect.left < readFramebuffer->getColorbuffer()->getWidth() ||
+ destTrimmedRect.bottom - destTrimmedRect.top < drawFramebuffer->getColorbuffer()->getHeight() ||
+ destTrimmedRect.right - destTrimmedRect.left < drawFramebuffer->getColorbuffer()->getWidth() ||
+ sourceTrimmedRect.top != 0 || destTrimmedRect.top != 0 || sourceTrimmedRect.left != 0 || destTrimmedRect.left != 0)
+ {
+ partialBufferCopy = true;
+ }
+
+ if (mask & GL_COLOR_BUFFER_BIT)
+ {
+ if (readFramebuffer->getColorbufferType() != drawFramebuffer->getColorbufferType() ||
+ readFramebuffer->getColorbuffer()->getD3DFormat() != drawFramebuffer->getColorbuffer()->getD3DFormat())
+ {
+ ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (partialBufferCopy && readFramebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ blitRenderTarget = true;
+
+ }
+
+ if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+ {
+ DepthStencilbuffer *readDSBuffer = NULL;
+ DepthStencilbuffer *drawDSBuffer = NULL;
+
+ // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
+ // both a depth and stencil buffer, it will be the same buffer.
+
+ if (mask & GL_DEPTH_BUFFER_BIT)
+ {
+ if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
+ {
+ if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
+ readFramebuffer->getDepthbuffer()->getD3DFormat() != drawFramebuffer->getDepthbuffer()->getD3DFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ blitDepthStencil = true;
+ readDSBuffer = readFramebuffer->getDepthbuffer();
+ drawDSBuffer = drawFramebuffer->getDepthbuffer();
+ }
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT)
+ {
+ if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
+ {
+ if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
+ readFramebuffer->getStencilbuffer()->getD3DFormat() != drawFramebuffer->getStencilbuffer()->getD3DFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ blitDepthStencil = true;
+ readDSBuffer = readFramebuffer->getStencilbuffer();
+ drawDSBuffer = drawFramebuffer->getStencilbuffer();
+ }
+ }
+
+ if (partialBufferCopy)
+ {
+ ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
+ return error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
+ }
+
+ if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
+ (readDSBuffer && readDSBuffer->getSamples() != 0))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
+ if (blitRenderTarget || blitDepthStencil)
+ {
+ egl::Display *display = getDisplay();
+ display->endScene();
+
+ if (blitRenderTarget)
+ {
+ HRESULT result = device->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect,
+ drawFramebuffer->getRenderTarget(), &destTrimmedRect, D3DTEXF_NONE);
+
+ if (FAILED(result))
+ {
+ ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
+ return;
+ }
+ }
+
+ if (blitDepthStencil)
+ {
+ HRESULT result = device->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
+
+ if (FAILED(result))
+ {
+ ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
+ return;
+ }
+ }
+ }
+}
+
}
extern "C"
{
-gl::Context *glCreateContext(const egl::Config *config)
+gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext)
{
- return new gl::Context(config);
+ return new gl::Context(config, shareContext);
}
void glDestroyContext(gl::Context *context)
diff --git a/ANGLE/src/libGLESv2/Context.h b/ANGLE/src/libGLESv2/Context.h
index 913fae2..6bca756 100644
--- a/ANGLE/src/libGLESv2/Context.h
+++ b/ANGLE/src/libGLESv2/Context.h
@@ -7,8 +7,8 @@
// Context.h: Defines the gl::Context class, managing all GL state and performing
// rendering operations. It is the GLES2 specific implementation of EGLContext.
-#ifndef INCLUDE_CONTEXT_H_
-#define INCLUDE_CONTEXT_H_
+#ifndef LIBGLESV2_CONTEXT_H_
+#define LIBGLESV2_CONTEXT_H_
#define GL_APICALL
#include <GLES2/gl2.h>
@@ -19,6 +19,8 @@
#include <map>
#include "common/angleutils.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/RefCountObject.h"
namespace egl
{
@@ -40,9 +42,11 @@ class Texture2D;
class TextureCubeMap;
class Framebuffer;
class Renderbuffer;
+class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
+class DepthStencilbuffer;
class VertexDataManager;
class IndexDataManager;
class BufferBackEnd;
@@ -67,15 +71,8 @@ enum
const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
-const float ALIASED_POINT_SIZE_RANGE_MAX = 1.0f;
-
-enum SamplerType
-{
- SAMPLER_2D,
- SAMPLER_CUBE,
-
- SAMPLER_TYPE_COUNT
-};
+const float ALIASED_POINT_SIZE_RANGE_MAX_SM2 = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MAX_SM3 = 64.0f;
struct Color
{
@@ -90,7 +87,7 @@ class AttributeState
{
public:
AttributeState()
- : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mBoundBuffer(0), mEnabled(false)
+ : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
{
mCurrentValue[0] = 0;
mCurrentValue[1] = 0;
@@ -105,7 +102,7 @@ class AttributeState
GLsizei mStride; // 0 means natural stride
const void *mPointer;
- GLuint mBoundBuffer; // Captured when VertexArrayPointer is called.
+ BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
bool mEnabled; // From Enable/DisableVertexAttribArray
@@ -180,16 +177,17 @@ struct State
bool depthMask;
int activeSampler; // Active texture unit selector - GL_TEXTURE0
- GLuint arrayBuffer;
- GLuint elementArrayBuffer;
- GLuint texture2D;
- GLuint textureCubeMap;
- GLuint framebuffer;
- GLuint renderbuffer;
+ BindingPointer<Buffer> arrayBuffer;
+ BindingPointer<Buffer> elementArrayBuffer;
+ BindingPointer<Texture> texture2D;
+ BindingPointer<Texture> textureCubeMap;
+ GLuint readFramebuffer;
+ GLuint drawFramebuffer;
+ BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
- GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
+ BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
GLint unpackAlignment;
GLint packAlignment;
@@ -198,7 +196,7 @@ struct State
class Context
{
public:
- Context(const egl::Config *config);
+ Context(const egl::Config *config, const gl::Context *shareContext);
~Context();
@@ -276,14 +274,15 @@ class Context
void setActiveSampler(int active);
- GLuint getFramebufferHandle() const;
+ GLuint getReadFramebufferHandle() const;
+ GLuint getDrawFramebufferHandle() const;
GLuint getRenderbufferHandle() const;
GLuint getArrayBufferHandle() const;
void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
const AttributeState &getVertexAttribState(unsigned int attribNum);
- void setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type,
+ void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
@@ -295,33 +294,36 @@ class Context
void setPackAlignment(GLint alignment);
GLint getPackAlignment() const;
+ // These create and destroy methods are merely pass-throughs to
+ // ResourceManager, which owns these object types
GLuint createBuffer();
GLuint createShader(GLenum type);
GLuint createProgram();
GLuint createTexture();
- GLuint createFramebuffer();
GLuint createRenderbuffer();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
- void deleteFramebuffer(GLuint framebuffer);
void deleteRenderbuffer(GLuint renderbuffer);
+ // Framebuffers are owned by the Context, so these methods do not pass through
+ GLuint createFramebuffer();
+ void deleteFramebuffer(GLuint framebuffer);
+
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
- void bindFramebuffer(GLuint framebuffer);
+ void bindReadFramebuffer(GLuint framebuffer);
+ void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
void useProgram(GLuint program);
void setFramebufferZero(Framebuffer *framebuffer);
- void setColorbufferZero(Colorbuffer *renderbuffer);
- void setDepthbufferZero(Depthbuffer *depthBuffer);
- void setStencilbufferZero(Stencilbuffer *stencilBuffer);
- void setRenderbuffer(Renderbuffer *renderbuffer);
+
+ void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, const GLfloat *values);
@@ -331,9 +333,6 @@ class Context
Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
- Colorbuffer *getColorbuffer(GLuint handle);
- Depthbuffer *getDepthbuffer(GLuint handle);
- Stencilbuffer *getStencilbuffer(GLuint handle);
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
@@ -341,7 +340,8 @@ class Context
Texture2D *getTexture2D();
TextureCubeMap *getTextureCubeMap();
Texture *getSamplerTexture(unsigned int sampler, SamplerType type);
- Framebuffer *getFramebuffer();
+ Framebuffer *getReadFramebuffer();
+ Framebuffer *getDrawFramebuffer();
bool getFloatv(GLenum pname, GLfloat *params);
bool getIntegerv(GLenum pname, GLint *params);
@@ -373,10 +373,15 @@ class Context
GLenum getError();
- const char *getPixelShaderProfile();
- const char *getVertexShaderProfile();
-
+ bool supportsShaderModel3() const;
+ GLsizei getMaxSupportedSamples() const;
+ int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const;
+ bool supportsCompressedTextures() const;
+
+ void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask);
Blit *getBlitter() { return mBlit; }
@@ -396,7 +401,6 @@ class Context
bool cullSkipsDraw(GLenum drawMode);
bool isTriangleMode(GLenum drawMode);
- bool hasStencil();
const egl::Config *const mConfig;
@@ -406,27 +410,11 @@ class Context
TextureCubeMap *mTextureCubeMapZero;
Colorbuffer *mColorbufferZero;
- Depthbuffer *mDepthbufferZero;
- Stencilbuffer *mStencilbufferZero;
-
- typedef std::map<GLuint, Buffer*> BufferMap;
- BufferMap mBufferMap;
-
- typedef std::map<GLuint, Shader*> ShaderMap;
- ShaderMap mShaderMap;
-
- typedef std::map<GLuint, Program*> ProgramMap;
- ProgramMap mProgramMap;
-
- typedef std::map<GLuint, Texture*> TextureMap;
- TextureMap mTextureMap;
+ DepthStencilbuffer *mDepthStencilbufferZero;
typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
- typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
- RenderbufferMap mRenderbufferMap;
-
void initExtensionString();
std::string mExtensionString;
@@ -435,7 +423,7 @@ class Context
IndexDataManager *mIndexDataManager;
Blit *mBlit;
-
+
Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
// Recorded errors
@@ -450,9 +438,12 @@ class Context
unsigned int mAppliedProgram;
unsigned int mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial;
+ unsigned int mAppliedStencilbufferSerial;
- const char *mPsProfile;
- const char *mVsProfile;
+ bool mSupportsShaderModel3;
+ std::map<D3DFORMAT, bool *> mMultiSampleSupport;
+ GLsizei mMaxSupportedSamples;
+ bool mSupportsCompressedTextures;
// state caching flags
bool mClearStateDirty;
@@ -471,13 +462,15 @@ class Context
IDirect3DStateBlock9 *mMaskedClearSavedState;
D3DCAPS9 mDeviceCaps;
+
+ ResourceManager *mResourceManager;
};
}
extern "C"
{
// Exported functions for use by EGL
-gl::Context *glCreateContext(const egl::Config *config);
+gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext);
void glDestroyContext(gl::Context *context);
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
gl::Context *glGetCurrentContext();
diff --git a/ANGLE/src/libGLESv2/Framebuffer.cpp b/ANGLE/src/libGLESv2/Framebuffer.cpp
index 1a3b01e..5c4bc99 100644
--- a/ANGLE/src/libGLESv2/Framebuffer.cpp
+++ b/ANGLE/src/libGLESv2/Framebuffer.cpp
@@ -16,85 +16,109 @@
namespace gl
{
+
Framebuffer::Framebuffer()
{
mColorbufferType = GL_NONE;
- mColorbufferHandle = 0;
-
mDepthbufferType = GL_NONE;
- mDepthbufferHandle = 0;
-
mStencilbufferType = GL_NONE;
- mStencilbufferHandle = 0;
}
Framebuffer::~Framebuffer()
{
+ mColorbufferPointer.set(NULL);
+ mDepthbufferPointer.set(NULL);
+ mStencilbufferPointer.set(NULL);
+}
+
+Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
+{
+ gl::Context *context = gl::getContext();
+ Renderbuffer *buffer = NULL;
+
+ if (type == GL_NONE)
+ {
+ buffer = NULL;
+ }
+ else if (type == GL_RENDERBUFFER)
+ {
+ buffer = context->getRenderbuffer(handle);
+ }
+ else if (IsTextureTarget(type))
+ {
+ buffer = context->getTexture(handle)->getColorbuffer(type);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ return buffer;
}
void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
{
mColorbufferType = type;
- mColorbufferHandle = colorbuffer;
+ mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
{
mDepthbufferType = type;
- mDepthbufferHandle = depthbuffer;
+ mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
{
mStencilbufferType = type;
- mStencilbufferHandle = stencilbuffer;
+ mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
}
void Framebuffer::detachTexture(GLuint texture)
{
- if (mColorbufferHandle == texture && IsTextureTarget(mColorbufferType))
+ if (mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType))
{
mColorbufferType = GL_NONE;
- mColorbufferHandle = 0;
+ mColorbufferPointer.set(NULL);
}
- if (mDepthbufferHandle == texture && IsTextureTarget(mDepthbufferType))
+ if (mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType))
{
mDepthbufferType = GL_NONE;
- mDepthbufferHandle = 0;
+ mDepthbufferPointer.set(NULL);
}
- if (mStencilbufferHandle == texture && IsTextureTarget(mStencilbufferType))
+ if (mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType))
{
mStencilbufferType = GL_NONE;
- mStencilbufferHandle = 0;
+ mStencilbufferPointer.set(NULL);
}
}
void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
- if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
+ if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
{
mColorbufferType = GL_NONE;
- mColorbufferHandle = 0;
+ mColorbufferPointer.set(NULL);
}
- if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
+ if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
{
mDepthbufferType = GL_NONE;
- mDepthbufferHandle = 0;
+ mDepthbufferPointer.set(NULL);
}
- if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
+ if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
{
mStencilbufferType = GL_NONE;
- mStencilbufferHandle = 0;
+ mStencilbufferPointer.set(NULL);
}
}
unsigned int Framebuffer::getRenderTargetSerial()
{
- Renderbuffer *colorbuffer = getColorbuffer();
+ Renderbuffer *colorbuffer = mColorbufferPointer.get();
if (colorbuffer)
{
@@ -106,7 +130,7 @@ unsigned int Framebuffer::getRenderTargetSerial()
IDirect3DSurface9 *Framebuffer::getRenderTarget()
{
- Renderbuffer *colorbuffer = getColorbuffer();
+ Renderbuffer *colorbuffer = mColorbufferPointer.get();
if (colorbuffer)
{
@@ -116,10 +140,26 @@ IDirect3DSurface9 *Framebuffer::getRenderTarget()
return NULL;
}
+IDirect3DSurface9 *Framebuffer::getDepthStencil()
+{
+ Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
+
+ if (!depthstencilbuffer)
+ {
+ depthstencilbuffer = mStencilbufferPointer.get();
+ }
+
+ if (depthstencilbuffer)
+ {
+ return depthstencilbuffer->getDepthStencil();
+ }
+
+ return NULL;
+}
+
unsigned int Framebuffer::getDepthbufferSerial()
{
- gl::Context *context = gl::getContext();
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ Renderbuffer *depthbuffer = mDepthbufferPointer.get();
if (depthbuffer)
{
@@ -129,70 +169,58 @@ unsigned int Framebuffer::getDepthbufferSerial()
return 0;
}
-IDirect3DSurface9 *Framebuffer::getDepthStencil()
+unsigned int Framebuffer::getStencilbufferSerial()
{
- gl::Context *context = gl::getContext();
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
- if (depthbuffer)
+ if (stencilbuffer)
{
- return depthbuffer->getDepthStencil();
+ return stencilbuffer->getSerial();
}
- return NULL;
+ return 0;
}
Colorbuffer *Framebuffer::getColorbuffer()
{
- gl::Context *context = gl::getContext();
- Colorbuffer *colorbuffer = NULL;
+ Renderbuffer *rb = mColorbufferPointer.get();
- if (mColorbufferType == GL_NONE)
+ if (rb != NULL && rb->isColorbuffer())
{
- UNREACHABLE();
- colorbuffer = NULL;
- }
- else if (mColorbufferType == GL_RENDERBUFFER)
- {
- colorbuffer = context->getColorbuffer(mColorbufferHandle);
+ return static_cast<Colorbuffer*>(rb->getStorage());
}
else
{
- colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
- }
-
- if (colorbuffer && colorbuffer->isColorbuffer())
- {
- return colorbuffer;
+ return NULL;
}
-
- return NULL;
}
-Depthbuffer *Framebuffer::getDepthbuffer()
+DepthStencilbuffer *Framebuffer::getDepthbuffer()
{
- gl::Context *context = gl::getContext();
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ Renderbuffer *rb = mDepthbufferPointer.get();
- if (depthbuffer && depthbuffer->isDepthbuffer())
+ if (rb != NULL && rb->isDepthbuffer())
{
- return depthbuffer;
+ return static_cast<DepthStencilbuffer*>(rb->getStorage());
+ }
+ else
+ {
+ return NULL;
}
-
- return NULL;
}
-Stencilbuffer *Framebuffer::getStencilbuffer()
+DepthStencilbuffer *Framebuffer::getStencilbuffer()
{
- gl::Context *context = gl::getContext();
- Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
+ Renderbuffer *rb = mStencilbufferPointer.get();
- if (stencilbuffer && stencilbuffer->isStencilbuffer())
+ if (rb != NULL && rb->isStencilbuffer())
{
- return stencilbuffer;
+ return static_cast<DepthStencilbuffer*>(rb->getStorage());
+ }
+ else
+ {
+ return NULL;
}
-
- return NULL;
}
GLenum Framebuffer::getColorbufferType()
@@ -212,25 +240,56 @@ GLenum Framebuffer::getStencilbufferType()
GLuint Framebuffer::getColorbufferHandle()
{
- return mColorbufferHandle;
+ return mColorbufferPointer.id();
}
GLuint Framebuffer::getDepthbufferHandle()
{
- return mDepthbufferHandle;
+ return mDepthbufferPointer.id();
}
GLuint Framebuffer::getStencilbufferHandle()
{
- return mStencilbufferHandle;
+ return mStencilbufferPointer.id();
}
-GLenum Framebuffer::completeness()
+bool Framebuffer::hasStencil()
{
- gl::Context *context = gl::getContext();
+ if (mStencilbufferType != GL_NONE)
+ {
+ DepthStencilbuffer *stencilbufferObject = getStencilbuffer();
+ if (stencilbufferObject)
+ {
+ return stencilbufferObject->getStencilSize() > 0;
+ }
+ }
+
+ return false;
+}
+
+bool Framebuffer::isMultisample()
+{
+ // If the framebuffer is not complete, attachment samples may be mismatched, and it
+ // cannot be used as a multisample framebuffer. If it is complete, it is required to
+ // have a color attachment, and all its attachments must have the same number of samples,
+ // so the number of samples for the colorbuffer will indicate whether the framebuffer is
+ // multisampled.
+ if (completeness() == GL_FRAMEBUFFER_COMPLETE && getColorbuffer()->getSamples() > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+GLenum Framebuffer::completeness()
+{
int width = 0;
int height = 0;
+ int samples = -1;
if (mColorbufferType != GL_NONE)
{
@@ -246,13 +305,29 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
+ if (IsTextureTarget(mColorbufferType))
+ {
+ if (IsCompressed(colorbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
+ samples = colorbuffer->getSamples();
}
+ else
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ }
+
+ DepthStencilbuffer *depthbuffer = NULL;
+ DepthStencilbuffer *stencilbuffer = NULL;
if (mDepthbufferType != GL_NONE)
{
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ depthbuffer = getDepthbuffer();
if (!depthbuffer)
{
@@ -273,11 +348,28 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
+
+ if (samples == -1)
+ {
+ samples = depthbuffer->getSamples();
+ }
+ else if (samples != depthbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ }
+
+ if (IsTextureTarget(mDepthbufferType))
+ {
+ if (IsCompressed(depthbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
}
if (mStencilbufferType != GL_NONE)
{
- Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
+ stencilbuffer = getStencilbuffer();
if (!stencilbuffer)
{
@@ -298,8 +390,66 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
+
+ if (samples == -1)
+ {
+ samples = stencilbuffer->getSamples();
+ }
+ else if (samples != stencilbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ }
+
+ if (IsTextureTarget(mStencilbufferType))
+ {
+ if (IsCompressed(stencilbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+ }
+
+ if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
+ {
+ if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+ stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+ depthbuffer->getSerial() != stencilbuffer->getSerial())
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+
+ return GL_FRAMEBUFFER_COMPLETE;
+}
+
+DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
+{
+ mColorbufferType = GL_RENDERBUFFER;
+ mDepthbufferType = GL_RENDERBUFFER;
+ mStencilbufferType = GL_RENDERBUFFER;
+
+ mColorbufferPointer.set(new Renderbuffer(0, color));
+
+ Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
+ mDepthbufferPointer.set(depthStencilRenderbuffer);
+ mStencilbufferPointer.set(depthStencilRenderbuffer);
+}
+
+int Framebuffer::getSamples()
+{
+ if (completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ return getColorbuffer()->getSamples();
+ }
+ else
+ {
+ return 0;
}
+}
+GLenum DefaultFramebuffer::completeness()
+{
return GL_FRAMEBUFFER_COMPLETE;
}
+
}
diff --git a/ANGLE/src/libGLESv2/Framebuffer.h b/ANGLE/src/libGLESv2/Framebuffer.h
index c35f940..0995145 100644
--- a/ANGLE/src/libGLESv2/Framebuffer.h
+++ b/ANGLE/src/libGLESv2/Framebuffer.h
@@ -15,19 +15,22 @@
#include <d3d9.h>
#include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
namespace gl
{
+class Renderbuffer;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
+class DepthStencilbuffer;
class Framebuffer
{
public:
Framebuffer();
- ~Framebuffer();
+ virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer);
void setDepthbuffer(GLenum type, GLuint depthbuffer);
@@ -41,10 +44,11 @@ class Framebuffer
unsigned int getRenderTargetSerial();
unsigned int getDepthbufferSerial();
+ unsigned int getStencilbufferSerial();
Colorbuffer *getColorbuffer();
- Depthbuffer *getDepthbuffer();
- Stencilbuffer *getStencilbuffer();
+ DepthStencilbuffer *getDepthbuffer();
+ DepthStencilbuffer *getStencilbuffer();
GLenum getColorbufferType();
GLenum getDepthbufferType();
@@ -54,20 +58,39 @@ class Framebuffer
GLuint getDepthbufferHandle();
GLuint getStencilbufferHandle();
- GLenum completeness();
+ bool hasStencil();
+ bool isMultisample();
+ int getSamples();
- private:
- DISALLOW_COPY_AND_ASSIGN(Framebuffer);
+ virtual GLenum completeness();
- GLuint mColorbufferHandle;
+ protected:
GLenum mColorbufferType;
+ BindingPointer<Renderbuffer> mColorbufferPointer;
- GLuint mDepthbufferHandle;
GLenum mDepthbufferType;
+ BindingPointer<Renderbuffer> mDepthbufferPointer;
- GLuint mStencilbufferHandle;
GLenum mStencilbufferType;
+ BindingPointer<Renderbuffer> mStencilbufferPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Framebuffer);
+
+ Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+ public:
+ DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil);
+
+ virtual GLenum completeness();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
};
+
}
#endif // LIBGLESV2_FRAMEBUFFER_H_
diff --git a/ANGLE/src/libGLESv2/Program.cpp b/ANGLE/src/libGLESv2/Program.cpp
index 78253c7..a32bc9f 100644
--- a/ANGLE/src/libGLESv2/Program.cpp
+++ b/ANGLE/src/libGLESv2/Program.cpp
@@ -45,7 +45,7 @@ UniformLocation::UniformLocation(const std::string &name, unsigned int element,
{
}
-Program::Program()
+Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
{
mFragmentShader = NULL;
mVertexShader = NULL;
@@ -62,6 +62,8 @@ Program::Program()
mDeleteStatus = false;
+ mRefCount = 0;
+
mSerial = issueSerial();
}
@@ -71,12 +73,12 @@ Program::~Program()
if (mVertexShader != NULL)
{
- mVertexShader->detach();
+ mVertexShader->release();
}
if (mFragmentShader != NULL)
{
- mFragmentShader->detach();
+ mFragmentShader->release();
}
}
@@ -90,7 +92,7 @@ bool Program::attachShader(Shader *shader)
}
mVertexShader = (VertexShader*)shader;
- mVertexShader->attach();
+ mVertexShader->addRef();
}
else if (shader->getType() == GL_FRAGMENT_SHADER)
{
@@ -100,7 +102,7 @@ bool Program::attachShader(Shader *shader)
}
mFragmentShader = (FragmentShader*)shader;
- mFragmentShader->attach();
+ mFragmentShader->addRef();
}
else UNREACHABLE();
@@ -116,7 +118,7 @@ bool Program::detachShader(Shader *shader)
return false;
}
- mVertexShader->detach();
+ mVertexShader->release();
mVertexShader = NULL;
}
else if (shader->getType() == GL_FRAGMENT_SHADER)
@@ -126,7 +128,7 @@ bool Program::detachShader(Shader *shader)
return false;
}
- mFragmentShader->detach();
+ mFragmentShader->release();
mFragmentShader = NULL;
}
else UNREACHABLE();
@@ -1195,6 +1197,10 @@ bool Program::linkVaryings()
}
}
+ Context *context = getContext();
+ bool sm3 = context->supportsShaderModel3();
+ std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
+
mVertexHLSL += "struct VS_INPUT\n"
"{\n";
@@ -1228,12 +1234,17 @@ bool Program::linkVaryings()
{
int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
- mVertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : TEXCOORD" + str(r) + ";\n";
+ mVertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
}
if (mFragmentShader->mUsesFragCoord)
{
- mVertexHLSL += " float4 gl_FragCoord : TEXCOORD" + str(registers) + ";\n";
+ mVertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ }
+
+ if (mVertexShader->mUsesPointSize && sm3)
+ {
+ mVertexHLSL += " float gl_PointSize : PSIZE;\n";
}
mVertexHLSL += "};\n"
@@ -1262,6 +1273,11 @@ bool Program::linkVaryings()
" output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.gl_Position.w = gl_Position.w;\n";
+ if (mVertexShader->mUsesPointSize && sm3)
+ {
+ mVertexHLSL += " output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n";
+ }
+
if (mFragmentShader->mUsesFragCoord)
{
mVertexHLSL += " output.gl_FragCoord = gl_Position;\n";
@@ -1345,7 +1361,7 @@ bool Program::linkVaryings()
for (int j = 0; j < rows; j++)
{
std::string n = str(varying->reg + i * rows + j);
- mPixelHLSL += " float4 v" + n + " : TEXCOORD" + n + ";\n";
+ mPixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n";
}
}
}
@@ -1354,9 +1370,14 @@ bool Program::linkVaryings()
if (mFragmentShader->mUsesFragCoord)
{
- mPixelHLSL += " float4 gl_FragCoord : TEXCOORD" + str(registers) + ";\n";
+ mPixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ }
+
+ if (mFragmentShader->mUsesPointCoord && sm3)
+ {
+ mPixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n";
}
-
+
if (mFragmentShader->mUsesFrontFacing)
{
mPixelHLSL += " float vFace : VFACE;\n";
@@ -1375,12 +1396,17 @@ bool Program::linkVaryings()
if (mFragmentShader->mUsesFragCoord)
{
mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"
- " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Window.x + dx_Window.z;\n"
- " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Window.y + dx_Window.w;\n"
+ " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
+ " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n"
" gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
" gl_FragCoord.w = rhw;\n";
}
+ if (mFragmentShader->mUsesPointCoord && sm3)
+ {
+ mPixelHLSL += " gl_PointCoord = float2(input.gl_PointCoord.x, 1.0 - input.gl_PointCoord.y);\n";
+ }
+
if (mFragmentShader->mUsesFrontFacing)
{
mPixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
@@ -1447,10 +1473,6 @@ void Program::link()
return;
}
- Context *context = getContext();
- const char *vertexProfile = context->getVertexShaderProfile();
- const char *pixelProfile = context->getPixelShaderProfile();
-
mPixelHLSL = mFragmentShader->getHLSL();
mVertexHLSL = mVertexShader->getHLSL();
@@ -1459,6 +1481,10 @@ void Program::link()
return;
}
+ Context *context = getContext();
+ const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
+ const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
+
ID3DXBuffer *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
ID3DXBuffer *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
@@ -1503,7 +1529,7 @@ void Program::link()
mDepthRangeFarLocation = getUniformLocation("gl_DepthRange.far", true);
mDepthRangeDiffLocation = getUniformLocation("gl_DepthRange.diff", true);
mDxDepthLocation = getUniformLocation("dx_Depth", true);
- mDxWindowLocation = getUniformLocation("dx_Window", true);
+ mDxViewportLocation = getUniformLocation("dx_Viewport", true);
mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true);
mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW", true);
mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines", true);
@@ -2355,13 +2381,13 @@ void Program::unlink(bool destroy)
{
if (mFragmentShader)
{
- mFragmentShader->detach();
+ mFragmentShader->release();
mFragmentShader = NULL;
}
if (mVertexShader)
{
- mVertexShader->detach();
+ mVertexShader->release();
mVertexShader = NULL;
}
}
@@ -2412,7 +2438,7 @@ void Program::unlink(bool destroy)
mDepthRangeNearLocation = -1;
mDepthRangeFarLocation = -1;
mDxDepthLocation = -1;
- mDxWindowLocation = -1;
+ mDxViewportLocation = -1;
mDxHalfPixelSizeLocation = -1;
mDxFrontCCWLocation = -1;
mDxPointsOrLinesLocation = -1;
@@ -2438,6 +2464,26 @@ bool Program::isValidated() const
return mValidated;
}
+void Program::release()
+{
+ mRefCount--;
+
+ if (mRefCount == 0 && mDeleteStatus)
+ {
+ mResourceManager->deleteProgram(mHandle);
+ }
+}
+
+void Program::addRef()
+{
+ mRefCount++;
+}
+
+unsigned int Program::getRefCount() const
+{
+ return mRefCount;
+}
+
unsigned int Program::getSerial() const
{
return mSerial;
@@ -2737,9 +2783,9 @@ GLint Program::getDxDepthLocation() const
return mDxDepthLocation;
}
-GLint Program::getDxWindowLocation() const
+GLint Program::getDxViewportLocation() const
{
- return mDxWindowLocation;
+ return mDxViewportLocation;
}
GLint Program::getDxHalfPixelSizeLocation() const
diff --git a/ANGLE/src/libGLESv2/Program.h b/ANGLE/src/libGLESv2/Program.h
index e52f20e..3021b7a 100644
--- a/ANGLE/src/libGLESv2/Program.h
+++ b/ANGLE/src/libGLESv2/Program.h
@@ -20,6 +20,7 @@
namespace gl
{
+class ResourceManager;
class FragmentShader;
class VertexShader;
@@ -55,7 +56,7 @@ struct UniformLocation
class Program
{
public:
- Program();
+ Program(ResourceManager *manager, GLuint handle);
~Program();
@@ -97,7 +98,7 @@ class Program
GLint getDepthRangeNearLocation() const;
GLint getDepthRangeFarLocation() const;
GLint getDxDepthLocation() const;
- GLint getDxWindowLocation() const;
+ GLint getDxViewportLocation() const;
GLint getDxHalfPixelSizeLocation() const;
GLint getDxFrontCCWLocation() const;
GLint getDxPointsOrLinesLocation() const;
@@ -119,6 +120,9 @@ class Program
GLint getActiveUniformCount();
GLint getActiveUniformMaxLength();
+ void addRef();
+ void release();
+ unsigned int getRefCount() const;
void flagForDeletion();
bool isFlaggedForDeletion() const;
@@ -204,7 +208,7 @@ class Program
GLint mDepthRangeNearLocation;
GLint mDepthRangeFarLocation;
GLint mDxDepthLocation;
- GLint mDxWindowLocation;
+ GLint mDxViewportLocation;
GLint mDxHalfPixelSizeLocation;
GLint mDxFrontCCWLocation;
GLint mDxPointsOrLinesLocation;
@@ -214,9 +218,14 @@ class Program
char *mInfoLog;
bool mValidated;
+ unsigned int mRefCount;
+
unsigned int mSerial;
static unsigned int mCurrentSerial;
+
+ ResourceManager *mResourceManager;
+ const GLuint mHandle;
};
}
diff --git a/ANGLE/src/libGLESv2/RefCountObject.cpp b/ANGLE/src/libGLESv2/RefCountObject.cpp
new file mode 100644
index 0000000..e3fd36e
--- /dev/null
+++ b/ANGLE/src/libGLESv2/RefCountObject.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#include "RefCountObject.h"
+
+namespace gl
+{
+
+RefCountObject::RefCountObject(GLuint id)
+{
+ mId = id;
+ mRefCount = 0;
+}
+
+RefCountObject::~RefCountObject()
+{
+}
+
+void RefCountObject::addRef() const
+{
+ mRefCount++;
+}
+
+void RefCountObject::release() const
+{
+ ASSERT(mRefCount > 0);
+
+ if (--mRefCount == 0)
+ {
+ delete this;
+ }
+}
+
+void RefCountObjectBindingPointer::set(RefCountObject *newObject)
+{
+ // addRef first in case newObject == mObject and this is the last reference to it.
+ if (newObject != NULL) newObject->addRef();
+ if (mObject != NULL) mObject->release();
+
+ mObject = newObject;
+}
+
+}
diff --git a/ANGLE/src/libGLESv2/RefCountObject.h b/ANGLE/src/libGLESv2/RefCountObject.h
new file mode 100644
index 0000000..a149350
--- /dev/null
+++ b/ANGLE/src/libGLESv2/RefCountObject.h
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RefCountObject.h: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#ifndef LIBGLESV2_REFCOUNTOBJECT_H_
+#define LIBGLESV2_REFCOUNTOBJECT_H_
+
+#include <cstddef>
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+class RefCountObject
+{
+ public:
+ explicit RefCountObject(GLuint id);
+ virtual ~RefCountObject();
+
+ virtual void addRef() const;
+ virtual void release() const;
+
+ GLuint id() const { return mId; }
+
+ private:
+ GLuint mId;
+
+ mutable std::size_t mRefCount;
+};
+
+class RefCountObjectBindingPointer
+{
+ protected:
+ RefCountObjectBindingPointer() : mObject(NULL) { }
+ ~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
+
+ void set(RefCountObject *newObject);
+ RefCountObject *get() const { return mObject; }
+
+ public:
+ GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; }
+ bool operator ! () const { return (get() == NULL); }
+
+ private:
+ RefCountObject *mObject;
+};
+
+template <class ObjectType>
+class BindingPointer : public RefCountObjectBindingPointer
+{
+ public:
+ void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); }
+ ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
+ ObjectType *operator -> () const { return get(); }
+};
+
+}
+
+#endif // LIBGLESV2_REFCOUNTOBJECT_H_
diff --git a/ANGLE/src/libGLESv2/Renderbuffer.cpp b/ANGLE/src/libGLESv2/Renderbuffer.cpp
index edd38ec..0eb4637 100644
--- a/ANGLE/src/libGLESv2/Renderbuffer.cpp
+++ b/ANGLE/src/libGLESv2/Renderbuffer.cpp
@@ -15,73 +15,148 @@
namespace gl
{
-unsigned int Renderbuffer::mCurrentSerial = 1;
+unsigned int RenderbufferStorage::mCurrentSerial = 1;
-Renderbuffer::Renderbuffer()
+Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
{
- mWidth = 0;
- mHeight = 0;
- mFormat = GL_RGBA4; // default format, needs to be one of the expected renderbuffer formats
- mSerial = issueSerial();
+ ASSERT(storage != NULL);
+ mStorage = storage;
}
Renderbuffer::~Renderbuffer()
{
+ delete mStorage;
+}
+
+bool Renderbuffer::isColorbuffer() const
+{
+ return mStorage->isColorbuffer();
+}
+
+bool Renderbuffer::isDepthbuffer() const
+{
+ return mStorage->isDepthbuffer();
+}
+
+bool Renderbuffer::isStencilbuffer() const
+{
+ return mStorage->isStencilbuffer();
+}
+
+IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+{
+ return mStorage->getRenderTarget();
+}
+
+IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+{
+ return mStorage->getDepthStencil();
+}
+
+int Renderbuffer::getWidth() const
+{
+ return mStorage->getWidth();
+}
+
+int Renderbuffer::getHeight() const
+{
+ return mStorage->getHeight();
+}
+
+GLenum Renderbuffer::getFormat() const
+{
+ return mStorage->getFormat();
+}
+
+D3DFORMAT Renderbuffer::getD3DFormat() const
+{
+ return mStorage->getD3DFormat();
+}
+
+unsigned int Renderbuffer::getSerial() const
+{
+ return mStorage->getSerial();
+}
+
+void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+{
+ ASSERT(newStorage != NULL);
+
+ delete mStorage;
+ mStorage = newStorage;
+}
+
+RenderbufferStorage::RenderbufferStorage()
+{
+ mSerial = issueSerial();
+}
+
+RenderbufferStorage::~RenderbufferStorage()
+{
}
-bool Renderbuffer::isColorbuffer()
+bool RenderbufferStorage::isColorbuffer() const
{
return false;
}
-bool Renderbuffer::isDepthbuffer()
+bool RenderbufferStorage::isDepthbuffer() const
{
return false;
}
-bool Renderbuffer::isStencilbuffer()
+bool RenderbufferStorage::isStencilbuffer() const
{
return false;
}
-IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
{
return NULL;
}
-IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
{
return NULL;
}
-int Renderbuffer::getWidth()
+int RenderbufferStorage::getWidth() const
{
return mWidth;
}
-int Renderbuffer::getHeight()
+int RenderbufferStorage::getHeight() const
{
return mHeight;
}
-void Renderbuffer::setSize(int width, int height)
+void RenderbufferStorage::setSize(int width, int height)
{
mWidth = width;
mHeight = height;
}
-
-GLenum Renderbuffer::getFormat()
+GLenum RenderbufferStorage::getFormat() const
{
return mFormat;
}
-unsigned int Renderbuffer::getSerial() const
+D3DFORMAT RenderbufferStorage::getD3DFormat() const
+{
+ return mD3DFormat;
+}
+
+GLsizei RenderbufferStorage::getSamples() const
+{
+ return mSamples;
+}
+
+unsigned int RenderbufferStorage::getSerial() const
{
return mSerial;
}
-unsigned int Renderbuffer::issueSerial()
+unsigned int RenderbufferStorage::issueSerial()
{
return mCurrentSerial++;
}
@@ -96,36 +171,59 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render
renderTarget->GetDesc(&description);
setSize(description.Width, description.Height);
+ mD3DFormat = description.Format;
+ mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
+ }
+ else
+ {
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
-
}
-Colorbuffer::Colorbuffer(int width, int height, GLenum format)
+Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
{
IDirect3DDevice9 *device = getDevice();
mRenderTarget = NULL;
- HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format),
- D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
+ D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
+ int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ if (supportedSamples == -1)
{
error(GL_OUT_OF_MEMORY);
return;
}
- ASSERT(SUCCEEDED(result));
+ if (width > 0 && height > 0)
+ {
+ HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
+ es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ {
+ error(GL_OUT_OF_MEMORY);
+
+ return;
+ }
+
+ ASSERT(SUCCEEDED(result));
+ }
if (mRenderTarget)
{
setSize(width, height);
mFormat = format;
+ mD3DFormat = requestedFormat;
+ mSamples = supportedSamples;
}
else
{
setSize(0, 0);
mFormat = GL_RGBA4;
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
}
@@ -137,12 +235,12 @@ Colorbuffer::~Colorbuffer()
}
}
-bool Colorbuffer::isColorbuffer()
+bool Colorbuffer::isColorbuffer() const
{
return true;
}
-GLuint Colorbuffer::getRedSize()
+GLuint Colorbuffer::getRedSize() const
{
if (mRenderTarget)
{
@@ -155,7 +253,7 @@ GLuint Colorbuffer::getRedSize()
return 0;
}
-GLuint Colorbuffer::getGreenSize()
+GLuint Colorbuffer::getGreenSize() const
{
if (mRenderTarget)
{
@@ -168,7 +266,7 @@ GLuint Colorbuffer::getGreenSize()
return 0;
}
-GLuint Colorbuffer::getBlueSize()
+GLuint Colorbuffer::getBlueSize() const
{
if (mRenderTarget)
{
@@ -181,7 +279,7 @@ GLuint Colorbuffer::getBlueSize()
return 0;
}
-GLuint Colorbuffer::getAlphaSize()
+GLuint Colorbuffer::getAlphaSize() const
{
if (mRenderTarget)
{
@@ -199,7 +297,7 @@ IDirect3DSurface9 *Colorbuffer::getRenderTarget()
return mRenderTarget;
}
-Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
+DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
{
if (depthStencil)
{
@@ -209,18 +307,34 @@ Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthS
depthStencil->GetDesc(&description);
setSize(description.Width, description.Height);
- mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
+ mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
+ mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
+ mD3DFormat = description.Format;
+ }
+ else
+ {
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
}
-Depthbuffer::Depthbuffer(int width, int height)
+DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
{
IDirect3DDevice9 *device = getDevice();
mDepthStencil = NULL;
- HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
+
+ int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
+
+ if (supportedSamples == -1)
+ {
+ error(GL_OUT_OF_MEMORY);
+
+ return;
+ }
+
+ HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
+ 0, FALSE, &mDepthStencil, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
@@ -234,18 +348,20 @@ Depthbuffer::Depthbuffer(int width, int height)
if (mDepthStencil)
{
setSize(width, height);
- mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
+ mFormat = GL_DEPTH24_STENCIL8_OES;
+ mD3DFormat = D3DFMT_D24S8;
+ mSamples = supportedSamples;
}
else
{
setSize(0, 0);
mFormat = GL_RGBA4; //default format
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
}
-Depthbuffer::~Depthbuffer()
+DepthStencilbuffer::~DepthStencilbuffer()
{
if (mDepthStencil)
{
@@ -253,12 +369,17 @@ Depthbuffer::~Depthbuffer()
}
}
-bool Depthbuffer::isDepthbuffer()
+bool DepthStencilbuffer::isDepthbuffer() const
+{
+ return true;
+}
+
+bool DepthStencilbuffer::isStencilbuffer() const
{
return true;
}
-GLuint Depthbuffer::getDepthSize()
+GLuint DepthStencilbuffer::getDepthSize() const
{
if (mDepthStencil)
{
@@ -271,85 +392,93 @@ GLuint Depthbuffer::getDepthSize()
return 0;
}
-IDirect3DSurface9 *Depthbuffer::getDepthStencil()
+GLuint DepthStencilbuffer::getStencilSize() const
+{
+ if (mDepthStencil)
+ {
+ D3DSURFACE_DESC description;
+ mDepthStencil->GetDesc(&description);
+
+ return es2dx::GetStencilSize(description.Format);
+ }
+
+ return 0;
+}
+
+IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
{
return mDepthStencil;
}
-Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
+Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
{
if (depthStencil)
{
- depthStencil->AddRef();
-
- D3DSURFACE_DESC description;
- depthStencil->GetDesc(&description);
-
- setSize(description.Width, description.Height);
- mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
+ mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage
}
}
-Stencilbuffer::Stencilbuffer(int width, int height)
+Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
- IDirect3DDevice9 *device = getDevice();
-
- mDepthStencil = NULL;
- HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ if (getDepthStencil())
{
- error(GL_OUT_OF_MEMORY);
-
- return;
+ mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage
}
+}
- ASSERT(SUCCEEDED(result));
+Depthbuffer::~Depthbuffer()
+{
+}
- if (mDepthStencil)
+bool Depthbuffer::isDepthbuffer() const
+{
+ return true;
+}
+
+bool Depthbuffer::isStencilbuffer() const
+{
+ return false;
+}
+
+Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
+{
+ if (depthStencil)
{
- setSize(width, height);
mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
// glRenderbufferStorage
}
else
{
- setSize(0, 0);
mFormat = GL_RGBA4; //default format
}
}
-Stencilbuffer::~Stencilbuffer()
+Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
- if (mDepthStencil)
+ if (getDepthStencil())
{
- mDepthStencil->Release();
+ mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage
}
}
-GLuint Stencilbuffer::getStencilSize()
+Stencilbuffer::~Stencilbuffer()
{
- if (mDepthStencil)
- {
- D3DSURFACE_DESC description;
- mDepthStencil->GetDesc(&description);
-
- return es2dx::GetStencilSize(description.Format);
- }
-
- return 0;
}
-bool Stencilbuffer::isStencilbuffer()
+bool Stencilbuffer::isDepthbuffer() const
{
- return true;
+ return false;
}
-IDirect3DSurface9 *Stencilbuffer::getDepthStencil()
+bool Stencilbuffer::isStencilbuffer() const
{
- return mDepthStencil;
+ return true;
}
}
diff --git a/ANGLE/src/libGLESv2/Renderbuffer.h b/ANGLE/src/libGLESv2/Renderbuffer.h
index 2c70ce9..cb8c06a 100644
--- a/ANGLE/src/libGLESv2/Renderbuffer.h
+++ b/ANGLE/src/libGLESv2/Renderbuffer.h
@@ -4,8 +4,9 @@
// found in the LICENSE file.
//
-// Renderbuffer.h: Defines the virtual gl::Renderbuffer class and its derived
-// classes Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#ifndef LIBGLESV2_RENDERBUFFER_H_
@@ -16,26 +17,33 @@
#include <d3d9.h>
#include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
namespace gl
{
-class Renderbuffer
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage
{
public:
- Renderbuffer();
+ RenderbufferStorage();
- virtual ~Renderbuffer();
+ virtual ~RenderbufferStorage() = 0;
- virtual bool isColorbuffer();
- virtual bool isDepthbuffer();
- virtual bool isStencilbuffer();
+ virtual bool isColorbuffer() const;
+ virtual bool isDepthbuffer() const;
+ virtual bool isStencilbuffer() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
- virtual int getWidth();
- virtual int getHeight();
- GLenum getFormat();
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+ virtual GLenum getFormat() const;
+ D3DFORMAT getD3DFormat() const;
+ GLsizei getSamples() const;
unsigned int getSerial() const;
static unsigned int issueSerial();
@@ -43,10 +51,12 @@ class Renderbuffer
protected:
void setSize(int width, int height);
GLenum mFormat;
+ D3DFORMAT mD3DFormat;
+ GLsizei mSamples;
unsigned int mSerial;
private:
- DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
+ DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
static unsigned int mCurrentSerial;
@@ -54,20 +64,52 @@ class Renderbuffer
int mHeight;
};
-class Colorbuffer : public Renderbuffer
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a wrapper for a RenderbufferStorage, but the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public RefCountObject
+{
+ public:
+ Renderbuffer(GLuint id, RenderbufferStorage *storage);
+
+ ~Renderbuffer();
+
+ bool isColorbuffer() const;
+ bool isDepthbuffer() const;
+ bool isStencilbuffer() const;
+
+ IDirect3DSurface9 *getRenderTarget();
+ IDirect3DSurface9 *getDepthStencil();
+
+ int getWidth() const;
+ int getHeight() const;
+ GLenum getFormat() const;
+ D3DFORMAT getD3DFormat() const;
+ unsigned int getSerial() const;
+
+ void setStorage(RenderbufferStorage *newStorage);
+ RenderbufferStorage *getStorage() { return mStorage; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
+
+ RenderbufferStorage *mStorage;
+};
+
+class Colorbuffer : public RenderbufferStorage
{
public:
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
- Colorbuffer(int width, int height, GLenum format);
+ Colorbuffer(int width, int height, GLenum format, GLsizei samples);
~Colorbuffer();
- bool isColorbuffer();
+ bool isColorbuffer() const;
- GLuint getRedSize();
- GLuint getGreenSize();
- GLuint getBlueSize();
- GLuint getAlphaSize();
+ GLuint getRedSize() const;
+ GLuint getGreenSize() const;
+ GLuint getBlueSize() const;
+ GLuint getAlphaSize() const;
IDirect3DSurface9 *getRenderTarget();
@@ -78,42 +120,55 @@ class Colorbuffer : public Renderbuffer
DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
};
-class Depthbuffer : public Renderbuffer
+class DepthStencilbuffer : public RenderbufferStorage
{
public:
- explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
- Depthbuffer(int width, int height);
+ explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
+ DepthStencilbuffer(int width, int height, GLsizei samples);
- ~Depthbuffer();
+ ~DepthStencilbuffer();
- bool isDepthbuffer();
+ virtual bool isDepthbuffer() const;
+ virtual bool isStencilbuffer() const;
- GLuint getDepthSize();
+ GLuint getDepthSize() const;
+ GLuint getStencilSize() const;
IDirect3DSurface9 *getDepthStencil();
private:
- DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
+ DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
IDirect3DSurface9 *mDepthStencil;
};
-class Stencilbuffer : public Renderbuffer
+class Depthbuffer : public DepthStencilbuffer
{
public:
- explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
- Stencilbuffer(int width, int height);
+ explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
+ Depthbuffer(int width, int height, GLsizei samples);
- ~Stencilbuffer();
+ ~Depthbuffer();
+
+ bool isDepthbuffer() const;
+ bool isStencilbuffer() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
+};
- bool isStencilbuffer();
+class Stencilbuffer : public DepthStencilbuffer
+{
+ public:
+ explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
+ Stencilbuffer(int width, int height, GLsizei samples);
- GLuint getStencilSize();
+ ~Stencilbuffer();
- IDirect3DSurface9 *getDepthStencil();
+ bool isDepthbuffer() const;
+ bool isStencilbuffer() const;
private:
DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
- IDirect3DSurface9 *mDepthStencil;
};
}
diff --git a/ANGLE/src/libGLESv2/ResourceManager.cpp b/ANGLE/src/libGLESv2/ResourceManager.cpp
new file mode 100644
index 0000000..12a86c1
--- /dev/null
+++ b/ANGLE/src/libGLESv2/ResourceManager.cpp
@@ -0,0 +1,340 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and
+// retrieves objects which may be shared by multiple Contexts.
+
+#include "libGLESv2/ResourceManager.h"
+
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/Program.h"
+#include "libGLESv2/RenderBuffer.h"
+#include "libGLESv2/Shader.h"
+#include "libGLESv2/Texture.h"
+
+namespace gl
+{
+ResourceManager::ResourceManager()
+{
+ mRefCount = 1;
+}
+
+ResourceManager::~ResourceManager()
+{
+ while (!mBufferMap.empty())
+ {
+ deleteBuffer(mBufferMap.begin()->first);
+ }
+
+ while (!mProgramMap.empty())
+ {
+ deleteProgram(mProgramMap.begin()->first);
+ }
+
+ while (!mShaderMap.empty())
+ {
+ deleteShader(mShaderMap.begin()->first);
+ }
+
+ while (!mRenderbufferMap.empty())
+ {
+ deleteRenderbuffer(mRenderbufferMap.begin()->first);
+ }
+
+ while (!mTextureMap.empty())
+ {
+ deleteTexture(mTextureMap.begin()->first);
+ }
+}
+
+void ResourceManager::addRef()
+{
+ mRefCount++;
+}
+
+void ResourceManager::release()
+{
+ if (--mRefCount == 0)
+ {
+ delete this;
+ }
+}
+
+// Returns an unused buffer name
+GLuint ResourceManager::createBuffer()
+{
+ unsigned int handle = 1;
+
+ while (mBufferMap.find(handle) != mBufferMap.end())
+ {
+ handle++;
+ }
+
+ mBufferMap[handle] = NULL;
+
+ return handle;
+}
+
+// Returns an unused shader/program name
+GLuint ResourceManager::createShader(GLenum type)
+{
+ unsigned int handle = 1;
+
+ while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space
+ {
+ handle++;
+ }
+
+ if (type == GL_VERTEX_SHADER)
+ {
+ mShaderMap[handle] = new VertexShader(this, handle);
+ }
+ else if (type == GL_FRAGMENT_SHADER)
+ {
+ mShaderMap[handle] = new FragmentShader(this, handle);
+ }
+ else UNREACHABLE();
+
+ return handle;
+}
+
+// Returns an unused program/shader name
+GLuint ResourceManager::createProgram()
+{
+ unsigned int handle = 1;
+
+ while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space
+ {
+ handle++;
+ }
+
+ mProgramMap[handle] = new Program(this, handle);
+
+ return handle;
+}
+
+// Returns an unused texture name
+GLuint ResourceManager::createTexture()
+{
+ unsigned int handle = 1;
+
+ while (mTextureMap.find(handle) != mTextureMap.end())
+ {
+ handle++;
+ }
+
+ mTextureMap[handle] = NULL;
+
+ return handle;
+}
+
+// Returns an unused renderbuffer name
+GLuint ResourceManager::createRenderbuffer()
+{
+ unsigned int handle = 1;
+
+ while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
+ {
+ handle++;
+ }
+
+ mRenderbufferMap[handle] = NULL;
+
+ return handle;
+}
+
+void ResourceManager::deleteBuffer(GLuint buffer)
+{
+ BufferMap::iterator bufferObject = mBufferMap.find(buffer);
+
+ if (bufferObject != mBufferMap.end())
+ {
+ if (bufferObject->second) bufferObject->second->release();
+ mBufferMap.erase(bufferObject);
+ }
+}
+
+void ResourceManager::deleteShader(GLuint shader)
+{
+ ShaderMap::iterator shaderObject = mShaderMap.find(shader);
+
+ if (shaderObject != mShaderMap.end())
+ {
+ if (shaderObject->second->getRefCount() == 0)
+ {
+ delete shaderObject->second;
+ mShaderMap.erase(shaderObject);
+ }
+ else
+ {
+ shaderObject->second->flagForDeletion();
+ }
+ }
+}
+
+void ResourceManager::deleteProgram(GLuint program)
+{
+ ProgramMap::iterator programObject = mProgramMap.find(program);
+
+ if (programObject != mProgramMap.end())
+ {
+ if (programObject->second->getRefCount() == 0)
+ {
+ delete programObject->second;
+ mProgramMap.erase(programObject);
+ }
+ else
+ {
+ programObject->second->flagForDeletion();
+ }
+ }
+}
+
+void ResourceManager::deleteTexture(GLuint texture)
+{
+ TextureMap::iterator textureObject = mTextureMap.find(texture);
+
+ if (textureObject != mTextureMap.end())
+ {
+ if (textureObject->second) textureObject->second->release();
+ mTextureMap.erase(textureObject);
+ }
+}
+
+void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
+{
+ RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
+
+ if (renderbufferObject != mRenderbufferMap.end())
+ {
+ if (renderbufferObject->second) renderbufferObject->second->release();
+ mRenderbufferMap.erase(renderbufferObject);
+ }
+}
+
+Buffer *ResourceManager::getBuffer(unsigned int handle)
+{
+ BufferMap::iterator buffer = mBufferMap.find(handle);
+
+ if (buffer == mBufferMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return buffer->second;
+ }
+}
+
+Shader *ResourceManager::getShader(unsigned int handle)
+{
+ ShaderMap::iterator shader = mShaderMap.find(handle);
+
+ if (shader == mShaderMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return shader->second;
+ }
+}
+
+Texture *ResourceManager::getTexture(unsigned int handle)
+{
+ if (handle == 0) return NULL;
+
+ TextureMap::iterator texture = mTextureMap.find(handle);
+
+ if (texture == mTextureMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return texture->second;
+ }
+}
+
+Program *ResourceManager::getProgram(unsigned int handle)
+{
+ ProgramMap::iterator program = mProgramMap.find(handle);
+
+ if (program == mProgramMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return program->second;
+ }
+}
+
+Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
+{
+ RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
+
+ if (renderbuffer == mRenderbufferMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return renderbuffer->second;
+ }
+}
+
+void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
+{
+ mRenderbufferMap[handle] = buffer;
+}
+
+void ResourceManager::checkBufferAllocation(unsigned int buffer)
+{
+ if (buffer != 0 && !getBuffer(buffer))
+ {
+ Buffer *bufferObject = new Buffer(buffer);
+ mBufferMap[buffer] = bufferObject;
+ bufferObject->addRef();
+ }
+}
+
+void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type)
+{
+ if (!getTexture(texture) && texture != 0)
+ {
+ Texture *textureObject;
+
+ if (type == SAMPLER_2D)
+ {
+ textureObject = new Texture2D(texture);
+ }
+ else if (type == SAMPLER_CUBE)
+ {
+ textureObject = new TextureCubeMap(texture);
+ }
+ else
+ {
+ UNREACHABLE();
+ return;
+ }
+
+ mTextureMap[texture] = textureObject;
+ textureObject->addRef();
+ }
+}
+
+void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
+{
+ if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
+ {
+ Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
+ mRenderbufferMap[renderbuffer] = renderbufferObject;
+ renderbufferObject->addRef();
+ }
+}
+
+}
diff --git a/ANGLE/src/libGLESv2/ResourceManager.h b/ANGLE/src/libGLESv2/ResourceManager.h
new file mode 100644
index 0000000..346e51f
--- /dev/null
+++ b/ANGLE/src/libGLESv2/ResourceManager.h
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGLESV2_RESOURCEMANAGER_H_
+#define LIBGLESV2_RESOURCEMANAGER_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include <map>
+
+#include "common/angleutils.h"
+
+namespace gl
+{
+class Buffer;
+class Shader;
+class Program;
+class Texture;
+class Renderbuffer;
+
+enum SamplerType
+{
+ SAMPLER_2D,
+ SAMPLER_CUBE,
+
+ SAMPLER_TYPE_COUNT
+};
+
+class ResourceManager
+{
+ public:
+ ResourceManager();
+ ~ResourceManager();
+
+ void addRef();
+ void release();
+
+ GLuint createBuffer();
+ GLuint createShader(GLenum type);
+ GLuint createProgram();
+ GLuint createTexture();
+ GLuint createRenderbuffer();
+
+ void deleteBuffer(GLuint buffer);
+ void deleteShader(GLuint shader);
+ void deleteProgram(GLuint program);
+ void deleteTexture(GLuint texture);
+ void deleteRenderbuffer(GLuint renderbuffer);
+
+ Buffer *getBuffer(GLuint handle);
+ Shader *getShader(GLuint handle);
+ Program *getProgram(GLuint handle);
+ Texture *getTexture(GLuint handle);
+ Renderbuffer *getRenderbuffer(GLuint handle);
+
+ void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
+
+ void checkBufferAllocation(unsigned int buffer);
+ void checkTextureAllocation(GLuint texture, SamplerType type);
+ void checkRenderbufferAllocation(GLuint renderbuffer);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ResourceManager);
+
+ std::size_t mRefCount;
+
+ typedef std::map<GLuint, Buffer*> BufferMap;
+ BufferMap mBufferMap;
+
+ typedef std::map<GLuint, Shader*> ShaderMap;
+ ShaderMap mShaderMap;
+
+ typedef std::map<GLuint, Program*> ProgramMap;
+ ProgramMap mProgramMap;
+
+ typedef std::map<GLuint, Texture*> TextureMap;
+ TextureMap mTextureMap;
+
+ typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
+ RenderbufferMap mRenderbufferMap;
+};
+
+}
+
+#endif // LIBGLESV2_RESOURCEMANAGER_H_
diff --git a/ANGLE/src/libGLESv2/Shader.cpp b/ANGLE/src/libGLESv2/Shader.cpp
index 730c1b5..b73ef2a 100644
--- a/ANGLE/src/libGLESv2/Shader.cpp
+++ b/ANGLE/src/libGLESv2/Shader.cpp
@@ -21,7 +21,7 @@ namespace gl
void *Shader::mFragmentCompiler = NULL;
void *Shader::mVertexCompiler = NULL;
-Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(context)
+Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
mSource = NULL;
mHlsl = NULL;
@@ -35,21 +35,22 @@ Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(cont
if (result)
{
TBuiltInResource resources;
- resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
- resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
- resources.maxVaryingVectors = MAX_VARYING_VECTORS;
- resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
- resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
- resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
- resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
+ ShInitBuiltInResource(&resources);
+ resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
+ resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
+ resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
+ resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+ resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+ resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
+ resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
}
}
- mAttachCount = 0;
+ mRefCount = 0;
mDeleteStatus = false;
}
@@ -187,24 +188,24 @@ const char *Shader::getHLSL()
return mHlsl;
}
-void Shader::attach()
+void Shader::addRef()
{
- mAttachCount++;
+ mRefCount++;
}
-void Shader::detach()
+void Shader::release()
{
- mAttachCount--;
+ mRefCount--;
- if (mAttachCount == 0 && mDeleteStatus)
+ if (mRefCount == 0 && mDeleteStatus)
{
- mContext->deleteShader(mHandle);
+ mResourceManager->deleteShader(mHandle);
}
}
-bool Shader::isAttached() const
+unsigned int Shader::getRefCount() const
{
- return mAttachCount > 0;
+ return mRefCount;
}
bool Shader::isFlaggedForDeletion() const
@@ -262,6 +263,8 @@ void Shader::parseVaryings()
mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
+ mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
+ mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
}
}
@@ -415,7 +418,7 @@ bool Shader::compareVarying(const Varying &x, const Varying &y)
return false;
}
-VertexShader::VertexShader(Context *context, GLuint handle) : Shader(context, handle)
+VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
}
@@ -479,7 +482,7 @@ void VertexShader::parseAttributes()
}
}
-FragmentShader::FragmentShader(Context *context, GLuint handle) : Shader(context, handle)
+FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
}
diff --git a/ANGLE/src/libGLESv2/Shader.h b/ANGLE/src/libGLESv2/Shader.h
index 777c236..5eaa053 100644
--- a/ANGLE/src/libGLESv2/Shader.h
+++ b/ANGLE/src/libGLESv2/Shader.h
@@ -18,7 +18,7 @@
#include <list>
#include <vector>
-#include "libGLESv2/Context.h"
+#include "libGLESv2/ResourceManager.h"
namespace gl
{
@@ -45,7 +45,7 @@ class Shader
friend Program;
public:
- Shader(Context *context, GLuint handle);
+ Shader(ResourceManager *manager, GLuint handle);
virtual ~Shader();
@@ -63,9 +63,9 @@ class Shader
bool isCompiled();
const char *getHLSL();
- void attach();
- void detach();
- bool isAttached() const;
+ void addRef();
+ void release();
+ unsigned int getRefCount() const;
bool isFlaggedForDeletion() const;
void flagForDeletion();
@@ -82,8 +82,8 @@ class Shader
static bool compareVarying(const Varying &x, const Varying &y);
const GLuint mHandle;
- int mAttachCount; // Number of program objects this shader is attached to
- bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
+ unsigned int mRefCount; // Number of program objects this shader is attached to
+ bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
char *mSource;
char *mHlsl;
@@ -93,8 +93,10 @@ class Shader
bool mUsesFragCoord;
bool mUsesFrontFacing;
+ bool mUsesPointSize;
+ bool mUsesPointCoord;
- Context *mContext;
+ ResourceManager *mResourceManager;
static void *mFragmentCompiler;
static void *mVertexCompiler;
@@ -121,7 +123,7 @@ class VertexShader : public Shader
friend Program;
public:
- VertexShader(Context *context, GLuint handle);
+ VertexShader(ResourceManager *manager, GLuint handle);
~VertexShader();
@@ -140,7 +142,7 @@ class VertexShader : public Shader
class FragmentShader : public Shader
{
public:
- FragmentShader(Context *context, GLuint handle);
+ FragmentShader(ResourceManager *manager, GLuint handle);
~FragmentShader();
diff --git a/ANGLE/src/libGLESv2/Texture.cpp b/ANGLE/src/libGLESv2/Texture.cpp
index 4079d43..2e0b1e3 100644
--- a/ANGLE/src/libGLESv2/Texture.cpp
+++ b/ANGLE/src/libGLESv2/Texture.cpp
@@ -23,7 +23,7 @@ namespace gl
{
Texture::Image::Image()
- : width(0), height(0), dirty(false), surface(NULL)
+ : width(0), height(0), dirty(false), surface(NULL), format(GL_NONE)
{
}
@@ -32,13 +32,16 @@ Texture::Image::~Image()
if (surface) surface->Release();
}
-Texture::Texture(Context *context) : mContext(context)
+Texture::Texture(GLuint id) : RefCountObject(id)
{
mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
mMagFilter = GL_LINEAR;
mWrapS = GL_REPEAT;
mWrapT = GL_REPEAT;
+ mWidth = 0;
+ mHeight = 0;
+
mDirtyMetaData = true;
mDirty = true;
mIsRenderable = false;
@@ -51,7 +54,8 @@ Texture::~Texture()
Blit *Texture::getBlitter()
{
- return mContext->getBlitter();
+ Context *context = getContext();
+ return context->getBlitter();
}
// Returns true on successful filter state update (valid enum parameter)
@@ -173,7 +177,15 @@ GLuint Texture::getHeight() const
// Selects an internal Direct3D 9 format for storing an Image
D3DFORMAT Texture::selectFormat(GLenum format)
{
- return D3DFMT_A8R8G8B8;
+ if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ return D3DFMT_DXT1;
+ }
+ else
+ {
+ return D3DFMT_A8R8G8B8;
+ }
}
int Texture::imagePitch(const Image &img) const
@@ -188,126 +200,282 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
{
GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
+ switch (format)
+ {
+ case GL_ALPHA:
+ loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_LUMINANCE:
+ loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_RGB:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ default: UNREACHABLE();
+ }
+ break;
+
+ case GL_RGBA:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ default: UNREACHABLE();
+ }
+ break;
+ default: UNREACHABLE();
+ }
+}
+
+void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
for (int y = 0; y < height; y++)
{
- const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
- const unsigned short *source16 = reinterpret_cast<const unsigned short*>(source);
- unsigned char *dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = 0;
+ dest[4 * x + 1] = 0;
+ dest[4 * x + 2] = 0;
+ dest[4 * x + 3] = source[x];
+ }
+ }
+}
+void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
for (int x = 0; x < width; x++)
{
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
+ dest[4 * x + 0] = source[x];
+ dest[4 * x + 1] = source[x];
+ dest[4 * x + 2] = source[x];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
- switch (format)
- {
- case GL_ALPHA:
- a = source[x];
- r = 0;
- g = 0;
- b = 0;
- break;
-
- case GL_LUMINANCE:
- r = source[x];
- g = source[x];
- b = source[x];
- a = 0xFF;
- break;
-
- case GL_LUMINANCE_ALPHA:
- r = source[2*x+0];
- g = source[2*x+0];
- b = source[2*x+0];
- a = source[2*x+1];
- break;
-
- case GL_RGB:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- r = source[x * 3 + 0];
- g = source[x * 3 + 1];
- b = source[x * 3 + 2];
- a = 0xFF;
- break;
-
- case GL_UNSIGNED_SHORT_5_6_5:
- {
- unsigned short rgba = source16[x];
+void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
- a = 0xFF;
- b = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
- g = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
- r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- }
- break;
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[2*x+0];
+ dest[4 * x + 1] = source[2*x+0];
+ dest[4 * x + 2] = source[2*x+0];
+ dest[4 * x + 3] = source[2*x+1];
+ }
+ }
+}
- default: UNREACHABLE();
- }
- break;
+void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
- case GL_RGBA:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- r = source[x * 4 + 0];
- g = source[x * 4 + 1];
- b = source[x * 4 + 2];
- a = source[x * 4 + 3];
- break;
-
- case GL_UNSIGNED_SHORT_4_4_4_4:
- {
- unsigned short rgba = source16[x];
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 3 + 2];
+ dest[4 * x + 1] = source[x * 3 + 1];
+ dest[4 * x + 2] = source[x * 3 + 0];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
- a = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
- b = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
- g = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
- r = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
- }
- break;
+void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- {
- unsigned short rgba = source16[x];
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
+ dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
- a = (rgba & 0x0001) ? 0xFF : 0;
- b = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
- g = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
- r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- }
- break;
+void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
- default: UNREACHABLE();
- }
- break;
- default: UNREACHABLE();
- }
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 4 + 2];
+ dest[4 * x + 1] = source[x * 4 + 1];
+ dest[4 * x + 2] = source[x * 4 + 0];
+ dest[4 * x + 3] = source[x * 4 + 3];
+ }
+ }
+}
+
+void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
- dest[4 * x + 0] = b;
- dest[4 * x + 1] = g;
- dest[4 * x + 2] = r;
- dest[4 * x + 3] = a;
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
+ dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
+ dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
+ dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
}
}
}
-void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
+ dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
+ }
+ }
+}
+
+void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ memcpy(dest, source, width*4);
+ }
+}
+
+void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img)
{
+ IDirect3DTexture9 *newTexture = NULL;
IDirect3DSurface9 *newSurface = NULL;
if (width != 0 && height != 0)
{
- HRESULT result = getDevice()->CreateOffscreenPlainSurface(width, height, selectFormat(format), D3DPOOL_SYSTEMMEM, &newSurface, NULL);
+ int levelToFetch = 0;
+ GLsizei requestWidth = width;
+ GLsizei requestHeight = height;
+ if (IsCompressed(format) && (width % 4 != 0 || height % 4 != 0))
+ {
+ bool isMult4 = false;
+ int upsampleCount = 0;
+ while (!isMult4)
+ {
+ requestWidth <<= 1;
+ requestHeight <<= 1;
+ upsampleCount++;
+ if (requestWidth % 4 == 0 && requestHeight % 4 == 0)
+ {
+ isMult4 = true;
+ }
+ }
+ levelToFetch = upsampleCount;
+ }
+
+ HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format),
+ D3DPOOL_SYSTEMMEM, &newTexture, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY);
}
+
+ newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
+ newTexture->Release();
}
if (img->surface) img->surface->Release();
@@ -316,18 +484,23 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
img->width = width;
img->height = height;
img->format = format;
+}
- if (pixels != NULL && newSurface != NULL)
+void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+{
+ createSurface(width, height, format, img);
+
+ if (pixels != NULL && img->surface != NULL)
{
D3DLOCKED_RECT locked;
- HRESULT result = newSurface->LockRect(&locked, NULL, 0);
+ HRESULT result = img->surface->LockRect(&locked, NULL, 0);
ASSERT(SUCCEEDED(result));
if (SUCCEEDED(result))
{
loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
- newSurface->UnlockRect();
+ img->surface->UnlockRect();
}
img->dirty = true;
@@ -336,9 +509,36 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
mDirtyMetaData = true;
}
-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
{
- if (width + xoffset > img->width || height + yoffset > img->height) return error(GL_INVALID_VALUE);
+ createSurface(width, height, format, img);
+
+ if (pixels != NULL && img->surface != NULL)
+ {
+ D3DLOCKED_RECT locked;
+ HRESULT result = img->surface->LockRect(&locked, NULL, 0);
+
+ ASSERT(SUCCEEDED(result));
+
+ if (SUCCEEDED(result))
+ {
+ memcpy(locked.pBits, pixels, imageSize);
+ img->surface->UnlockRect();
+ }
+
+ img->dirty = true;
+ }
+
+ mDirtyMetaData = true;
+}
+
+bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+{
+ if (width + xoffset > img->width || height + yoffset > img->height)
+ {
+ error(GL_INVALID_VALUE);
+ return false;
+ }
D3DLOCKED_RECT locked;
HRESULT result = img->surface->LockRect(&locked, NULL, 0);
@@ -352,6 +552,47 @@ void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
}
img->dirty = true;
+ return true;
+}
+
+bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
+{
+ if (width + xoffset > img->width || height + yoffset > img->height)
+ {
+ error(GL_INVALID_VALUE);
+ return false;
+ }
+
+ if (format != getFormat())
+ {
+ error(GL_INVALID_OPERATION);
+ return false;
+ }
+
+ RECT updateRegion;
+ updateRegion.left = xoffset;
+ updateRegion.right = xoffset + width;
+ updateRegion.bottom = yoffset + height;
+ updateRegion.top = yoffset;
+
+ D3DLOCKED_RECT locked;
+ HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0);
+
+ ASSERT(SUCCEEDED(result));
+
+ if (SUCCEEDED(result))
+ {
+ GLsizei inputPitch = ComputeCompressedPitch(width, format);
+ int rows = imageSize / inputPitch;
+ for (int i = 0; i < rows; ++i)
+ {
+ memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
+ }
+ img->surface->UnlockRect();
+ }
+
+ img->dirty = true;
+ return true;
}
IDirect3DBaseTexture9 *Texture::getTexture()
@@ -442,7 +683,7 @@ int Texture::levelCount() const
return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
}
-Texture2D::Texture2D(Context *context) : Texture(context)
+Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexture = NULL;
mColorbufferProxy = NULL;
@@ -464,6 +705,11 @@ GLenum Texture2D::getTarget() const
return GL_TEXTURE_2D;
}
+GLenum Texture2D::getFormat() const
+{
+ return mImageArray[0].format;
+}
+
// While OpenGL doesn't check texture consistency until draw-time, D3D9 requires a complete texture
// for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels.
// Call this when a particular level of the texture must be defined with a specific format, width and height.
@@ -522,6 +768,13 @@ void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsi
Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
}
+void Texture2D::setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+ redefineTexture(level, internalFormat, width, height);
+
+ Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]);
+}
+
void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
ASSERT(mImageArray[level].surface != NULL);
@@ -559,17 +812,31 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
- commitRect(level, xoffset, yoffset, width, height);
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]))
+ {
+ commitRect(level, xoffset, yoffset, width, height);
+ }
+}
+
+void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[level]))
+ {
+ commitRect(level, xoffset, yoffset, width, height);
+ }
}
-void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (redefineTexture(level, internalFormat, width, height))
{
convertToRenderTarget();
pushTexture(mTexture, true);
}
+ else
+ {
+ needRenderTarget();
+ }
if (width != 0 && height != 0 && level < levelCount())
{
@@ -591,7 +858,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
mImageArray[level].format = internalFormat;
}
-void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
{
@@ -689,6 +956,11 @@ bool Texture2D::isComplete() const
return true;
}
+bool Texture2D::isCompressed() const
+{
+ return IsCompressed(getFormat());
+}
+
// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
IDirect3DBaseTexture9 *Texture2D::createTexture()
{
@@ -871,16 +1143,17 @@ void Texture2D::generateMipmaps()
}
}
-Colorbuffer *Texture2D::getColorbuffer(GLenum target)
+Renderbuffer *Texture2D::getColorbuffer(GLenum target)
{
if (target != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
+ return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
if (mColorbufferProxy == NULL)
{
- mColorbufferProxy = new TextureColorbufferProxy(this, target);
+ mColorbufferProxy = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
+ mColorbufferProxy->addRef();
}
return mColorbufferProxy;
@@ -898,7 +1171,7 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
return renderTarget;
}
-TextureCubeMap::TextureCubeMap(Context *context) : Texture(context)
+TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
{
mTexture = NULL;
@@ -927,6 +1200,11 @@ GLenum TextureCubeMap::getTarget() const
return GL_TEXTURE_CUBE_MAP;
}
+GLenum TextureCubeMap::getFormat() const
+{
+ return mImageArray[0][0].format;
+}
+
void TextureCubeMap::setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
setImage(0, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
@@ -957,6 +1235,13 @@ void TextureCubeMap::setImageNegZ(GLint level, GLenum internalFormat, GLsizei wi
setImage(5, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
+void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+ redefineTexture(level, internalFormat, width);
+
+ Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[faceIndex(face)][level]);
+}
+
void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
int face = faceIndex(faceTarget);
@@ -994,8 +1279,18 @@ void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, G
void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]);
- commitRect(face, level, xoffset, yoffset, width, height);
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]))
+ {
+ commitRect(face, level, xoffset, yoffset, width, height);
+ }
+}
+
+void TextureCubeMap::subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(face)][level]))
+ {
+ commitRect(face, level, xoffset, yoffset, width, height);
+ }
}
// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -1064,6 +1359,11 @@ bool TextureCubeMap::isComplete() const
return true;
}
+bool TextureCubeMap::isCompressed() const
+{
+ return IsCompressed(getFormat());
+}
+
// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
IDirect3DBaseTexture9 *TextureCubeMap::createTexture()
{
@@ -1278,7 +1578,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei
return !textureOkay;
}
-void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
unsigned int faceindex = faceIndex(face);
@@ -1287,6 +1587,10 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat,
convertToRenderTarget();
pushTexture(mTexture, true);
}
+ else
+ {
+ needRenderTarget();
+ }
ASSERT(width == height);
@@ -1340,7 +1644,7 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier
return (SUCCEEDED(hr)) ? surface : NULL;
}
-void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
GLsizei size = mImageArray[faceIndex(face)][level].width;
@@ -1356,7 +1660,7 @@ void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint
}
else
{
- getRenderTarget(face);
+ needRenderTarget();
}
if (level < levelCount())
@@ -1440,18 +1744,19 @@ void TextureCubeMap::generateMipmaps()
}
}
-Colorbuffer *TextureCubeMap::getColorbuffer(GLenum target)
+Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target)
{
if (!IsCubemapTextureTarget(target))
{
- return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
+ return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
unsigned int face = faceIndex(target);
if (mFaceProxies[face] == NULL)
{
- mFaceProxies[face] = new TextureColorbufferProxy(this, target);
+ mFaceProxies[face] = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
+ mFaceProxies[face]->addRef();
}
return mFaceProxies[face];
@@ -1475,6 +1780,16 @@ Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLen
ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
}
+void Texture::TextureColorbufferProxy::addRef() const
+{
+ mTexture->addRef();
+}
+
+void Texture::TextureColorbufferProxy::release() const
+{
+ mTexture->release();
+}
+
IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
{
if (mRenderTarget) mRenderTarget->Release();
@@ -1484,14 +1799,19 @@ IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
return mRenderTarget;
}
-int Texture::TextureColorbufferProxy::getWidth()
+int Texture::TextureColorbufferProxy::getWidth() const
{
return mTexture->getWidth();
}
-int Texture::TextureColorbufferProxy::getHeight()
+int Texture::TextureColorbufferProxy::getHeight() const
{
return mTexture->getHeight();
}
+GLenum Texture::TextureColorbufferProxy::getFormat() const
+{
+ return mTexture->getFormat();
+}
+
}
diff --git a/ANGLE/src/libGLESv2/Texture.h b/ANGLE/src/libGLESv2/Texture.h
index 40fa11d..efa882c 100644
--- a/ANGLE/src/libGLESv2/Texture.h
+++ b/ANGLE/src/libGLESv2/Texture.h
@@ -23,7 +23,6 @@
namespace gl
{
-class Context;
class Blit;
enum
@@ -34,10 +33,10 @@ enum
MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE
};
-class Texture
+class Texture : public RefCountObject
{
public:
- explicit Texture(Context *context);
+ explicit Texture(GLuint id);
virtual ~Texture();
@@ -56,15 +55,19 @@ class Texture
GLuint getWidth() const;
GLuint getHeight() const;
+ virtual GLenum getFormat() const = 0;
virtual bool isComplete() const = 0;
+ virtual bool isCompressed() const = 0;
IDirect3DBaseTexture9 *getTexture();
- virtual Colorbuffer *getColorbuffer(GLenum target) = 0;
+ virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
bool isDirty() const;
+ static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
+
protected:
class TextureColorbufferProxy;
friend class TextureColorbufferProxy;
@@ -74,10 +77,14 @@ class Texture
TextureColorbufferProxy(Texture *texture, GLenum target);
// target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets)
+ virtual void addRef() const;
+ virtual void release() const;
+
virtual IDirect3DSurface9 *getRenderTarget();
- virtual int getWidth();
- virtual int getHeight();
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+ virtual GLenum getFormat() const;
private:
Texture *mTexture;
@@ -102,13 +109,10 @@ class Texture
static D3DFORMAT selectFormat(GLenum format);
int imagePitch(const Image& img) const;
- GLenum mMinFilter;
- GLenum mMagFilter;
- GLenum mWrapS;
- GLenum mWrapT;
-
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
- void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
+ bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
+ void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
+ bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
void needRenderTarget();
@@ -128,45 +132,72 @@ class Texture
Blit *getBlitter();
+ int levelCount() const;
+
unsigned int mWidth;
unsigned int mHeight;
-
- int levelCount() const;
+ GLenum mMinFilter;
+ GLenum mMagFilter;
+ GLenum mWrapS;
+ GLenum mWrapT;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
- Context *mContext;
+ void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+
+ void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
- bool mDirtyMetaData;
- bool mIsRenderable;
bool mDirty;
+ bool mDirtyMetaData;
+ bool mIsRenderable;
- void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
- GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+ void createSurface(GLsizei width, GLsizei height, GLenum format, Image *img);
};
class Texture2D : public Texture
{
public:
- explicit Texture2D(Context *context);
+ explicit Texture2D(GLuint id);
~Texture2D();
GLenum getTarget() const;
+ GLenum getFormat() const;
void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
- void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
- void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+ void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
+ bool isCompressed() const;
virtual void generateMipmaps();
- virtual Colorbuffer *getColorbuffer(GLenum target);
+ virtual Renderbuffer *getColorbuffer(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
@@ -174,30 +205,29 @@ class Texture2D : public Texture
virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
virtual IDirect3DBaseTexture9 *convertToRenderTarget();
+ virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual bool dirtyImageData() const;
+ bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[MAX_TEXTURE_LEVELS];
IDirect3DTexture9 *mTexture;
- TextureColorbufferProxy *mColorbufferProxy;
-
- bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
-
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ Renderbuffer *mColorbufferProxy;
};
class TextureCubeMap : public Texture
{
public:
- explicit TextureCubeMap(Context *context);
+ explicit TextureCubeMap(GLuint id);
~TextureCubeMap();
GLenum getTarget() const;
+ GLenum getFormat() const;
void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
@@ -206,15 +236,19 @@ class TextureCubeMap : public Texture
void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+
void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
- void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
- void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+ void subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
+ bool isCompressed() const;
virtual void generateMipmaps();
- virtual Colorbuffer *getColorbuffer(GLenum target);
+ virtual Renderbuffer *getColorbuffer(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
@@ -222,6 +256,7 @@ class TextureCubeMap : public Texture
virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
virtual IDirect3DBaseTexture9 *convertToRenderTarget();
+ virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual bool dirtyImageData() const;
@@ -241,9 +276,7 @@ class TextureCubeMap : public Texture
IDirect3DCubeTexture9 *mTexture;
- TextureColorbufferProxy *mFaceProxies[6];
-
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ Renderbuffer *mFaceProxies[6];
};
}
diff --git a/ANGLE/src/libGLESv2/libGLESv2.cpp b/ANGLE/src/libGLESv2/libGLESv2.cpp
index a136bd3..25d083b 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.cpp
+++ b/ANGLE/src/libGLESv2/libGLESv2.cpp
@@ -180,7 +180,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM);
}
@@ -189,7 +189,15 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
if (context)
{
- context->bindFramebuffer(framebuffer);
+ if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindReadFramebuffer(framebuffer);
+ }
+
+ if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindDrawFramebuffer(framebuffer);
+ }
}
}
catch(std::bad_alloc&)
@@ -559,7 +567,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM, 0);
}
@@ -568,7 +576,15 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
if (context)
{
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ }
return framebuffer->completeness();
}
@@ -720,22 +736,107 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
try
{
- if (!gl::IsTextureTarget(target))
+ if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
{
- return error(GL_INVALID_ENUM);
+ return error(GL_INVALID_VALUE);
}
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+ if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
- if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
+ switch (target)
+ {
+ case GL_TEXTURE_2D:
+ if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ 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 (width != height)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ switch (internalformat)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if (border != 0)
{
return error(GL_INVALID_VALUE);
}
- return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (!context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ }
+
+ if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (target == GL_TEXTURE_2D)
+ {
+ gl::Texture2D *texture = context->getTexture2D();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+ }
+ else
+ {
+ gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ switch (target)
+ {
+ 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:
+ texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+ break;
+ default: UNREACHABLE();
+ }
+ }
+ }
+
}
catch(std::bad_alloc&)
{
@@ -763,17 +864,95 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
return error(GL_INVALID_VALUE);
}
- if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
+ if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
+ (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
- if (xoffset != 0 || yoffset != 0)
+ switch (format)
{
- return error(GL_INVALID_OPERATION);
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if (width == 0 || height == 0 || data == NULL)
+ {
+ return;
}
- return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (!context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
+ }
+
+ if (imageSize != gl::ComputeCompressedSize(width, height, format))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (xoffset % 4 != 0 || yoffset % 4 != 0)
+ {
+ return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
+ // does not exist unless DXT1 textures are supported.
+ }
+
+ if (target == GL_TEXTURE_2D)
+ {
+ gl::Texture2D *texture = context->getTexture2D();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if ((width % 4 != 0 && width != texture->getWidth()) ||
+ (height % 4 != 0 && height != texture->getHeight()))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else if (gl::IsCubemapTextureTarget(target))
+ {
+ gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if ((width % 4 != 0 && width != texture->getWidth()) ||
+ (height % 4 != 0 && height != texture->getHeight()))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
}
catch(std::bad_alloc&)
{
@@ -834,6 +1013,8 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_RGBA:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: // a different error is generated than otherwise. That is handled below.
break;
default:
return error(GL_INVALID_VALUE);
@@ -848,8 +1029,31 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (context)
{
- gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
+ if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -858,6 +1062,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
{
return error(GL_INVALID_OPERATION);
}
+
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
texture->copyImage(level, internalformat, x, y, width, height, source);
}
@@ -870,6 +1079,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copyImage(target, level, internalformat, x, y, width, height, source);
}
else
@@ -916,8 +1130,18 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
if (context)
{
- gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -927,6 +1151,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -938,6 +1167,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
}
else
@@ -1559,7 +1793,8 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
try
{
- if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
+ if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ || renderbuffertarget != GL_RENDERBUFFER)
{
return error(GL_INVALID_ENUM);
}
@@ -1568,9 +1803,20 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
if (context)
{
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ GLuint framebufferHandle = 0;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ framebufferHandle = context->getReadFramebufferHandle();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ framebufferHandle = context->getDrawFramebufferHandle();
+ }
- if (context->getFramebufferHandle() == 0 || !framebuffer)
+ if (framebufferHandle == 0 || !framebuffer)
{
return error(GL_INVALID_OPERATION);
}
@@ -1604,7 +1850,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM);
}
@@ -1636,6 +1882,11 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
return error(GL_INVALID_OPERATION);
}
+ if (tex->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
switch (textarget)
{
case GL_TEXTURE_2D:
@@ -1667,9 +1918,20 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
}
}
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ GLuint framebufferHandle = 0;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ framebufferHandle = context->getReadFramebufferHandle();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ framebufferHandle = context->getDrawFramebufferHandle();
+ }
- if (context->getFramebufferHandle() == 0 || !framebuffer)
+ if (framebufferHandle == 0 || !framebuffer)
{
return error(GL_INVALID_OPERATION);
}
@@ -1770,6 +2032,11 @@ void __stdcall glGenerateMipmap(GLenum target)
return error(GL_INVALID_ENUM);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->generateMipmaps();
}
}
@@ -2225,14 +2492,29 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
if (context)
{
- if (context->getFramebufferHandle() == 0)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_OPERATION);
+ return error(GL_INVALID_ENUM);
}
- if (target != GL_FRAMEBUFFER)
+ gl::Framebuffer *framebuffer = NULL;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM);
+ if(context->getReadFramebufferHandle() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ framebuffer = context->getReadFramebuffer();
+ }
+ else
+ {
+ if (context->getDrawFramebufferHandle() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ framebuffer = context->getDrawFramebuffer();
}
GLenum attachmentType;
@@ -2240,16 +2522,16 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
switch (attachment)
{
case GL_COLOR_ATTACHMENT0:
- attachmentType = context->getFramebuffer()->getColorbufferType();
- attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
+ attachmentType = framebuffer->getColorbufferType();
+ attachmentHandle = framebuffer->getColorbufferHandle();
break;
case GL_DEPTH_ATTACHMENT:
- attachmentType = context->getFramebuffer()->getDepthbufferType();
- attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
+ attachmentType = framebuffer->getDepthbufferType();
+ attachmentHandle = framebuffer->getDepthbufferHandle();
break;
case GL_STENCIL_ATTACHMENT:
- attachmentType = context->getFramebuffer()->getStencilbufferType();
- attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
+ attachmentType = framebuffer->getStencilbufferType();
+ attachmentHandle = framebuffer->getStencilbufferHandle();
break;
default: return error(GL_INVALID_ENUM);
}
@@ -2508,7 +2790,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_RED_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
}
else
{
@@ -2518,7 +2800,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_GREEN_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
}
else
{
@@ -2528,7 +2810,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_BLUE_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
}
else
{
@@ -2538,7 +2820,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_ALPHA_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
}
else
{
@@ -2548,7 +2830,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_DEPTH_SIZE:
if (renderbuffer->isDepthbuffer())
{
- *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
+ *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
}
else
{
@@ -2558,13 +2840,25 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_STENCIL_SIZE:
if (renderbuffer->isStencilbuffer())
{
- *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
+ *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
}
else
{
*params = 0;
}
break;
+ case GL_RENDERBUFFER_SAMPLES_ANGLE:
+ {
+ if (context->getMaxSupportedSamples() != 0)
+ {
+ *params = renderbuffer->getStorage()->getSamples();
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -2993,7 +3287,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE);
}
- gl::AttributeState attribState = context->getVertexAttribState(index);
+ const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
@@ -3013,7 +3307,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *params = (GLfloat)attribState.mBoundBuffer;
+ *params = (GLfloat)attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
@@ -3046,7 +3340,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE);
}
- gl::AttributeState attribState = context->getVertexAttribState(index);
+ const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
@@ -3066,7 +3360,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *params = attribState.mBoundBuffer;
+ *params = attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
@@ -3481,6 +3775,17 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe
return error(GL_INVALID_OPERATION);
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ break;
+ default:
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
switch (type)
{
@@ -3521,10 +3826,10 @@ void __stdcall glReleaseShaderCompiler(void)
}
}
-void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
- TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, internalformat, width, height);
+ TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, samples, internalformat, width, height);
try
{
@@ -3543,12 +3848,15 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
case GL_RGB5_A1:
case GL_RGB565:
case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
break;
default:
return error(GL_INVALID_ENUM);
}
- if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
+ if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -3557,7 +3865,13 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
if (context)
{
- if (context->getRenderbufferHandle() == 0)
+ if (samples > context->getMaxSupportedSamples())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ GLuint handle = context->getRenderbufferHandle();
+ if (handle == 0)
{
return error(GL_INVALID_OPERATION);
}
@@ -3565,15 +3879,20 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
switch (internalformat)
{
case GL_DEPTH_COMPONENT16:
- context->setRenderbuffer(new gl::Depthbuffer(width, height));
+ context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
break;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
- context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
break;
case GL_STENCIL_INDEX8:
- context->setRenderbuffer(new gl::Stencilbuffer(width, height));
+ context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
+ break;
+ case GL_DEPTH24_STENCIL8_OES:
+ context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
break;
default:
return error(GL_INVALID_ENUM);
@@ -3586,6 +3905,11 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
}
}
+void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
+}
+
void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
{
TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
@@ -3958,6 +4282,18 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
return error(GL_INVALID_ENUM);
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
default:
return error(GL_INVALID_VALUE);
}
@@ -3971,6 +4307,19 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (context)
{
+ if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -4146,6 +4495,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -4157,6 +4511,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else
@@ -4965,7 +5324,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
if (context)
{
- context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
+ context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
}
}
catch(std::bad_alloc&)
@@ -4998,6 +5357,54 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
}
+void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+ "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+ "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+ srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+ try
+ {
+ switch (filter)
+ {
+ case GL_NEAREST:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
+ {
+ ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
+ {
+ ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
@@ -5027,6 +5434,7 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
static const Extension glExtensions[] =
{
{"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
+ {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
};
for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
diff --git a/ANGLE/src/libGLESv2/libGLESv2.def b/ANGLE/src/libGLESv2/libGLESv2.def
index 0aaaa67..a043ed8 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.def
+++ b/ANGLE/src/libGLESv2/libGLESv2.def
@@ -144,11 +144,13 @@ EXPORTS
glViewport @142
; Extensions
- glTexImage3DOES @143
+ glTexImage3DOES @143
+ glBlitFramebufferANGLE @149
+ glRenderbufferStorageMultisampleANGLE @150
; EGL dependencies
- glCreateContext @144 NONAME
- glDestroyContext @145 NONAME
- glMakeCurrent @146 NONAME
- glGetCurrentContext @147 NONAME
+ glCreateContext @144 NONAME
+ glDestroyContext @145 NONAME
+ glMakeCurrent @146 NONAME
+ glGetCurrentContext @147 NONAME
glGetProcAddress @148 NONAME \ No newline at end of file
diff --git a/ANGLE/src/libGLESv2/libGLESv2.vcproj b/ANGLE/src/libGLESv2/libGLESv2.vcproj
index e994e05..f9e34d0 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.vcproj
+++ b/ANGLE/src/libGLESv2/libGLESv2.vcproj
@@ -217,10 +217,18 @@
>
</File>
<File
+ RelativePath=".\RefCountObject.cpp"
+ >
+ </File>
+ <File
RelativePath=".\Renderbuffer.cpp"
>
</File>
<File
+ RelativePath=".\ResourceManager.cpp"
+ >
+ </File>
+ <File
RelativePath=".\Shader.cpp"
>
</File>
@@ -299,10 +307,18 @@
>
</File>
<File
+ RelativePath=".\RefCountObject.h"
+ >
+ </File>
+ <File
RelativePath=".\Renderbuffer.h"
>
</File>
<File
+ RelativePath=".\ResourceManager.h"
+ >
+ </File>
+ <File
RelativePath=".\Shader.h"
>
</File>
diff --git a/ANGLE/src/libGLESv2/main.h b/ANGLE/src/libGLESv2/main.h
index dec112a..7f9c880 100644
--- a/ANGLE/src/libGLESv2/main.h
+++ b/ANGLE/src/libGLESv2/main.h
@@ -11,6 +11,7 @@
#define GL_APICALL
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include "common/debug.h"
#include "libEGL/Display.h"
diff --git a/ANGLE/src/libGLESv2/utilities.cpp b/ANGLE/src/libGLESv2/utilities.cpp
index f584588..7fc2bc4 100644
--- a/ANGLE/src/libGLESv2/utilities.cpp
+++ b/ANGLE/src/libGLESv2/utilities.cpp
@@ -183,6 +183,49 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
return (rawPitch + alignment - 1) & ~(alignment - 1);
}
+GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return 0;
+ }
+
+ ASSERT(width % 4 == 0);
+
+ return 8 * width / 4;
+}
+
+GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return 0;
+ }
+
+ return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
+}
+
+bool IsCompressed(GLenum format)
+{
+ if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
// Returns the size, in bytes, of a single texel in an Image
int ComputePixelSize(GLenum format, GLenum type)
{
@@ -196,6 +239,7 @@ int ComputePixelSize(GLenum format, GLenum type)
case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
case GL_RGB: return sizeof(unsigned char) * 3;
case GL_RGBA: return sizeof(unsigned char) * 4;
+ case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
default: UNREACHABLE();
}
break;
@@ -228,6 +272,7 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
switch (format)
{
case GL_RGBA:
+ case GL_BGRA_EXT:
case GL_RGB:
case GL_ALPHA:
case GL_LUMINANCE:
@@ -599,12 +644,31 @@ D3DFORMAT ConvertRenderbufferFormat(GLenum format)
switch (format)
{
case GL_RGBA4:
- case GL_RGB5_A1: return D3DFMT_A8R8G8B8;
+ case GL_RGB5_A1:
+ case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
case GL_RGB565: return D3DFMT_R5G6B5;
+ case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
case GL_DEPTH_COMPONENT16:
- case GL_STENCIL_INDEX8: return D3DFMT_D24S8;
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
}
}
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
+{
+ if (type == D3DMULTISAMPLE_NONMASKABLE)
+ return 0;
+ else
+ return type;
+}
+
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
+{
+ if (samples <= 1)
+ return D3DMULTISAMPLE_NONE;
+ else
+ return (D3DMULTISAMPLE_TYPE)samples;
+}
+
}
diff --git a/ANGLE/src/libGLESv2/utilities.h b/ANGLE/src/libGLESv2/utilities.h
index 6e6c140..b6c8ce5 100644
--- a/ANGLE/src/libGLESv2/utilities.h
+++ b/ANGLE/src/libGLESv2/utilities.h
@@ -11,6 +11,7 @@
#define GL_APICALL
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <d3d9.h>
namespace gl
@@ -28,6 +29,9 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
int ComputePixelSize(GLenum format, GLenum type);
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
+GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
+GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
+bool IsCompressed(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
bool IsTextureTarget(GLenum target);
bool CheckTextureFormatType(GLenum format, GLenum type);
@@ -56,6 +60,8 @@ unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
}
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
index 5e0536f..8bd33d6 100644
--- a/JavaScriptCore/API/JSObjectRef.cpp
+++ b/JavaScriptCore/API/JSObjectRef.cpp
@@ -382,7 +382,7 @@ bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRe
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
- JSValue jsValue = toJS(exec, value);
+ JSValue jsValue = value ? toJS(exec, value) : JSValue();
Identifier name(propertyName->identifier(&exec->globalData()));
if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) {
static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(name, jsValue);
diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c
index 183abf5..1ecfc7e 100644
--- a/JavaScriptCore/API/tests/testapi.c
+++ b/JavaScriptCore/API/tests/testapi.c
@@ -933,17 +933,15 @@ int main(int argc, char* argv[])
JSStringRef privatePropertyName = JSStringCreateWithUTF8CString("privateProperty");
if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, aHeapRef)) {
printf("FAIL: Could not set private property.\n");
- failed = 1;
- } else {
+ failed = 1;
+ } else
printf("PASS: Set private property.\n");
- }
aStackRef = 0;
if (JSObjectSetPrivateProperty(context, aHeapRef, privatePropertyName, aHeapRef)) {
printf("FAIL: JSObjectSetPrivateProperty should fail on non-API objects.\n");
- failed = 1;
- } else {
+ failed = 1;
+ } else
printf("PASS: Did not allow JSObjectSetPrivateProperty on a non-API object.\n");
- }
if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName) != aHeapRef) {
printf("FAIL: Could not retrieve private property.\n");
failed = 1;
@@ -954,15 +952,15 @@ int main(int argc, char* argv[])
failed = 1;
} else
printf("PASS: JSObjectGetPrivateProperty return NULL.\n");
-
+
if (JSObjectGetProperty(context, myObject, privatePropertyName, 0) == aHeapRef) {
printf("FAIL: Accessed private property through ordinary property lookup.\n");
failed = 1;
} else
printf("PASS: Cannot access private property through ordinary property lookup.\n");
-
+
JSGarbageCollect(context);
-
+
for (int i = 0; i < 10000; i++)
JSObjectMake(context, 0, 0);
@@ -973,7 +971,18 @@ int main(int argc, char* argv[])
} else
printf("PASS: Private property does not appear to have been collected.\n");
JSStringRelease(lengthStr);
-
+
+ if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, 0)) {
+ printf("FAIL: Could not set private property to NULL.\n");
+ failed = 1;
+ } else
+ printf("PASS: Set private property to NULL.\n");
+ if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName)) {
+ printf("FAIL: Could not retrieve private property.\n");
+ failed = 1;
+ } else
+ printf("PASS: Retrieved private property.\n");
+
JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}");
JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON);
JSStringRelease(validJSON);
diff --git a/JavaScriptCore/CMakeListsEfl.txt b/JavaScriptCore/CMakeListsEfl.txt
index 7897ea5..90ee22b 100644
--- a/JavaScriptCore/CMakeListsEfl.txt
+++ b/JavaScriptCore/CMakeListsEfl.txt
@@ -8,6 +8,12 @@ LIST(APPEND JavaScriptCore_LIBRARIES
${ICU_I18N_LIBRARIES}
)
+IF (ENABLE_GLIB_SUPPORT)
+ LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
+ ${JAVASCRIPTCORE_DIR}/wtf/gobject
+ )
+ENDIF ()
+
LIST(APPEND JavaScriptCore_LINK_FLAGS
${ECORE_LDFLAGS}
)
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 1cf4ccd..85860d8 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,476 @@
+2010-09-09 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Added a regular expression tracing facility. This tracing is connected
+ to jsc. Every compiled regular expression object is added to a list.
+ When the process exits, each regular expression dumps its pattern,
+ JIT address, number of times it was executed and the number of matches.
+ This tracing is controlled by the macro ENABLE_REGEXP_TRACING in
+ wtf/Platform.h.
+ https://bugs.webkit.org/show_bug.cgi?id=45401
+
+ * JavaScriptCore.exp:
+ * jsc.cpp:
+ (runWithScripts):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ (JSC::JSGlobalData::addRegExpToTrace):
+ (JSC::JSGlobalData::dumpRegExpTrace):
+ * runtime/JSGlobalData.h:
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::create):
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+ * wtf/Platform.h:
+ * yarr/RegexJIT.h:
+ (JSC::Yarr::RegexCodeBlock::getAddr):
+
+2010-09-09 John Therrell <jtherrell@apple.com>
+
+ 32-bit build fix.
+
+ * jit/ExecutableAllocator.cpp:
+ (JSC::ExecutableAllocator::committedByteCount):
+
+2010-09-09 John Therrell <jtherrell@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Added statistics sampling and reporting for JavaScriptCore's RegisterFile and ExecutableAllocator classes
+ https://bugs.webkit.org/show_bug.cgi?id=45134
+
+ Added thread-safe committed byte counting and reporting functionality to RegisterFile and
+ ExecutableAllocator.
+
+ * JavaScriptCore.exp:
+ Exported new symbols to allow for WebKit to get statistics from JavaScriptCore classes.
+
+ * interpreter/RegisterFile.cpp:
+ (JSC::registerFileStatisticsMutex):
+ Added function which returns a static Mutex used for locking during read/write access to
+ static committed byte count variable.
+ (JSC::RegisterFile::~RegisterFile):
+ Added call to addToStatistics since memory is decommitted here.
+ (JSC::RegisterFile::releaseExcessCapacity):
+ Added call to addToStatistics since memory is decommitted here.
+ (JSC::RegisterFile::initializeThreading):
+ Added function which calls registerFileStatisticsMutex().
+ (JSC::RegisterFile::committedByteCount):
+ Added function which returns the current committed byte count for RegisterFile.
+ (JSC::RegisterFile::addToCommittedByteCount):
+ Added function which updates committed byte count.
+
+ * interpreter/RegisterFile.h:
+ (JSC::RegisterFile::RegisterFile):
+ Added call to addToStatistics since memory is committed here.
+ (JSC::RegisterFile::grow):
+ Added call to addToStatistics since memory is committed here.
+
+ * jit/ExecutableAllocator.h:
+ Added function prototype for public static function committedByteCount().
+
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::FixedVMPoolAllocator::release):
+ Added call to addToStatistics since memory is decommitted here.
+ (JSC::FixedVMPoolAllocator::reuse):
+ Added call to addToStatistics since memory is committed here.
+ (JSC::FixedVMPoolAllocator::addToCommittedByteCount):
+ Added function which updates committed byte count.
+ (JSC::ExecutableAllocator::committedByteCount):
+ Added function which returns the current committed byte count for ExecutableAllocator.
+
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ Added call to RegisterFile::initializeThreading.
+
+2010-09-09 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <http://webkit.org/b/45502> JSObjectSetPrivateProperty does not handle NULL values as it claims
+
+ * API/JSObjectRef.cpp:
+ (JSObjectSetPrivateProperty): Don't call toJS if we have a NULL value as that will cause an assertion
+ failure. Instead map NULL directly to the null JSValue.
+ * API/tests/testapi.c:
+ (main): Add test coverage for the NULL value case.
+
+2010-09-09 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ [Qt] JSVALUE32_64 not works on Windows platform with MinGW compiler
+ https://bugs.webkit.org/show_bug.cgi?id=29268
+
+ * wtf/Platform.h: Enable JSVALUE32_64 for Qt/Windows/MinGW, because it works now.
+
+2010-09-08 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Removing doneSemicolon label in the lexer
+ https://bugs.webkit.org/show_bug.cgi?id=45289
+
+ As a side effect of moving the multiline comment parsing
+ to a separate function, an opportunity raised to simplify
+ the single line comment parsing, and removing doneSemicolon
+ label. Slight performance increase on --parse-only
+ tests (from 32.8ms to 31.5ms)
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::lex):
+
+2010-09-08 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Remove accessor for private member variable in JSParser
+ https://bugs.webkit.org/show_bug.cgi?id=45378
+
+ m_token is private to JSParser, so it does not seem to be useful
+ to have an accessor for it. On top of that, the file was both
+ using the accessor and directly accessing the member variable,
+ only one style should be used.
+
+2010-09-08 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ [Qt] REGRESSION(63348): jsc is broken
+ https://bugs.webkit.org/show_bug.cgi?id=42818
+
+ Need fastcall conventions on Qt/Win/MinGW.
+ Based on patches of Gavin Barraclough: r63947 and r63948.
+
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+
+2010-09-08 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ Remove some unnecessary duplicate calls to string functions
+
+ https://bugs.webkit.org/show_bug.cgi?id=45314
+
+ * wtf/text/WTFString.cpp:
+ (WTF::String::format):
+
+2010-09-08 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ Re-Disable JIT for MSVC 64bit to fix the build on this compiler.
+ https://bugs.webkit.org/show_bug.cgi?id=45382
+
+ It was enabled in the cleanup made in r64176, though it is still
+ not implemented.
+
+ * wtf/Platform.h:
+
+2010-09-08 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Need a WebSocket implementation
+ https://bugs.webkit.org/show_bug.cgi?id=45197
+
+ Add a GIO-based WebSocket implementation.
+
+ * wtf/gobject/GRefPtr.cpp: Added PlatformRefPtr support for GSource.
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+ * wtf/gobject/GRefPtr.h: Added new template specialization declarations.
+ * wtf/gobject/GTypedefs.h: Add some more GLib/GIO forward declarations.
+
+2010-08-30 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Handle MediaQueryExp memory management exclusively with smart pointers
+ https://bugs.webkit.org/show_bug.cgi?id=44874
+
+ Implemented a non-copying sort function to make it possible to sort a Vector
+ of OwnPtrs (which cannot be copied). This is required for the above.
+
+ * wtf/NonCopyingSort.h: Added.
+ (WTF::nonCopyingSort): It's secretly heapsort.
+ (WTF::heapSort): heapsort implementation.
+ (WTF::siftDown): Helper function for heapsort.
+ (WTF::heapify): ditto
+
+ Adjust build systems.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-09-08 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Refactoring multiline comments in the lexer
+ https://bugs.webkit.org/show_bug.cgi?id=45289
+
+ MultiLine comment parsing is moved to a separate function.
+
+ Slight performance increase on --parse-only tests (from 33.6ms to 32.8ms)
+ SunSpider reports no change (from 523.1ms to 521.2ms).
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::parseMultilineComment):
+ (JSC::Lexer::lex):
+ * parser/Lexer.h:
+
+2010-09-07 James Robinson <jamesr@chromium.org>
+
+ Compile fix attempt for windows.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-09-07 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by James Robinson.
+
+ Fix Windows build after r66936
+ https://bugs.webkit.org/show_bug.cgi?id=45348
+
+ Add symbol names that were missing from r66936.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-09-07 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Oliver Hunt.
+
+ pushState and replaceState do not clone RegExp objects correctly
+ https://bugs.webkit.org/show_bug.cgi?id=44718
+
+ Move internal representation of JSC::RegExp (which depends on wether
+ YARR and YARR_JIT is enabled) into RegExpRepresentation which can live
+ in the implementation only. This makes it feasible to use RegExp in
+ WebCore without bringing in all of YARR.
+
+ * JavaScriptCore.exp: Export RegExp and RegExpObject functions that are
+ needed inside WebCore's JSC bindings.
+ * runtime/RegExp.cpp:
+ (JSC::RegExpRepresentation::~RegExpRepresentation):
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::~RegExp):
+ (JSC::RegExp::compile):
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+
+2010-09-07 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/8381749> -Wcast-align warning emitted when building with clang
+
+ Remove the -Wcast-align-warning since it isn't really useful, and clang is more aggressive about warning than gcc.
+
+ * Configurations/Base.xcconfig:
+
+2010-09-07 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ REGRESSION(66741): Undefined pthread macros
+ https://bugs.webkit.org/show_bug.cgi?id=45246
+
+ PTHREAD_MUTEX_NORMAL and PTHREAD_MUTEX_DEFAULT (introduced in r60487) are not defined on Linux,
+ but used in a statement. Add an additional check to test this.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::initializeScavenger):
+
+2010-09-06 Oliver Hunt <oliver@apple.com>
+
+ Windows build fix
+
+2010-09-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ SerializedScriptValue needs to use a flat storage mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=45244
+
+ Export JSArray::put
+
+ * JavaScriptCore.exp:
+
+2010-09-06 Chao-ying Fu <fu@mips.com>
+
+ Reviewed by Oliver Hunt.
+
+ Support JSVALUE32_64 on MIPS
+ https://bugs.webkit.org/show_bug.cgi?id=43999
+
+ Add missing functions to support JSVALUE32_64 on MIPS.
+ Remove JSVALUE32 as the default for MIPS.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::divd):
+ (JSC::MIPSAssembler::mthc1):
+ (JSC::MIPSAssembler::cvtwd):
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::neg32):
+ (JSC::MacroAssemblerMIPS::branchOr32):
+ (JSC::MacroAssemblerMIPS::set8):
+ (JSC::MacroAssemblerMIPS::loadDouble):
+ (JSC::MacroAssemblerMIPS::divDouble):
+ (JSC::MacroAssemblerMIPS::convertInt32ToDouble):
+ (JSC::MacroAssemblerMIPS::branchDouble):
+ (JSC::MacroAssemblerMIPS::branchConvertDoubleToInt32):
+ (JSC::MacroAssemblerMIPS::zeroDouble):
+ * jit/JIT.h:
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks):
+ * jit/JITStubs.h:
+ * wtf/Platform.h:
+
+2010-09-06 Robert Hogan <robert@webkit.org>
+
+ Unreviewed, compile fix.
+
+ Fix compile failure in r66843
+
+ Revert to original patch in bugzilla. Leave bug open for
+ discussion on potential removal of double utf8 conversion.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45240
+
+ * wtf/text/WTFString.cpp:
+ (WTF::String::format):
+
+2010-09-06 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] utf8 encoding of console() messages
+
+ Unskip:
+ http/tests/security/xssAuditor/embed-tag-null-char.html
+ http/tests/security/xssAuditor/object-embed-tag-null-char.html
+
+ Both tests failed because Qt's implementation of String::format()
+ is casting a utf8 result to String, which assumes latin1 in
+ its constructor. So instead of casting a QString to a String, use
+ StringImpl::create() instead. Unfortunately, this involves a lot
+ of extra casts but the end result is correct.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45240
+
+ * wtf/text/WTFString.cpp:
+ (WTF::String::format):
+
+2010-09-03 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45135
+ <rdar://problem/7823714> TCMalloc_PageHeap doesn't hold a mutex while manipulating shared data
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::initializeScavenger): Make sure to create a non-recursive mutex
+ regardless of platform default, so that we can assert that it's held (this is for platforms
+ that don't have libdispatch).
+ (WTF::TCMalloc_PageHeap::signalScavenger): Assert that the mutex is held, so we can look
+ at m_scavengeThreadActive. For platforms that have libdispatch, assert that pageheap_lock
+ is held.
+ (WTF::TCMalloc_PageHeap::periodicScavenge): Make sure that pageheap_lock is held before
+ manipulating m_scavengeThreadActive. Otherwise, there is an obvious race condition, and we
+ can make unbalanced calls to dispatch_resume().
+
+2010-09-03 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Martin Robinson.
+
+ [EFL] Regression (66531) Build break with Glib Support
+ https://bugs.webkit.org/show_bug.cgi?id=45011
+
+ Move GtkTypedefs.h to GTypedefs.h and let it inside gobject directory
+ since when glib is enabled, EFL port needs it, too.
+
+ * CMakeListsEfl.txt: Include gobject directory to find new header
+ file.
+ * GNUmakefile.am: Ditto.
+ * wtf/CMakeListsEfl.txt: Ditto.
+ * wtf/Platform.h: Include header if port is EFL and glib support is
+ enabled.
+ * wtf/gtk/GtkTypedefs.h: Removed.
+ * wtf/gobject/GTypedefs.h: Added. Sections specific to GTK are now
+ guarded by PLATFORM(GTK).
+
+2010-09-03 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ Fix warning in wtf/ByteArray.h
+ https://bugs.webkit.org/show_bug.cgi?id=44672
+
+ * wtf/ByteArray.h: Use maximal sized array for MSVC and unsized array for other compilers.
+
+2010-09-02 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Actually parse a URL from ParsedURL
+ https://bugs.webkit.org/show_bug.cgi?id=45080
+
+ This patch only handles standard URLs. At some point we'll need to
+ distinguish between standard URLs and other kinds of URLs.
+
+ * wtf/url/api/ParsedURL.cpp:
+ (WTF::ParsedURL::ParsedURL):
+
+2010-09-02 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Add ParsedURL and URLString to WTFURL API
+ https://bugs.webkit.org/show_bug.cgi?id=45078
+
+ Currently there's no actual URL parsing going on, but this patch is a
+ start to sketching out the API.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/url/api/ParsedURL.cpp: Added.
+ (WTF::ParsedURL::ParsedURL):
+ (WTF::ParsedURL::scheme):
+ (WTF::ParsedURL::username):
+ (WTF::ParsedURL::password):
+ (WTF::ParsedURL::host):
+ (WTF::ParsedURL::port):
+ (WTF::ParsedURL::path):
+ (WTF::ParsedURL::query):
+ (WTF::ParsedURL::fragment):
+ (WTF::ParsedURL::segment):
+ * wtf/url/api/ParsedURL.h: Added.
+ (WTF::ParsedURL::spec):
+ * wtf/url/api/URLString.h: Added.
+ (WTF::URLString::URLString):
+ (WTF::URLString::string):
+
+2010-09-02 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Add WTFURL to the JavaScriptCore build on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=45075
+
+ Building code is good.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
2010-09-02 Alexey Proskuryakov <ap@apple.com>
Reviewed by Oliver Hunt.
diff --git a/JavaScriptCore/Configurations/Base.xcconfig b/JavaScriptCore/Configurations/Base.xcconfig
index 72de2fe..09b6de1 100644
--- a/JavaScriptCore/Configurations/Base.xcconfig
+++ b/JavaScriptCore/Configurations/Base.xcconfig
@@ -57,14 +57,14 @@ VALID_ARCHS_macosx = i386 ppc x86_64 ppc64 $(ARCHS_UNIVERSAL_IPHONE_OS);
WARNING_CFLAGS_BASE = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings;
WARNING_CFLAGS = $(WARNING_CFLAGS_$(REAL_PLATFORM_NAME));
WARNING_CFLAGS_iphoneos = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
-WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
+WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
WARNING_CFLAGS_macosx = $(WARNING_CFLAGS_macosx_$(CURRENT_ARCH));
-WARNING_CFLAGS_macosx_ = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
-WARNING_CFLAGS_macosx_i386 = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
-WARNING_CFLAGS_macosx_ppc = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
+WARNING_CFLAGS_macosx_ = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
+WARNING_CFLAGS_macosx_i386 = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
+WARNING_CFLAGS_macosx_ppc = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
// FIXME: JavaScriptCore 64-bit builds should build with -Wshorten-64-to-32
-WARNING_CFLAGS_macosx_ppc64 = $(WARNING_CFLAGS_BASE) -Wcast-align;
-WARNING_CFLAGS_macosx_x86_64 = $(WARNING_CFLAGS_BASE) -Wcast-align;
+WARNING_CFLAGS_macosx_ppc64 = $(WARNING_CFLAGS_BASE);
+WARNING_CFLAGS_macosx_x86_64 = $(WARNING_CFLAGS_BASE);
HEADER_SEARCH_PATHS = . icu $(HEADER_SEARCH_PATHS);
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index 29f35ef..673e234 100644
--- a/JavaScriptCore/Configurations/Version.xcconfig
+++ b/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 534;
-MINOR_VERSION = 7;
+MINOR_VERSION = 8;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index b4c658e..dd2ba21 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -442,7 +442,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/gobject/GOwnPtr.h \
JavaScriptCore/wtf/gobject/GRefPtr.cpp \
JavaScriptCore/wtf/gobject/GRefPtr.h \
- JavaScriptCore/wtf/gtk/GtkTypedefs.h \
+ JavaScriptCore/wtf/gobject/GTypedefs.h \
JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \
JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \
JavaScriptCore/wtf/HashCountedSet.h \
@@ -463,6 +463,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/MD5.cpp \
JavaScriptCore/wtf/MD5.h \
JavaScriptCore/wtf/MessageQueue.h \
+ JavaScriptCore/wtf/NonCopyingSort.h \
JavaScriptCore/wtf/Noncopyable.h \
JavaScriptCore/wtf/NotFound.h \
JavaScriptCore/wtf/OwnArrayPtr.h \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 30f5aa8..ee0bfb7 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -129,8 +129,10 @@ __ZN3JSC12JSGlobalData13startSamplingEv
__ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
__ZN3JSC12JSGlobalData14resetDateCacheEv
__ZN3JSC12JSGlobalData14sharedInstanceEv
+__ZN3JSC12JSGlobalData15dumpRegExpTraceEv
__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE
__ZN3JSC12JSGlobalDataD1Ev
+__ZN3JSC12RegisterFile18committedByteCountEv
__ZN3JSC12SamplingTool5setupEv
__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
@@ -191,6 +193,7 @@ __ZN3JSC18PropertyDescriptor17defaultAttributesE
__ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j
__ZN3JSC18PropertyDescriptor9setGetterENS_7JSValueE
__ZN3JSC18PropertyDescriptor9setSetterENS_7JSValueE
+__ZN3JSC19ExecutableAllocator18committedByteCountEv
__ZN3JSC19initializeThreadingEv
__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
@@ -241,6 +244,7 @@ __ZN3JSC6JSLockC1EPNS_9ExecStateE
__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
__ZN3JSC7JSArray15setSubclassDataEPv
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3JSC7JSArray4infoE
__ZN3JSC7JSArray9setLengthEj
__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
@@ -480,6 +484,8 @@ __ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_10JSFunctionE
__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
+__ZN3JSC12RegExpObject4infoE
+__ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEN3WTF17NonNullPassRefPtrINS_9StructureEEENS4_INS_6RegExpEEE
__ZNK3JSC14JSGlobalObject14isDynamicScopeERb
__ZNK3JSC16InternalFunction9classInfoEv
__ZNK3JSC16JSVariableObject16isVariableObjectEv
@@ -510,6 +516,8 @@ __ZNK3JSC6JSCell9getStringEPNS_9ExecStateE
__ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
__ZNK3JSC6JSCell9getUInt32ERj
__ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZN3JSC6RegExpD1Ev
__ZNK3JSC7ArgList8getSliceEiRS0_
__ZNK3JSC7JSArray12subclassDataEv
__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index 12614d0..462960d 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -394,6 +394,7 @@
'wtf/MallocZoneSupport.h',
'wtf/MathExtras.h',
'wtf/MessageQueue.h',
+ 'wtf/NonCopyingSort.h',
'wtf/Noncopyable.h',
'wtf/NotFound.h',
'wtf/OwnArrayPtr.h',
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index cb9c820..7226326 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -17,10 +17,12 @@ EXPORTS
??0Mutex@WTF@@QAE@XZ
??0PrototypeFunction@JSC@@QAE@PAVExecState@1@PAVJSGlobalObject@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@HABVIdentifier@1@P6I_J0@Z@Z
??0RefCountedLeakCounter@WTF@@QAE@PBD@Z
+ ??0RegExpObject@JSC@@QAE@PAVJSGlobalObject@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@V?$NonNullPassRefPtr@VRegExp@JSC@@@4@@Z
??0StringObject@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVUString@1@@Z
??0Structure@JSC@@AAE@VJSValue@1@ABVTypeInfo@1@I@Z
??0ThreadCondition@WTF@@QAE@XZ
??0UString@JSC@@QAE@PBD@Z
+ ??0UString@JSC@@QAE@PBDI@Z
??0UString@JSC@@QAE@PB_WI@Z
??0WTFThreadData@WTF@@QAE@XZ
??1ClientData@JSGlobalData@JSC@@UAE@XZ
@@ -31,6 +33,7 @@ EXPORTS
??1JSGlobalObject@JSC@@UAE@XZ
??1Mutex@WTF@@QAE@XZ
??1RefCountedLeakCounter@WTF@@QAE@XZ
+ ??1RegExp@JSC@@QAE@XZ
??1Structure@JSC@@QAE@XZ
??1ThreadCondition@WTF@@QAE@XZ
??1WTFThreadData@WTF@@QAE@XZ
@@ -79,6 +82,7 @@ EXPORTS
?create@ByteArray@WTF@@SA?AV?$PassRefPtr@VByteArray@WTF@@@2@I@Z
?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4ThreadStackType@2@@Z
?create@OpaqueJSString@@SA?AV?$PassRefPtr@UOpaqueJSString@@@WTF@@ABVUString@JSC@@@Z
+ ?create@RegExp@JSC@@SA?AV?$PassRefPtr@VRegExp@JSC@@@WTF@@PAVJSGlobalData@2@ABVUString@2@1@Z
?createEmptyString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@@Z
?createError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVUString@1@@Z
?createInheritorID@JSObject@JSC@@AAEPAVStructure@2@XZ
@@ -162,6 +166,7 @@ EXPORTS
?getOwnPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
?getOwnPropertyNames@JSVariableObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
?getOwnPropertyNames@StringObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
+ ?getOwnPropertySlot@JSArray@JSC@@UAE_NPAVExecState@2@IAAVPropertySlot@2@@Z
?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertySlot@2@@Z
?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@IAAVPropertySlot@2@@Z
?getOwnPropertySlot@JSObject@JSC@@UAE_NPAVExecState@2@IAAVPropertySlot@2@@Z
@@ -188,6 +193,7 @@ EXPORTS
?hasTransition@Structure@JSC@@QAE_NPAVStringImpl@WTF@@I@Z
?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z
?increment@RefCountedLeakCounter@WTF@@QAEXXZ
+ ?info@RegExpObject@JSC@@2UClassInfo@2@B
?init@AtomicString@WTF@@SAXXZ
?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z
?initializeMainThread@WTF@@YAXXZ
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 7bb2e2a..42a91eb 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -405,6 +405,10 @@
>
</File>
<File
+ RelativePath="..\..\wtf\NonCopyingSort.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\Noncopyable.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index f9a547e..bee44b6 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -188,6 +188,7 @@
6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; };
65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DFC92D08EA173A00F7300B /* HashTable.cpp */; };
+ 65E1A3DF122B894500B26097 /* NonCopyingSort.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E1A2F4122B880D00B26097 /* NonCopyingSort.h */; settings = {ATTRIBUTES = (Private, ); }; };
65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B808E7EECC0023E5F6 /* Assertions.cpp */; settings = {COMPILER_FLAGS = "-Wno-missing-format-attribute"; }; };
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */; };
@@ -297,6 +298,15 @@
969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07940ED1D3AE00F1F681 /* Opcode.cpp */; };
969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
96DD73790F9DA3100027FBCC /* VMTags.h in Headers */ = {isa = PBXBuildFile; fileRef = 96DD73780F9DA3100027FBCC /* VMTags.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9714AF46122F28850092D9F5 /* URLSegments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9714AF35122F27E70092D9F5 /* URLSegments.cpp */; };
+ 9714AF4B122F289A0092D9F5 /* RawURLBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF31122F27E70092D9F5 /* RawURLBuffer.h */; };
+ 9714AF4C122F289A0092D9F5 /* URLBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF32122F27E70092D9F5 /* URLBuffer.h */; };
+ 9714AF4D122F289A0092D9F5 /* URLComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF33122F27E70092D9F5 /* URLComponent.h */; };
+ 9714AF4E122F289A0092D9F5 /* URLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF34122F27E70092D9F5 /* URLParser.h */; };
+ 9714AF4F122F289A0092D9F5 /* URLSegments.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF36122F27E70092D9F5 /* URLSegments.h */; };
+ 9714AF5E122F32070092D9F5 /* ParsedURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9714AF57122F31F50092D9F5 /* ParsedURL.cpp */; };
+ 9714AF5F122F32070092D9F5 /* ParsedURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF58122F31F50092D9F5 /* ParsedURL.h */; };
+ 9714AF60122F32070092D9F5 /* URLString.h in Headers */ = {isa = PBXBuildFile; fileRef = 9714AF59122F31F50092D9F5 /* URLString.h */; };
971EDEA61169E0D3005E4262 /* Terminator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97F6903A1169DF7F00A6BB46 /* Terminator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1712B3A11C7B212007A5315 /* RegExpCache.cpp */; };
A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B3E11C7B228007A5315 /* RegExpCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -766,6 +776,7 @@
65DFC92D08EA173A00F7300B /* HashTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashTable.cpp; sourceTree = "<group>"; tabWidth = 8; };
65DFC92E08EA173A00F7300B /* HashTable.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashTable.h; sourceTree = "<group>"; tabWidth = 8; };
65DFC92F08EA173A00F7300B /* HashTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashTraits.h; sourceTree = "<group>"; tabWidth = 8; };
+ 65E1A2F4122B880D00B26097 /* NonCopyingSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NonCopyingSort.h; sourceTree = "<group>"; };
65E217B708E7EECC0023E5F6 /* Assertions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Assertions.h; sourceTree = "<group>"; tabWidth = 8; };
65E217B808E7EECC0023E5F6 /* Assertions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Assertions.cpp; sourceTree = "<group>"; tabWidth = 8; };
65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastMalloc.cpp; sourceTree = "<group>"; tabWidth = 8; };
@@ -915,6 +926,15 @@
969A07950ED1D3AE00F1F681 /* Opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Opcode.h; sourceTree = "<group>"; };
969A09220ED1E09C00F1F681 /* Completion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Completion.cpp; sourceTree = "<group>"; };
96DD73780F9DA3100027FBCC /* VMTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMTags.h; sourceTree = "<group>"; };
+ 9714AF31122F27E70092D9F5 /* RawURLBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RawURLBuffer.h; path = url/src/RawURLBuffer.h; sourceTree = "<group>"; };
+ 9714AF32122F27E70092D9F5 /* URLBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLBuffer.h; path = url/src/URLBuffer.h; sourceTree = "<group>"; };
+ 9714AF33122F27E70092D9F5 /* URLComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLComponent.h; path = url/src/URLComponent.h; sourceTree = "<group>"; };
+ 9714AF34122F27E70092D9F5 /* URLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLParser.h; path = url/src/URLParser.h; sourceTree = "<group>"; };
+ 9714AF35122F27E70092D9F5 /* URLSegments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = URLSegments.cpp; path = url/src/URLSegments.cpp; sourceTree = "<group>"; };
+ 9714AF36122F27E70092D9F5 /* URLSegments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLSegments.h; path = url/src/URLSegments.h; sourceTree = "<group>"; };
+ 9714AF57122F31F50092D9F5 /* ParsedURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParsedURL.cpp; path = url/api/ParsedURL.cpp; sourceTree = "<group>"; };
+ 9714AF58122F31F50092D9F5 /* ParsedURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParsedURL.h; path = url/api/ParsedURL.h; sourceTree = "<group>"; };
+ 9714AF59122F31F50092D9F5 /* URLString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = URLString.h; path = url/api/URLString.h; sourceTree = "<group>"; };
97F6903A1169DF7F00A6BB46 /* Terminator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminator.h; sourceTree = "<group>"; };
A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
@@ -1426,6 +1446,7 @@
65162EF108E6A21C007556CD /* wtf */ = {
isa = PBXGroup;
children = (
+ 9714AF2F122F27C60092D9F5 /* url */,
06D358A00DAAD9C4003B174E /* mac */,
8656573E115BE35200291F40 /* text */,
E195678D09E7CF1200B89D13 /* unicode */,
@@ -1473,6 +1494,7 @@
511FC4C7117EE23D00425272 /* MD5.cpp */,
511FC4CA117EE2A800425272 /* MD5.h */,
E1EE798B0D6CA53D00FEA3BA /* MessageQueue.h */,
+ 65E1A2F4122B880D00B26097 /* NonCopyingSort.h */,
9303F5690991190000AD71B8 /* Noncopyable.h */,
C0A2723F0E509F1E00E96E15 /* NotFound.h */,
9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */,
@@ -1902,6 +1924,38 @@
path = bytecode;
sourceTree = "<group>";
};
+ 9714AF2F122F27C60092D9F5 /* url */ = {
+ isa = PBXGroup;
+ children = (
+ 9714AF56122F31DD0092D9F5 /* api */,
+ 9714AF30122F27D20092D9F5 /* src */,
+ );
+ name = url;
+ sourceTree = "<group>";
+ };
+ 9714AF30122F27D20092D9F5 /* src */ = {
+ isa = PBXGroup;
+ children = (
+ 9714AF31122F27E70092D9F5 /* RawURLBuffer.h */,
+ 9714AF32122F27E70092D9F5 /* URLBuffer.h */,
+ 9714AF33122F27E70092D9F5 /* URLComponent.h */,
+ 9714AF34122F27E70092D9F5 /* URLParser.h */,
+ 9714AF35122F27E70092D9F5 /* URLSegments.cpp */,
+ 9714AF36122F27E70092D9F5 /* URLSegments.h */,
+ );
+ name = src;
+ sourceTree = "<group>";
+ };
+ 9714AF56122F31DD0092D9F5 /* api */ = {
+ isa = PBXGroup;
+ children = (
+ 9714AF57122F31F50092D9F5 /* ParsedURL.cpp */,
+ 9714AF58122F31F50092D9F5 /* ParsedURL.h */,
+ 9714AF59122F31F50092D9F5 /* URLString.h */,
+ );
+ name = api;
+ sourceTree = "<group>";
+ };
E195678D09E7CF1200B89D13 /* unicode */ = {
isa = PBXGroup;
children = (
@@ -2115,6 +2169,7 @@
A76EE6590FAE59D5003F069A /* NativeFunctionWrapper.h in Headers */,
7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
+ 65E1A3DF122B894500B26097 /* NonCopyingSort.h in Headers */,
BC18C4400E16F5CD00B34460 /* Noncopyable.h in Headers */,
C0A272630E50A06300E96E15 /* NotFound.h in Headers */,
BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
@@ -2245,6 +2300,13 @@
862AF4B612239C7B0024E5B8 /* DecimalNumber.h in Headers */,
BCFBE696122560E800309E9D /* PassOwnArrayPtr.h in Headers */,
BCFBE698122561D200309E9D /* OwnArrayPtrCommon.h in Headers */,
+ 9714AF4B122F289A0092D9F5 /* RawURLBuffer.h in Headers */,
+ 9714AF4C122F289A0092D9F5 /* URLBuffer.h in Headers */,
+ 9714AF4D122F289A0092D9F5 /* URLComponent.h in Headers */,
+ 9714AF4E122F289A0092D9F5 /* URLParser.h in Headers */,
+ 9714AF4F122F289A0092D9F5 /* URLSegments.h in Headers */,
+ 9714AF5F122F32070092D9F5 /* ParsedURL.h in Headers */,
+ 9714AF60122F32070092D9F5 /* URLString.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2338,7 +2400,6 @@
isa = PBXProject;
buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
@@ -2697,6 +2758,8 @@
8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */,
DDE82AD71209D955005C1756 /* GCHandle.cpp in Sources */,
A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */,
+ 9714AF46122F28850092D9F5 /* URLSegments.cpp in Sources */,
+ 9714AF5E122F32070092D9F5 /* ParsedURL.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/assembler/MIPSAssembler.h b/JavaScriptCore/assembler/MIPSAssembler.h
index bc77f8d..f9e40c4 100644
--- a/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/JavaScriptCore/assembler/MIPSAssembler.h
@@ -529,6 +529,12 @@ public:
| (ft << OP_SH_FT));
}
+ void divd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+ {
+ emitInst(0x46200003 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+ | (ft << OP_SH_FT));
+ }
+
void lwc1(FPRegisterID ft, RegisterID rs, int offset)
{
emitInst(0xc4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
@@ -560,6 +566,12 @@ public:
copDelayNop();
}
+ void mthc1(RegisterID rt, FPRegisterID fs)
+ {
+ emitInst(0x44e00000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
+ copDelayNop();
+ }
+
void mfc1(RegisterID rt, FPRegisterID fs)
{
emitInst(0x44000000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
@@ -581,6 +593,11 @@ public:
emitInst(0x46800021 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
}
+ void cvtwd(FPRegisterID fd, FPRegisterID fs)
+ {
+ emitInst(0x46200024 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
+ }
+
void ceqd(FPRegisterID fs, FPRegisterID ft)
{
emitInst(0x46200032 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
diff --git a/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 3bb9e75..3fb2549 100644
--- a/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -281,6 +281,11 @@ public:
}
}
+ void neg32(RegisterID srcDest)
+ {
+ m_assembler.subu(srcDest, MIPSRegisters::zero, srcDest);
+ }
+
void not32(RegisterID srcDest)
{
m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero);
@@ -620,11 +625,6 @@ public:
return label;
}
- Label loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
- {
- return loadPtrWithPatchToLEA(address, dest);
- }
-
/* Need to use zero-extened load half-word for load16. */
void load16(ImplicitAddress address, RegisterID dest)
{
@@ -1302,6 +1302,27 @@ public:
return branchSub32(cond, immTempRegister, dest);
}
+ Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
+ if (cond == Signed) {
+ or32(src, dest);
+ // Check if dest is negative.
+ m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+ return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+ }
+ if (cond == Zero) {
+ or32(src, dest);
+ return branchEqual(dest, MIPSRegisters::zero);
+ }
+ if (cond == NonZero) {
+ or32(src, dest);
+ return branchNotEqual(dest, MIPSRegisters::zero);
+ }
+ ASSERT(0);
+ return Jump();
+ }
+
// Miscellaneous operations:
void breakpoint()
@@ -1351,6 +1372,17 @@ public:
m_assembler.nop();
}
+ void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+ {
+ set32(cond, left, right, dest);
+ }
+
+ void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ {
+ move(right, immTempRegister);
+ set32(cond, left, immTempRegister, dest);
+ }
+
void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
{
if (cond == Equal || cond == Zero) {
@@ -1546,6 +1578,28 @@ public:
#endif
}
+ void loadDouble(const void* address, FPRegisterID dest)
+ {
+#if WTF_MIPS_ISA(1)
+ /*
+ li addrTemp, address
+ lwc1 dest, 0(addrTemp)
+ lwc1 dest+1, 4(addrTemp)
+ */
+ move(ImmPtr(address), addrTempRegister);
+ m_assembler.lwc1(dest, addrTempRegister, 0);
+ m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, 4);
+#else
+ /*
+ li addrTemp, address
+ ldc1 dest, 0(addrTemp)
+ */
+ move(ImmPtr(address), addrTempRegister);
+ m_assembler.ldc1(dest, addrTempRegister, 0);
+#endif
+ }
+
+
void storeDouble(FPRegisterID src, ImplicitAddress address)
{
#if WTF_MIPS_ISA(1)
@@ -1609,12 +1663,31 @@ public:
m_assembler.muld(dest, dest, fpTempRegister);
}
+ void divDouble(FPRegisterID src, FPRegisterID dest)
+ {
+ m_assembler.divd(dest, dest, src);
+ }
+
void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
{
m_assembler.mtc1(src, fpTempRegister);
m_assembler.cvtdw(dest, fpTempRegister);
}
+ void convertInt32ToDouble(Address src, FPRegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ m_assembler.mtc1(dataTempRegister, fpTempRegister);
+ m_assembler.cvtdw(dest, fpTempRegister);
+ }
+
+ void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
+ {
+ load32(src.m_ptr, dataTempRegister);
+ m_assembler.mtc1(dataTempRegister, fpTempRegister);
+ m_assembler.cvtdw(dest, fpTempRegister);
+ }
+
void insertRelaxationWords()
{
/* We need four words for relaxation. */
@@ -1667,7 +1740,7 @@ public:
return branchTrue();
}
if (cond == DoubleNotEqual) {
- m_assembler.ceqd(left, right);
+ m_assembler.cueqd(left, right);
return branchFalse(); // false
}
if (cond == DoubleGreaterThan) {
@@ -1690,6 +1763,10 @@ public:
m_assembler.cueqd(left, right);
return branchTrue();
}
+ if (cond == DoubleNotEqualOrUnordered) {
+ m_assembler.ceqd(left, right);
+ return branchFalse(); // false
+ }
if (cond == DoubleGreaterThanOrUnordered) {
m_assembler.coled(left, right);
return branchFalse(); // false
@@ -1722,6 +1799,34 @@ public:
return branch32(Equal, dest, Imm32(0x7fffffff));
}
+ // Convert 'src' to an integer, and places the resulting 'dest'.
+ // If the result is not representable as a 32 bit value, branch.
+ // May also branch for some values that are representable in 32 bits
+ // (specifically, in this case, 0).
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ {
+ m_assembler.cvtwd(fpTempRegister, src);
+ m_assembler.mfc1(dest, fpTempRegister);
+
+ // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
+ failureCases.append(branch32(Equal, dest, MIPSRegisters::zero));
+
+ // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
+ convertInt32ToDouble(dest, fpTemp);
+ failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fpTemp, src));
+ }
+
+ void zeroDouble(FPRegisterID dest)
+ {
+#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
+ m_assembler.mtc1(MIPSRegisters::zero, dest);
+ m_assembler.mthc1(MIPSRegisters::zero, dest);
+#else
+ m_assembler.mtc1(MIPSRegisters::zero, dest);
+ m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(dest + 1));
+#endif
+ }
+
private:
// If m_fixedWidth is true, we will generate a fixed number of instructions.
// Otherwise, we can emit any number of instructions.
diff --git a/JavaScriptCore/interpreter/RegisterFile.cpp b/JavaScriptCore/interpreter/RegisterFile.cpp
index 4f5d1d5..4c37676 100644
--- a/JavaScriptCore/interpreter/RegisterFile.cpp
+++ b/JavaScriptCore/interpreter/RegisterFile.cpp
@@ -33,16 +33,26 @@
namespace JSC {
+static size_t committedBytesCount = 0;
+
+static Mutex& registerFileStatisticsMutex()
+{
+ DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
+ return staticMutex;
+}
+
RegisterFile::~RegisterFile()
{
void* base = m_reservation.base();
m_reservation.decommit(base, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(base));
+ addToCommittedByteCount(-(reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(base)));
m_reservation.deallocate();
}
void RegisterFile::releaseExcessCapacity()
{
m_reservation.decommit(m_start, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(m_start));
+ addToCommittedByteCount(-(reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(m_start)));
m_commitEnd = m_start;
m_maxUsed = m_start;
}
@@ -62,4 +72,22 @@ JSGlobalObject* RegisterFile::globalObject()
return m_globalObject.get();
}
+void RegisterFile::initializeThreading()
+{
+ registerFileStatisticsMutex();
+}
+
+size_t RegisterFile::committedByteCount()
+{
+ MutexLocker locker(registerFileStatisticsMutex());
+ return committedBytesCount;
+}
+
+void RegisterFile::addToCommittedByteCount(long byteCount)
+{
+ MutexLocker locker(registerFileStatisticsMutex());
+ ASSERT(static_cast<long>(committedBytesCount) + byteCount > -1);
+ committedBytesCount += byteCount;
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h
index f3284ff..d9f6a2b 100644
--- a/JavaScriptCore/interpreter/RegisterFile.h
+++ b/JavaScriptCore/interpreter/RegisterFile.h
@@ -134,10 +134,13 @@ namespace JSC {
void markGlobals(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, lastGlobal(), m_start); }
void markCallFrames(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, m_start, m_end); }
+ static size_t committedByteCount();
+ static void initializeThreading();
+
private:
void checkAllocatedOkay(bool okay);
-
void releaseExcessCapacity();
+ void addToCommittedByteCount(long);
size_t m_numGlobals;
const size_t m_maxGlobals;
Register* m_start;
@@ -166,6 +169,7 @@ namespace JSC {
checkAllocatedOkay(base);
size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize);
checkAllocatedOkay(m_reservation.commit(base, committedSize));
+ addToCommittedByteCount(static_cast<long>(committedSize));
m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(base) + committedSize);
m_start = static_cast<Register*>(base) + maxGlobals;
m_end = m_start;
@@ -193,6 +197,7 @@ namespace JSC {
if (newEnd > m_commitEnd) {
size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize);
checkAllocatedOkay(m_reservation.commit(m_commitEnd, size));
+ addToCommittedByteCount(static_cast<long>(size));
m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(m_commitEnd) + size);
}
diff --git a/JavaScriptCore/jit/ExecutableAllocator.cpp b/JavaScriptCore/jit/ExecutableAllocator.cpp
index 4800613..8742eda 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -66,6 +66,11 @@ bool ExecutableAllocator::isValid() const
{
return true;
}
+
+size_t ExecutableAllocator::committedByteCount()
+{
+ return 0;
+}
#endif
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index 576f889..f145404 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -297,6 +297,7 @@ public:
#else
#error "The cacheFlush support is missing on this platform."
#endif
+ static size_t committedByteCount();
private:
diff --git a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index b34204f..15247c2 100644
--- a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -54,6 +54,9 @@
using namespace WTF;
namespace JSC {
+
+static size_t committedBytesCount = 0;
+static SpinLock spinlock = SPINLOCK_INITIALIZER;
// FreeListEntry describes a free chunk of memory, stored in the freeList.
struct FreeListEntry {
@@ -128,12 +131,14 @@ class FixedVMPoolAllocator
void release(void* position, size_t size)
{
m_allocation.decommit(position, size);
+ addToCommittedByteCount(-static_cast<long>(size));
}
void reuse(void* position, size_t size)
{
bool okay = m_allocation.commit(position, size);
ASSERT_UNUSED(okay, okay);
+ addToCommittedByteCount(static_cast<long>(size));
}
// All addition to the free list should go through this method, rather than
@@ -415,6 +420,13 @@ private:
}
#endif
+ void addToCommittedByteCount(long byteCount)
+ {
+ ASSERT(spinlock.IsHeld());
+ ASSERT(static_cast<long>(committedBytesCount) + byteCount > -1);
+ committedBytesCount += byteCount;
+ }
+
// Freed space from the most common sized allocations will be held in this list, ...
const size_t m_commonSize;
Vector<void*> m_commonSizedAllocations;
@@ -428,14 +440,19 @@ private:
PageReservation m_allocation;
};
+size_t ExecutableAllocator::committedByteCount()
+{
+ SpinLockHolder lockHolder(&spinlock);
+ return committedBytesCount;
+}
+
void ExecutableAllocator::intializePageSize()
{
ExecutableAllocator::pageSize = getpagesize();
}
static FixedVMPoolAllocator* allocator = 0;
-static SpinLock spinlock = SPINLOCK_INITIALIZER;
-
+
bool ExecutableAllocator::isValid() const
{
SpinLockHolder lock_holder(&spinlock);
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 7c03a47..6f1168b 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -448,6 +448,52 @@ namespace JSC {
// sequencePutById
static const int sequencePutByIdInstructionSpace = 36;
static const int sequencePutByIdConstantSpace = 4;
+#elif CPU(MIPS)
+#if WTF_MIPS_ISA(1)
+ static const int patchOffsetPutByIdStructure = 16;
+ static const int patchOffsetPutByIdExternalLoad = 48;
+ static const int patchLengthPutByIdExternalLoad = 20;
+ static const int patchOffsetPutByIdPropertyMapOffset1 = 68;
+ static const int patchOffsetPutByIdPropertyMapOffset2 = 84;
+ static const int patchOffsetGetByIdStructure = 16;
+ static const int patchOffsetGetByIdBranchToSlowCase = 48;
+ static const int patchOffsetGetByIdExternalLoad = 48;
+ static const int patchLengthGetByIdExternalLoad = 20;
+ static const int patchOffsetGetByIdPropertyMapOffset1 = 68;
+ static const int patchOffsetGetByIdPropertyMapOffset2 = 88;
+ static const int patchOffsetGetByIdPutResult = 108;
+#if ENABLE(OPCODE_SAMPLING)
+ #error "OPCODE_SAMPLING is not yet supported"
+#else
+ static const int patchOffsetGetByIdSlowCaseCall = 44;
+#endif
+ static const int patchOffsetOpCallCompareToJump = 32;
+ static const int patchOffsetMethodCheckProtoObj = 32;
+ static const int patchOffsetMethodCheckProtoStruct = 56;
+ static const int patchOffsetMethodCheckPutFunction = 88;
+#else // WTF_MIPS_ISA(1)
+ static const int patchOffsetPutByIdStructure = 12;
+ static const int patchOffsetPutByIdExternalLoad = 44;
+ static const int patchLengthPutByIdExternalLoad = 16;
+ static const int patchOffsetPutByIdPropertyMapOffset1 = 60;
+ static const int patchOffsetPutByIdPropertyMapOffset2 = 76;
+ static const int patchOffsetGetByIdStructure = 12;
+ static const int patchOffsetGetByIdBranchToSlowCase = 44;
+ static const int patchOffsetGetByIdExternalLoad = 44;
+ static const int patchLengthGetByIdExternalLoad = 16;
+ static const int patchOffsetGetByIdPropertyMapOffset1 = 60;
+ static const int patchOffsetGetByIdPropertyMapOffset2 = 76;
+ static const int patchOffsetGetByIdPutResult = 92;
+#if ENABLE(OPCODE_SAMPLING)
+ #error "OPCODE_SAMPLING is not yet supported"
+#else
+ static const int patchOffsetGetByIdSlowCaseCall = 44;
+#endif
+ static const int patchOffsetOpCallCompareToJump = 32;
+ static const int patchOffsetMethodCheckProtoObj = 32;
+ static const int patchOffsetMethodCheckProtoStruct = 52;
+ static const int patchOffsetMethodCheckPutFunction = 84;
+#endif
#else
#error "JSVALUE32_64 not supported on this platform."
#endif
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 035325a..1ad19b7 100644
--- a/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -244,6 +244,37 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
restoreReturnAddressBeforeReturn(regT3);
+#elif CPU(MIPS)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
+ emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
+ emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+
+ preserveReturnAddressAfterCall(regT3); // Callee preserved
+ emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
+
+ // Calling convention: f(a0, a1, a2, a3);
+ // Host function signature: f(ExecState*);
+
+ // Allocate stack space for 16 bytes (8-byte aligned)
+ // 16 bytes (unused) for 4 arguments
+ subPtr(Imm32(16), stackPointerRegister);
+
+ // Setup arg0
+ move(callFrameRegister, MIPSRegisters::a0);
+
+ // Call
+ emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2);
+ loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+ move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ call(Address(regT2, executableOffsetToFunction));
+
+ // Restore stack space
+ addPtr(Imm32(16), stackPointerRegister);
+
+ restoreReturnAddressBeforeReturn(regT3);
+
#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
#else
@@ -327,6 +358,39 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
restoreReturnAddressBeforeReturn(regT3);
+#elif CPU(MIPS)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
+ emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
+ emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+
+ preserveReturnAddressAfterCall(regT3); // Callee preserved
+ emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
+
+ // Calling convention: f(a0, a1, a2, a3);
+ // Host function signature: f(ExecState*);
+
+ // Allocate stack space for 16 bytes (8-byte aligned)
+ // 16 bytes (unused) for 4 arguments
+ subPtr(Imm32(16), stackPointerRegister);
+
+ // Setup arg0
+ move(callFrameRegister, MIPSRegisters::a0);
+
+ // Call
+ emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2);
+ loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+ move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+
+ // call the function
+ nativeCall = call();
+
+ // Restore stack space
+ addPtr(Imm32(16), stackPointerRegister);
+
+ restoreReturnAddressBeforeReturn(regT3);
+
#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
#else
diff --git a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 31ecfed..f6280ef 100644
--- a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -640,8 +640,14 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)));
+#if CPU(MIPS)
+ // For MIPS, we don't add sizeof(void*) to the stack offset.
+ load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT3);
+ load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT2);
+#else
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + sizeof(void*) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT3);
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + sizeof(void*) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT2);
+#endif
// Write the value
compilePutDirectOffset(regT0, regT2, regT3, newStructure, cachedOffset);
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index e17c7cb..d5e55b4 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -80,8 +80,12 @@ namespace JSC {
#if OS(LINUX) && CPU(X86_64)
#define SYMBOL_STRING_RELOCATION(name) #name "@plt"
+#elif OS(DARWIN)
+#define SYMBOL_STRING_RELOCATION(name) "_" #name
+#elif CPU(X86) && COMPILER(MINGW)
+#define SYMBOL_STRING_RELOCATION(name) "@" #name "@4"
#else
-#define SYMBOL_STRING_RELOCATION(name) SYMBOL_STRING(name)
+#define SYMBOL_STRING_RELOCATION(name) #name
#endif
#if OS(DARWIN)
@@ -311,6 +315,21 @@ extern "C" {
#define PRESERVEDR4_OFFSET 68
// See DEFINE_STUB_FUNCTION for more information.
+#elif CPU(MIPS)
+
+#define PRESERVED_GP_OFFSET 60
+#define PRESERVED_S0_OFFSET 64
+#define PRESERVED_S1_OFFSET 68
+#define PRESERVED_S2_OFFSET 72
+#define PRESERVED_RETURN_ADDRESS_OFFSET 76
+#define THUNK_RETURN_ADDRESS_OFFSET 80
+#define REGISTER_FILE_OFFSET 84
+#define CALLFRAME_OFFSET 88
+#define EXCEPTION_OFFSET 92
+#define ENABLE_PROFILER_REFERENCE_OFFSET 96
+#define GLOBAL_DATA_OFFSET 100
+#define STACK_LENGTH 104
+
#else
#error "JIT not supported on this platform."
#endif
@@ -465,95 +484,18 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif CPU(MIPS)
-asm volatile(
-".text" "\n"
-".align 2" "\n"
-".set noreorder" "\n"
-".set nomacro" "\n"
-".set nomips16" "\n"
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-".ent " SYMBOL_STRING(ctiTrampoline) "\n"
-SYMBOL_STRING(ctiTrampoline) ":" "\n"
- "addiu $29,$29,-72" "\n"
- "sw $31,44($29)" "\n"
- "sw $18,40($29)" "\n"
- "sw $17,36($29)" "\n"
- "sw $16,32($29)" "\n"
-#if WTF_MIPS_PIC
- "sw $28,28($29)" "\n"
-#endif
- "move $16,$6 # set callFrameRegister" "\n"
- "li $17,512 # set timeoutCheckRegister" "\n"
- "move $25,$4 # move executableAddress to t9" "\n"
- "sw $5,52($29) # store registerFile to current stack" "\n"
- "sw $6,56($29) # store callFrame to curent stack" "\n"
- "sw $7,60($29) # store exception to current stack" "\n"
- "lw $8,88($29) # load enableProfilerReference from previous stack" "\n"
- "lw $9,92($29) # load globalData from previous stack" "\n"
- "sw $8,64($29) # store enableProfilerReference to current stack" "\n"
- "jalr $25" "\n"
- "sw $9,68($29) # store globalData to current stack" "\n"
- "lw $16,32($29)" "\n"
- "lw $17,36($29)" "\n"
- "lw $18,40($29)" "\n"
- "lw $31,44($29)" "\n"
- "jr $31" "\n"
- "addiu $29,$29,72" "\n"
-".set reorder" "\n"
-".set macro" "\n"
-".end " SYMBOL_STRING(ctiTrampoline) "\n"
-);
-
-asm volatile(
-".text" "\n"
-".align 2" "\n"
-".set noreorder" "\n"
-".set nomacro" "\n"
-".set nomips16" "\n"
-".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-".ent " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-#if WTF_MIPS_PIC
- "lw $28,28($29)" "\n"
-".set macro" "\n"
- "la $25," SYMBOL_STRING(cti_vm_throw) "\n"
-".set nomacro" "\n"
- "bal " SYMBOL_STRING(cti_vm_throw) "\n"
- "move $4,$29" "\n"
-#else
- "jal " SYMBOL_STRING(cti_vm_throw) "\n"
- "move $4,$29" "\n"
-#endif
- "lw $16,32($29)" "\n"
- "lw $17,36($29)" "\n"
- "lw $18,40($29)" "\n"
- "lw $31,44($29)" "\n"
- "jr $31" "\n"
- "addiu $29,$29,72" "\n"
-".set reorder" "\n"
-".set macro" "\n"
-".end " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-);
-
-asm volatile(
-".text" "\n"
-".align 2" "\n"
-".set noreorder" "\n"
-".set nomacro" "\n"
-".set nomips16" "\n"
-".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
-".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
-SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
- "lw $16,32($29)" "\n"
- "lw $17,36($29)" "\n"
- "lw $18,40($29)" "\n"
- "lw $31,44($29)" "\n"
- "jr $31" "\n"
- "addiu $29,$29,72" "\n"
-".set reorder" "\n"
-".set macro" "\n"
-".end " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
-);
+#define PRESERVED_GP_OFFSET 28
+#define PRESERVED_S0_OFFSET 32
+#define PRESERVED_S1_OFFSET 36
+#define PRESERVED_S2_OFFSET 40
+#define PRESERVED_RETURN_ADDRESS_OFFSET 44
+#define THUNK_RETURN_ADDRESS_OFFSET 48
+#define REGISTER_FILE_OFFSET 52
+#define CALLFRAME_OFFSET 56
+#define EXCEPTION_OFFSET 60
+#define ENABLE_PROFILER_REFERENCE_OFFSET 64
+#define GLOBAL_DATA_OFFSET 68
+#define STACK_LENGTH 72
#elif COMPILER(MSVC) && CPU(X86)
@@ -626,6 +568,98 @@ extern "C" {
#endif // USE(JSVALUE32_64)
+#if CPU(MIPS)
+asm volatile(
+".text" "\n"
+".align 2" "\n"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\n"
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+".ent " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+ "addiu $29,$29,-" STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
+ "sw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
+ "sw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
+ "sw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
+ "sw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
+#if WTF_MIPS_PIC
+ "sw $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n"
+#endif
+ "move $16,$6 # set callFrameRegister" "\n"
+ "li $17,512 # set timeoutCheckRegister" "\n"
+ "move $25,$4 # move executableAddress to t9" "\n"
+ "sw $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store registerFile to current stack" "\n"
+ "sw $6," STRINGIZE_VALUE_OF(CALLFRAME_OFFSET) "($29) # store callFrame to curent stack" "\n"
+ "sw $7," STRINGIZE_VALUE_OF(EXCEPTION_OFFSET) "($29) # store exception to current stack" "\n"
+ "lw $8," STRINGIZE_VALUE_OF(STACK_LENGTH + 16) "($29) # load enableProfilerReference from previous stack" "\n"
+ "lw $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29) # load globalData from previous stack" "\n"
+ "sw $8," STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "($29) # store enableProfilerReference to current stack" "\n"
+ "jalr $25" "\n"
+ "sw $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29) # store globalData to current stack" "\n"
+ "lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
+ "lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
+ "lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
+ "lw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
+ "jr $31" "\n"
+ "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
+".set reorder" "\n"
+".set macro" "\n"
+".end " SYMBOL_STRING(ctiTrampoline) "\n"
+);
+
+asm volatile(
+".text" "\n"
+".align 2" "\n"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\n"
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+".ent " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+#if WTF_MIPS_PIC
+ "lw $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n"
+".set macro" "\n"
+ "la $25," SYMBOL_STRING(cti_vm_throw) "\n"
+".set nomacro" "\n"
+ "bal " SYMBOL_STRING(cti_vm_throw) "\n"
+ "move $4,$29" "\n"
+#else
+ "jal " SYMBOL_STRING(cti_vm_throw) "\n"
+ "move $4,$29" "\n"
+#endif
+ "lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
+ "lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
+ "lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
+ "lw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
+ "jr $31" "\n"
+ "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
+".set reorder" "\n"
+".set macro" "\n"
+".end " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+);
+
+asm volatile(
+".text" "\n"
+".align 2" "\n"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\n"
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+ "lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
+ "lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
+ "lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
+ "lw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
+ "jr $31" "\n"
+ "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
+".set reorder" "\n"
+".set macro" "\n"
+".end " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+);
+#endif
+
#if COMPILER(GCC) && CPU(ARM_THUMB2)
asm volatile(
@@ -803,17 +837,17 @@ JITThunks::JITThunks(JSGlobalData* globalData)
#elif CPU(MIPS)
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedGP) == 28);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS0) == 32);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS1) == 36);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS2) == 40);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == 44);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == 48);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == 52);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == 56);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == 60);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 64);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == 68);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedGP) == PRESERVED_GP_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS0) == PRESERVED_S0_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS1) == PRESERVED_S1_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS2) == PRESERVED_S2_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == EXCEPTION_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == GLOBAL_DATA_OFFSET);
#endif
}
@@ -1086,14 +1120,14 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
".globl " SYMBOL_STRING(cti_##op) "\n" \
".ent " SYMBOL_STRING(cti_##op) "\n" \
SYMBOL_STRING(cti_##op) ":" "\n" \
- "lw $28,28($29)" "\n" \
- "sw $31,48($29)" "\n" \
+ "lw $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n" \
+ "sw $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
".set macro" "\n" \
"la $25," SYMBOL_STRING(JITStubThunked_##op) "\n" \
".set nomacro" "\n" \
"bal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
"nop" "\n" \
- "lw $31,48($29)" "\n" \
+ "lw $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
"jr $31" "\n" \
"nop" "\n" \
".set reorder" "\n" \
@@ -1116,10 +1150,10 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
".globl " SYMBOL_STRING(cti_##op) "\n" \
".ent " SYMBOL_STRING(cti_##op) "\n" \
SYMBOL_STRING(cti_##op) ":" "\n" \
- "sw $31,48($29)" "\n" \
+ "sw $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
"jal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
"nop" "\n" \
- "lw $31,48($29)" "\n" \
+ "lw $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
"jr $31" "\n" \
"nop" "\n" \
".set reorder" "\n" \
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index 4e73070..d3d7c53 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -204,9 +204,13 @@ namespace JSC {
#endif // COMPILER(MSVC)
#elif CPU(MIPS)
struct JITStackFrame {
- void* reserved; // Unused
+ JITStubArg reserved; // Unused
JITStubArg args[6];
+#if USE(JSVALUE32_64)
+ void* padding; // Make the overall stack length 8-byte aligned.
+#endif
+
void* preservedGP; // store GP when using PIC code
void* preservedS0;
void* preservedS1;
@@ -235,12 +239,16 @@ namespace JSC {
#define STUB_ARGS_DECLARATION void** args
#define STUB_ARGS (args)
-#if CPU(X86) && COMPILER(MSVC)
-#define JIT_STUB __fastcall
-#elif CPU(X86) && COMPILER(GCC) && !OS(WINDOWS)
-#define JIT_STUB __attribute__ ((fastcall))
+#if CPU(X86)
+ #if COMPILER(MSVC)
+ #define JIT_STUB __fastcall
+ #elif COMPILER(GCC)
+ #define JIT_STUB __attribute__ ((fastcall))
+ #else
+ #error "JIT_STUB function calls require fastcall conventions on x86, add appropriate directive/attribute here for your compiler!"
+ #endif
#else
-#define JIT_STUB
+ #define JIT_STUB
#endif
extern "C" void ctiVMThrowTrampoline();
diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp
index 8b535a9..d756a0c 100644
--- a/JavaScriptCore/jsc.cpp
+++ b/JavaScriptCore/jsc.cpp
@@ -408,6 +408,9 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
#if ENABLE(SAMPLING_COUNTERS)
AbstractSamplingCounter::dump();
#endif
+#if ENABLE(REGEXP_TRACING)
+ globalData->dumpRegExpTrace();
+#endif
return success;
}
diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp
index 6852de1..820811e 100644
--- a/JavaScriptCore/parser/JSParser.cpp
+++ b/JavaScriptCore/parser/JSParser.cpp
@@ -85,11 +85,10 @@ private:
bool m_oldAllowsIn;
};
- const JSToken& token() { return m_token; }
void next(Lexer::LexType lexType = Lexer::IdentifyReservedWords)
{
- m_lastLine = token().m_info.line;
- m_lastTokenEnd = token().m_info.endOffset;
+ m_lastLine = m_token.m_info.line;
+ m_lastTokenEnd = m_token.m_info.endOffset;
m_lexer->setLastLineNumber(m_lastLine);
m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType);
m_tokenCount++;
@@ -110,17 +109,17 @@ private:
int tokenStart()
{
- return token().m_info.startOffset;
+ return m_token.m_info.startOffset;
}
int tokenLine()
{
- return token().m_info.line;
+ return m_token.m_info.line;
}
int tokenEnd()
{
- return token().m_info.endOffset;
+ return m_token.m_info.endOffset;
}
template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
@@ -168,7 +167,7 @@ private:
bool autoSemiColon()
{
- if (token().m_type == SEMICOLON) {
+ if (m_token.m_type == SEMICOLON) {
next();
return true;
}
@@ -324,7 +323,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(Tr
int varStart = tokenStart();
identStart = varStart;
- const Identifier* name = token().m_data.ident;
+ const Identifier* name = m_token.m_data.ident;
lastIdent = name;
next();
bool hasInitializer = match(EQUAL);
@@ -356,7 +355,7 @@ template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationLi
do {
next();
matchOrFail(IDENT);
- const Identifier* name = token().m_data.ident;
+ const Identifier* name = m_token.m_data.ident;
next();
bool hasInitializer = match(EQUAL);
context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
@@ -482,7 +481,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseBreakStatement(TreeBui
if (autoSemiColon())
return context.createBreakStatement(startCol, endCol, startLine, endLine);
matchOrFail(IDENT);
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
endCol = tokenEnd();
endLine = tokenLine();
next();
@@ -502,7 +501,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseContinueStatement(Tree
if (autoSemiColon())
return context.createContinueStatement(startCol, endCol, startLine, endLine);
matchOrFail(IDENT);
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
endCol = tokenEnd();
endLine = tokenLine();
next();
@@ -654,7 +653,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuild
next();
consumeOrFail(OPENPAREN);
matchOrFail(IDENT);
- ident = token().m_data.ident;
+ ident = m_token.m_data.ident;
next();
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
@@ -705,7 +704,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseBlockStatement(TreeBui
template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context)
{
failIfStackOverflow();
- switch (token().m_type) {
+ switch (m_token.m_type) {
case OPENBRACE:
return parseBlockStatement(context);
case VAR:
@@ -757,14 +756,14 @@ template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder&
template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParameters(TreeBuilder& context, bool& usesArguments)
{
matchOrFail(IDENT);
- usesArguments = m_globalData->propertyNames->arguments == *token().m_data.ident;
- TreeFormalParameterList list = context.createFormalParameterList(*token().m_data.ident);
+ usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident;
+ TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
TreeFormalParameterList tail = list;
next();
while (match(COMMA)) {
next();
matchOrFail(IDENT);
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
next();
usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident;
tail = context.createFormalParameterList(tail, *ident);
@@ -784,7 +783,7 @@ template <class TreeBuilder> TreeFunctionBody JSParser::parseFunctionBody(TreeBu
template <JSParser::FunctionRequirements requirements, class TreeBuilder> bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
{
if (match(IDENT)) {
- name = token().m_data.ident;
+ name = m_token.m_data.ident;
next();
} else if (requirements == FunctionNeedsName)
return false;
@@ -797,7 +796,7 @@ template <JSParser::FunctionRequirements requirements, class TreeBuilder> bool J
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
- openBracePos = token().m_data.intValue;
+ openBracePos = m_token.m_data.intValue;
bodyStartLine = tokenLine();
next();
@@ -807,7 +806,7 @@ template <JSParser::FunctionRequirements requirements, class TreeBuilder> bool J
context.setUsesArguments(body);
matchOrFail(CLOSEBRACE);
- closeBracePos = token().m_data.intValue;
+ closeBracePos = m_token.m_data.intValue;
next();
return true;
}
@@ -837,7 +836,7 @@ template <class TreeBuilder> TreeStatement JSParser::parseExpressionOrLabelState
*/
int start = tokenStart();
int startLine = tokenLine();
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
int currentToken = m_tokenCount;
TreeExpression expression = parseExpression(context);
failIfFalse(expression);
@@ -972,7 +971,7 @@ template <typename TreeBuilder> TreeExpression JSParser::parseAssignmentExpressi
Operator op;
bool hadAssignment = false;
while (true) {
- switch (token().m_type) {
+ switch (m_token.m_type) {
case EQUAL: op = OpEqual; break;
case PLUSEQUAL: op = OpPlusEq; break;
case MINUSEQUAL: op = OpMinusEq; break;
@@ -1051,11 +1050,11 @@ template <class TreeBuilder> TreeExpression JSParser::parseBinaryExpression(Tree
failIfFalse(current);
context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), initialAssignments != m_assignmentCount);
- int precedence = isBinaryOperator(token().m_type);
+ int precedence = isBinaryOperator(m_token.m_type);
if (!precedence)
break;
m_nonLHSCount++;
- int operatorToken = token().m_type;
+ int operatorToken = m_token.m_type;
next();
while (operatorStackDepth && context.operatorStackHasHigherPrecedence(operatorStackDepth, precedence)) {
@@ -1086,12 +1085,12 @@ template <class TreeBuilder> TreeExpression JSParser::parseBinaryExpression(Tree
template <bool complete, class TreeBuilder> TreeProperty JSParser::parseProperty(TreeBuilder& context)
{
bool wasIdent = false;
- switch (token().m_type) {
+ switch (m_token.m_type) {
namedProperty:
case IDENT:
wasIdent = true;
case STRING: {
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
next(Lexer::IgnoreReservedWords);
if (match(COLON)) {
next();
@@ -1118,7 +1117,7 @@ template <bool complete, class TreeBuilder> TreeProperty JSParser::parseProperty
return context.template createGetterOrSetterProperty<complete>(type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
case NUMBER: {
- double propertyName = token().m_data.doubleValue;
+ double propertyName = m_token.m_data.doubleValue;
next();
consumeOrFail(COLON);
TreeExpression node = parseAssignmentExpression(context);
@@ -1126,14 +1125,14 @@ template <bool complete, class TreeBuilder> TreeProperty JSParser::parseProperty
return context.template createProperty<complete>(m_globalData, propertyName, node, PropertyNode::Constant);
}
default:
- failIfFalse(token().m_type & KeywordTokenFlag);
+ failIfFalse(m_token.m_type & KeywordTokenFlag);
goto namedProperty;
}
}
template <class TreeBuilder> TreeExpression JSParser::parseObjectLiteral(TreeBuilder& context)
{
- int startOffset = token().m_data.intValue;
+ int startOffset = m_token.m_data.intValue;
consumeOrFail(OPENBRACE);
if (match(CLOSEBRACE)) {
@@ -1260,7 +1259,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseArrayLiteral(TreeBuil
template <class TreeBuilder> TreeExpression JSParser::parsePrimaryExpression(TreeBuilder& context)
{
- switch (token().m_type) {
+ switch (m_token.m_type) {
case OPENBRACE:
return parseObjectLiteral(context);
case OPENBRACKET:
@@ -1280,17 +1279,17 @@ template <class TreeBuilder> TreeExpression JSParser::parsePrimaryExpression(Tre
}
case IDENT: {
int start = tokenStart();
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
next();
return context.createResolve(ident, start);
}
case STRING: {
- const Identifier* ident = token().m_data.ident;
+ const Identifier* ident = m_token.m_data.ident;
next();
return context.createString(ident);
}
case NUMBER: {
- double d = token().m_data.doubleValue;
+ double d = m_token.m_data.doubleValue;
next();
return context.createNumberExpr(d);
}
@@ -1372,7 +1371,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
failIfFalse(base);
while (true) {
- switch (token().m_type) {
+ switch (m_token.m_type) {
case OPENBRACKET: {
int expressionEnd = lastTokenEnd();
next();
@@ -1410,7 +1409,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(Tree
int expressionEnd = lastTokenEnd();
next(Lexer::IgnoreReservedWords);
matchOrFail(IDENT);
- base = context.createDotAccess(base, *token().m_data.ident, expressionStart, expressionEnd, tokenEnd());
+ base = context.createDotAccess(base, *m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
next();
break;
}
@@ -1428,15 +1427,15 @@ template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeB
{
AllowInOverride allowInOverride(this);
int tokenStackDepth = 0;
- while (isUnaryOp(token().m_type)) {
+ while (isUnaryOp(m_token.m_type)) {
m_nonLHSCount++;
- context.appendUnaryToken(tokenStackDepth, token().m_type, tokenStart());
+ context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart());
next();
}
int subExprStart = tokenStart();
TreeExpression expr = parseMemberExpression(context);
failIfFalse(expr);
- switch (token().m_type) {
+ switch (m_token.m_type) {
case PLUSPLUS:
m_nonLHSCount++;
expr = context.makePostfixNode(expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp
index 6c4db32..cc4321d 100644
--- a/JavaScriptCore/parser/Lexer.cpp
+++ b/JavaScriptCore/parser/Lexer.cpp
@@ -675,6 +675,27 @@ ALWAYS_INLINE bool Lexer::parseNumberAfterExponentIndicator()
return true;
}
+ALWAYS_INLINE bool Lexer::parseMultilineComment()
+{
+ while (true) {
+ while (UNLIKELY(m_current == '*')) {
+ shift();
+ if (m_current == '/') {
+ shift();
+ return true;
+ }
+ }
+
+ if (UNLIKELY(m_current == -1))
+ return false;
+
+ if (isLineTerminator(m_current))
+ shiftLineTerminator();
+ else
+ shift();
+ }
+}
+
JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType)
{
ASSERT(!m_error);
@@ -835,7 +856,9 @@ start:
}
if (m_current == '*') {
shift();
- goto inMultiLineComment;
+ if (parseMultilineComment())
+ goto start;
+ goto returnError;
}
if (m_current == '=') {
shift();
@@ -1002,7 +1025,8 @@ inNumberAfterDecimalPoint:
m_terminator = true;
if (lastTokenWasRestrKeyword()) {
token = SEMICOLON;
- goto doneSemicolon;
+ m_delimited = true;
+ goto returnToken;
}
goto start;
case CharacterInvalid:
@@ -1024,44 +1048,19 @@ inSingleLineComment:
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
- if (lastTokenWasRestrKeyword())
- goto doneSemicolon;
- goto start;
-
-inMultiLineComment:
- while (true) {
- if (UNLIKELY(m_current == '*')) {
- shift();
- if (m_current == '/')
- break;
- if (m_current == '*')
- continue;
- }
-
- if (UNLIKELY(m_current == -1))
- goto returnError;
-
- if (isLineTerminator(m_current))
- shiftLineTerminator();
- else
- shift();
- }
- shift();
- goto start;
+ if (!lastTokenWasRestrKeyword())
+ goto start;
-doneSemicolon:
token = SEMICOLON;
m_delimited = true;
// Fall through into returnToken.
-returnToken: {
- int lineNumber = m_lineNumber;
- llocp->line = lineNumber;
+returnToken:
+ llocp->line = m_lineNumber;
llocp->startOffset = startOffset;
llocp->endOffset = currentOffset();
m_lastToken = token;
return token;
-}
returnError:
m_error = true;
diff --git a/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h
index da84a6b..e6c1efd 100644
--- a/JavaScriptCore/parser/Lexer.h
+++ b/JavaScriptCore/parser/Lexer.h
@@ -101,6 +101,7 @@ namespace JSC {
ALWAYS_INLINE bool parseDecimal(double& returnValue);
ALWAYS_INLINE void parseNumberAfterDecimalPoint();
ALWAYS_INLINE bool parseNumberAfterExponentIndicator();
+ ALWAYS_INLINE bool parseMultilineComment();
static const size_t initialReadBufferCapacity = 32;
diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp
index 33e8e68..08dddc1 100644
--- a/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -58,6 +58,7 @@ static void initializeThreadingOnce()
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
initializeDates();
+ RegisterFile::initializeThreading();
#endif
}
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 97f9be5..5eaa59b 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -51,6 +51,10 @@
#include "Parser.h"
#include "RegExpCache.h"
#include <wtf/WTFThreadData.h>
+#if ENABLE(REGEXP_TRACING)
+#include "RegExp.h"
+#endif
+
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <wtf/Threading.h>
@@ -145,6 +149,9 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, cachedUTCOffset(NaN)
, maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
, m_regExpCache(new RegExpCache(this))
+#if ENABLE(REGEXP_TRACING)
+ , m_rtTraceList(new RTTraceList())
+#endif
#ifndef NDEBUG
, exclusiveThread(0)
#endif
@@ -218,6 +225,9 @@ JSGlobalData::~JSGlobalData()
delete clientData;
delete m_regExpCache;
+#if ENABLE(REGEXP_TRACING)
+ delete m_rtTraceList;
+#endif
}
PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type)
@@ -301,4 +311,38 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
interpreter->dumpSampleData(exec);
}
+
+#if ENABLE(REGEXP_TRACING)
+void JSGlobalData::addRegExpToTrace(PassRefPtr<RegExp> regExp)
+{
+ m_rtTraceList->add(regExp);
+}
+
+void JSGlobalData::dumpRegExpTrace()
+{
+ // The first RegExp object is ignored. It is create by the RegExpPrototype ctor and not used.
+ RTTraceList::iterator iter = ++m_rtTraceList->begin();
+
+ if (iter != m_rtTraceList->end()) {
+ printf("\nRegExp Tracing\n");
+ printf(" match() matches\n");
+ printf("Regular Expression JIT Address calls found\n");
+ printf("----------------------------------------+----------------+----------+----------\n");
+
+ unsigned reCount = 0;
+
+ for (; iter != m_rtTraceList->end(); ++iter, ++reCount)
+ (*iter)->printTraceData();
+
+ printf("%d Regular Expressions\n", reCount);
+ }
+
+ m_rtTraceList->clear();
+}
+#else
+void JSGlobalData::dumpRegExpTrace()
+{
+}
+#endif
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 43c4bab..8e2ed61 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -46,6 +46,9 @@
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/ThreadSpecific.h>
+#if ENABLE(REGEXP_TRACING)
+#include <wtf/ListHashSet.h>
+#endif
struct OpaqueJSClass;
struct OpaqueJSClassContextData;
@@ -64,6 +67,9 @@ namespace JSC {
class Stringifier;
class Structure;
class UString;
+#if ENABLE(REGEXP_TRACING)
+ class RegExp;
+#endif
struct HashTable;
struct Instruction;
@@ -222,6 +228,11 @@ namespace JSC {
BumpPointerAllocator m_regexAllocator;
#endif
+#if ENABLE(REGEXP_TRACING)
+ typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
+ RTTraceList* m_rtTraceList;
+#endif
+
#ifndef NDEBUG
ThreadIdentifier exclusiveThread;
#endif
@@ -234,6 +245,10 @@ namespace JSC {
void stopSampling();
void dumpSampleData(ExecState* exec);
RegExpCache* regExpCache() { return m_regExpCache; }
+#if ENABLE(REGEXP_TRACING)
+ void addRegExpToTrace(PassRefPtr<RegExp> regExp);
+#endif
+ void dumpRegExpTrace();
private:
JSGlobalData(GlobalDataType, ThreadStackType);
static JSGlobalData*& sharedInstanceInternal();
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index 5ad9f3f..d4545cb 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -46,11 +46,33 @@
namespace JSC {
+struct RegExpRepresentation {
+#if ENABLE(YARR_JIT)
+ Yarr::RegexCodeBlock m_regExpJITCode;
+#elif ENABLE(YARR)
+ OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
+#else
+ JSRegExp* m_regExp;
+#endif
+
+#if !ENABLE(YARR)
+ ~RegExpRepresentation()
+ {
+ jsRegExpFree(m_regExp);
+ }
+#endif
+};
+
inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
: m_pattern(pattern)
, m_flagBits(0)
, m_constructionError(0)
, m_numSubpatterns(0)
+#if ENABLE(REGEXP_TRACING)
+ , m_rtMatchCallCount(0)
+ , m_rtMatchFoundCount(0)
+#endif
+ , m_representation(adoptPtr(new RegExpRepresentation))
{
// NOTE: The global flag is handled on a case-by-case basis by functions like
// String::match and RegExpObject::match.
@@ -65,16 +87,17 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
compile(globalData);
}
-#if !ENABLE(YARR)
RegExp::~RegExp()
{
- jsRegExpFree(m_regExp);
}
-#endif
PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
{
- return adoptRef(new RegExp(globalData, pattern, flags));
+ RefPtr<RegExp> res = adoptRef(new RegExp(globalData, pattern, flags));
+#if ENABLE(REGEXP_TRACING)
+ globalData->addRegExpToTrace(res);
+#endif
+ return res.release();
}
#if ENABLE(YARR)
@@ -82,9 +105,9 @@ PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patte
void RegExp::compile(JSGlobalData* globalData)
{
#if ENABLE(YARR_JIT)
- Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
+ Yarr::jitCompileRegex(globalData, m_representation->m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
#else
- m_regExpBytecode = Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, &globalData->m_regexAllocator, ignoreCase(), multiline());
+ m_representation->m_regExpBytecode = Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, &globalData->m_regexAllocator, ignoreCase(), multiline());
#endif
}
@@ -94,14 +117,18 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
startOffset = 0;
if (ovector)
ovector->resize(0);
+
+#if ENABLE(REGEXP_TRACING)
+ m_rtMatchCallCount++;
+#endif
if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
return -1;
#if ENABLE(YARR_JIT)
- if (!!m_regExpJITCode) {
+ if (!!m_representation->m_regExpJITCode) {
#else
- if (m_regExpBytecode) {
+ if (m_representation->m_regExpBytecode) {
#endif
int offsetVectorSize = (m_numSubpatterns + 1) * 3; // FIXME: should be 2 - but adding temporary fallback to pcre.
int* offsetVector;
@@ -119,9 +146,9 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
offsetVector[j] = -1;
#if ENABLE(YARR_JIT)
- int result = Yarr::executeRegex(m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector, offsetVectorSize);
+ int result = Yarr::executeRegex(m_representation->m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector, offsetVectorSize);
#else
- int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector);
+ int result = Yarr::interpretRegex(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector);
#endif
if (result < 0) {
@@ -134,6 +161,11 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
ovector->clear();
}
+#if ENABLE(REGEXP_TRACING)
+ if (result != -1)
+ m_rtMatchFoundCount++;
+#endif
+
return result;
}
@@ -144,14 +176,18 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
void RegExp::compile(JSGlobalData*)
{
- m_regExp = 0;
+ m_representation->m_regExp = 0;
JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
JSRegExpMultilineOption multilineOption = multiline() ? JSRegExpMultiline : JSRegExpSingleLine;
- m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.characters()), m_pattern.length(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
+ m_representation->m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.characters()), m_pattern.length(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
}
int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
{
+#if ENABLE(REGEXP_TRACING)
+ m_rtMatchCallCount++;
+#endif
+
if (startOffset < 0)
startOffset = 0;
if (ovector)
@@ -160,7 +196,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
return -1;
- if (m_regExp) {
+ if (m_representation->m_regExp) {
// Set up the offset vector for the result.
// First 2/3 used for result, the last third used by PCRE.
int* offsetVector;
@@ -175,7 +211,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
offsetVector = ovector->data();
}
- int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.characters()), s.length(), startOffset, offsetVector, offsetVectorSize);
+ int numMatches = jsRegExpExecute(m_representation->m_regExp, reinterpret_cast<const UChar*>(s.characters()), s.length(), startOffset, offsetVector, offsetVectorSize);
if (numMatches < 0) {
#ifndef NDEBUG
@@ -187,12 +223,45 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
return -1;
}
+#if ENABLE(REGEXP_TRACING)
+ m_rtMatchFoundCount++;
+#endif
+
return offsetVector[0];
}
return -1;
}
-
+
#endif
+#if ENABLE(REGEXP_TRACING)
+ void RegExp::printTraceData()
+ {
+ char formattedPattern[41];
+ char rawPattern[41];
+
+ strncpy(rawPattern, m_pattern.utf8().data(), 40);
+ rawPattern[40]= '\0';
+
+ int pattLen = strlen(rawPattern);
+
+ snprintf(formattedPattern, 41, (pattLen <= 38) ? "/%.38s/" : "/%.36s...", rawPattern);
+
+#if ENABLE(YARR_JIT)
+ Yarr::RegexCodeBlock& codeBlock = m_representation->m_regExpJITCode;
+
+ char jitAddr[20];
+ if (codeBlock.getFallback())
+ sprintf(jitAddr, "fallback");
+ else
+ sprintf(jitAddr, "0x%014lx", (uintptr_t)codeBlock.getAddr());
+#else
+ const char* jitAddr = "JIT Off";
+#endif
+
+ printf("%-40.40s %16.16s %10d %10d\n", formattedPattern, jitAddr, m_rtMatchCallCount, m_rtMatchFoundCount);
+ }
+#endif
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h
index aadad6b..e6e2fbc 100644
--- a/JavaScriptCore/runtime/RegExp.h
+++ b/JavaScriptCore/runtime/RegExp.h
@@ -26,21 +26,16 @@
#include "ExecutableAllocator.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
-#include "yarr/RegexJIT.h"
-#include "yarr/RegexInterpreter.h"
-
-struct JSRegExp;
namespace JSC {
+ struct RegExpRepresentation;
class JSGlobalData;
class RegExp : public RefCounted<RegExp> {
public:
static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
-#if !ENABLE(YARR)
~RegExp();
-#endif
bool global() const { return m_flagBits & Global; }
bool ignoreCase() const { return m_flagBits & IgnoreCase; }
@@ -53,6 +48,10 @@ namespace JSC {
int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
unsigned numSubpatterns() const { return m_numSubpatterns; }
+
+#if ENABLE(REGEXP_TRACING)
+ void printTraceData();
+#endif
private:
RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
@@ -65,14 +64,12 @@ namespace JSC {
int m_flagBits;
const char* m_constructionError;
unsigned m_numSubpatterns;
-
-#if ENABLE(YARR_JIT)
- Yarr::RegexCodeBlock m_regExpJITCode;
-#elif ENABLE(YARR)
- OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
-#else
- JSRegExp* m_regExp;
+#if ENABLE(REGEXP_TRACING)
+ unsigned m_rtMatchCallCount;
+ unsigned m_rtMatchFoundCount;
#endif
+
+ OwnPtr<RegExpRepresentation> m_representation;
};
} // namespace JSC
diff --git a/JavaScriptCore/wtf/ByteArray.h b/JavaScriptCore/wtf/ByteArray.h
index f5f5ded..f4d34a4 100644
--- a/JavaScriptCore/wtf/ByteArray.h
+++ b/JavaScriptCore/wtf/ByteArray.h
@@ -26,7 +26,9 @@
#ifndef ByteArray_h
#define ByteArray_h
+#include <limits.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/Platform.h>
#include <wtf/RefCounted.h>
namespace WTF {
@@ -86,7 +88,14 @@ namespace WTF {
{
}
size_t m_size;
- unsigned char m_data[sizeof(size_t)];
+// MSVC can't handle correctly unsized array.
+// warning C4200: nonstandard extension used : zero-sized array in struct/union
+// Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
+#if COMPILER(MSVC)
+ unsigned char m_data[INT_MAX];
+#else
+ unsigned char m_data[];
+#endif
};
}
diff --git a/JavaScriptCore/wtf/CMakeListsEfl.txt b/JavaScriptCore/wtf/CMakeListsEfl.txt
index 3cd3c8e..6a714ae 100644
--- a/JavaScriptCore/wtf/CMakeListsEfl.txt
+++ b/JavaScriptCore/wtf/CMakeListsEfl.txt
@@ -14,6 +14,10 @@ IF (ENABLE_GLIB_SUPPORT)
gobject/GOwnPtr.cpp
gobject/GRefPtr.cpp
)
+
+ LIST(APPEND WTF_INCLUDE_DIRECTORIES
+ ${JAVASCRIPTCORE_DIR}/wtf/gobject
+ )
ENDIF ()
LIST(APPEND WTF_LIBRARIES
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index ee6b02c..0f240ff 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -1492,11 +1492,23 @@ void TCMalloc_PageHeap::init()
void TCMalloc_PageHeap::initializeScavenger()
{
- pthread_mutex_init(&m_scavengeMutex, 0);
- pthread_cond_init(&m_scavengeCondition, 0);
- m_scavengeThreadActive = true;
- pthread_t thread;
- pthread_create(&thread, 0, runScavengerThread, this);
+ // Create a non-recursive mutex.
+#if !defined(PTHREAD_MUTEX_NORMAL) || PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_DEFAULT
+ pthread_mutex_init(&m_scavengeMutex, 0);
+#else
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
+
+ pthread_mutex_init(&m_scavengeMutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+#endif
+
+ pthread_cond_init(&m_scavengeCondition, 0);
+ m_scavengeThreadActive = true;
+ pthread_t thread;
+ pthread_create(&thread, 0, runScavengerThread, this);
}
void* TCMalloc_PageHeap::runScavengerThread(void* context)
@@ -1510,8 +1522,10 @@ void* TCMalloc_PageHeap::runScavengerThread(void* context)
ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
{
- if (!m_scavengeThreadActive && shouldScavenge())
- pthread_cond_signal(&m_scavengeCondition);
+ // m_scavengeMutex should be held before accessing m_scavengeThreadActive.
+ ASSERT(pthread_mutex_trylock(m_scavengeMutex));
+ if (!m_scavengeThreadActive && shouldScavenge())
+ pthread_cond_signal(&m_scavengeCondition);
}
#else // !HAVE(DISPATCH_H)
@@ -1528,10 +1542,11 @@ void TCMalloc_PageHeap::initializeScavenger()
ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
{
- if (!m_scavengingScheduled && shouldScavenge()) {
- m_scavengingScheduled = true;
- dispatch_resume(m_scavengeTimer);
- }
+ ASSERT(IsHeld(pageheap_lock));
+ if (!m_scavengingScheduled && shouldScavenge()) {
+ m_scavengingScheduled = true;
+ dispatch_resume(m_scavengeTimer);
+ }
}
#endif
@@ -2397,15 +2412,13 @@ void TCMalloc_PageHeap::scavengerThread()
void TCMalloc_PageHeap::periodicScavenge()
{
- {
SpinLockHolder h(&pageheap_lock);
pageheap->scavenge();
- }
- if (!shouldScavenge()) {
- m_scavengingScheduled = false;
- dispatch_suspend(m_scavengeTimer);
- }
+ if (!shouldScavenge()) {
+ m_scavengingScheduled = false;
+ dispatch_suspend(m_scavengeTimer);
+ }
}
#endif // HAVE(DISPATCH_H)
diff --git a/JavaScriptCore/wtf/NonCopyingSort.h b/JavaScriptCore/wtf/NonCopyingSort.h
new file mode 100644
index 0000000..fd611bd
--- /dev/null
+++ b/JavaScriptCore/wtf/NonCopyingSort.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WTF_NonCopyingSort_h
+#define WTF_NonCopyingSort_h
+
+namespace WTF {
+
+using std::swap;
+
+template<typename RandomAccessIterator, typename Predicate>
+inline void siftDown(RandomAccessIterator array, ptrdiff_t start, ptrdiff_t end, Predicate compareLess)
+{
+ ptrdiff_t root = start;
+
+ while (root * 2 + 1 <= end) {
+ ptrdiff_t child = root * 2 + 1;
+ if (child < end && compareLess(array[child], array[child + 1]))
+ child++;
+
+ if (compareLess(array[root], array[child])) {
+ swap(array[root], array[child]);
+ root = child;
+ } else
+ return;
+ }
+}
+
+template<typename RandomAccessIterator, typename Predicate>
+inline void heapify(RandomAccessIterator array, ptrdiff_t count, Predicate compareLess)
+{
+ ptrdiff_t start = (count - 2) / 2;
+
+ while (start >= 0) {
+ siftDown(array, start, count - 1, compareLess);
+ start--;
+ }
+}
+
+template<typename RandomAccessIterator, typename Predicate>
+void heapSort(RandomAccessIterator start, RandomAccessIterator end, Predicate compareLess)
+{
+ ptrdiff_t count = end - start;
+ heapify(start, count, compareLess);
+
+ ptrdiff_t endIndex = count - 1;
+ while (endIndex > 0) {
+ swap(start[endIndex], start[0]);
+ siftDown(start, 0, endIndex - 1, compareLess);
+ endIndex--;
+ }
+}
+
+template<typename RandomAccessIterator, typename Predicate>
+inline void nonCopyingSort(RandomAccessIterator start, RandomAccessIterator end, Predicate compareLess)
+{
+ // heapsort happens to use only swaps, not copies, but the essential thing about
+ // this function is the fact that it does not copy, not the specific algorithm
+ heapSort(start, end, compareLess);
+}
+
+} // namespace WTF
+
+using WTF::nonCopyingSort;
+
+#endif // WTF_NonCopyingSort_h
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 4fc0a64..e77fe98 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -142,6 +142,7 @@
#define WTF_MIPS_ARCH_REV __mips_isa_rev
#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
#define WTF_MIPS_DOUBLE_FLOAT (defined __mips_hard_float && !defined __mips_single_float)
+#define WTF_MIPS_FP64 (defined __mips_fpr && __mips_fpr == 64)
/* MIPS requires allocators to use aligned memory */
#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
#endif /* MIPS */
@@ -939,11 +940,7 @@
|| CPU(SPARC64) \
|| CPU(PPC64)
#define WTF_USE_JSVALUE64 1
-#elif CPU(MIPS) || (CPU(ARM_TRADITIONAL) && COMPILER(MSVC))
-#define WTF_USE_JSVALUE32 1
-#elif OS(WINDOWS) && COMPILER(MINGW)
-/* Using JSVALUE32_64 causes padding/alignement issues for JITStubArg
-on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
+#elif CPU(ARM_TRADITIONAL) && COMPILER(MSVC)
#define WTF_USE_JSVALUE32 1
#else
#define WTF_USE_JSVALUE32_64 1
@@ -959,6 +956,11 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#define ENABLE_JIT 0
#endif
+/* JIT is not implemented for 64 bit on MSVC */
+#if !defined(ENABLE_JIT) && COMPILER(MSVC) && CPU(X86_64)
+#define ENABLE_JIT 0
+#endif
+
/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */
#if !defined(ENABLE_JIT) \
&& (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \
@@ -1016,6 +1018,9 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#define ENABLE_COMPUTED_GOTO_INTERPRETER 1
#endif
+/* Regular Expression Tracing - Set to 1 to trace RegExp's in jsc. Results dumped at exit */
+#define ENABLE_REGEXP_TRACING 0
+
/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */
#if ENABLE(JIT) && !defined(ENABLE_YARR) && !defined(ENABLE_YARR_JIT)
#define ENABLE_YARR 1
@@ -1133,8 +1138,8 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#define ENABLE_BRANCH_COMPACTION 1
#endif
-#if PLATFORM(GTK)
-#include "GtkTypedefs.h"
+#if PLATFORM(GTK) || (PLATFORM(EFL) && ENABLE(GLIB_SUPPORT))
+#include "GTypedefs.h"
#endif
#endif /* WTF_Platform_h */
diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
index c16024c..14f7cf4 100644
--- a/JavaScriptCore/wtf/gobject/GRefPtr.cpp
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
@@ -66,4 +66,17 @@ template <> void derefPlatformPtr(GVariant* ptr)
#endif
+template <> GSource* refPlatformPtr(GSource* ptr)
+{
+ if (ptr)
+ g_source_ref(ptr);
+ return ptr;
+}
+
+template <> void derefPlatformPtr(GSource* ptr)
+{
+ if (ptr)
+ g_source_unref(ptr);
+}
+
} // namespace WTF
diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h
index 1ca55ce..ede0a7a 100644
--- a/JavaScriptCore/wtf/gobject/GRefPtr.h
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.h
@@ -36,6 +36,8 @@ template <> GHashTable* refPlatformPtr(GHashTable* ptr);
template <> void derefPlatformPtr(GHashTable* ptr);
template <> GVariant* refPlatformPtr(GVariant* ptr);
template <> void derefPlatformPtr(GVariant* ptr);
+template <> GSource* refPlatformPtr(GSource* ptr);
+template <> void derefPlatformPtr(GSource* ptr);
template <typename T> inline T* refPlatformPtr(T* ptr)
{
diff --git a/JavaScriptCore/wtf/gtk/GtkTypedefs.h b/JavaScriptCore/wtf/gobject/GTypedefs.h
index ee96f84..e79ba33 100644
--- a/JavaScriptCore/wtf/gtk/GtkTypedefs.h
+++ b/JavaScriptCore/wtf/gobject/GTypedefs.h
@@ -36,7 +36,8 @@ typedef unsigned long gulong;
typedef unsigned short gushort;
typedef void* gpointer;
-typedef struct _cairo_surface cairo_surface_t;
+typedef struct _GAsyncResult GAsyncResult;
+typedef struct _GCancellable GCancellable;
typedef struct _GCond GCond;
typedef struct _GDir GDir;
typedef struct _GdkAtom* GdkAtom;
@@ -48,9 +49,22 @@ typedef struct _GdkPixbuf GdkPixbuf;
typedef struct _GError GError;
typedef struct _GFile GFile;
typedef struct _GHashTable GHashTable;
+typedef struct _GInputStream GInputStream;
typedef struct _GList GList;
typedef struct _GMutex GMutex;
+typedef struct _GOutputStream GOutputStream;
typedef struct _GPatternSpec GPatternSpec;
+typedef struct _GSocketClient GSocketClient;
+typedef struct _GSocketConnection GSocketConnection;
+typedef struct _GSource GSource;
+typedef struct _GVariant GVariant;
+typedef union _GdkEvent GdkEvent;
+
+#if PLATFORM(CAIRO)
+typedef struct _cairo_surface cairo_surface_t;
+#endif
+
+#if PLATFORM(GTK)
typedef struct _GtkAction GtkAction;
typedef struct _GtkAdjustment GtkAdjustment;
typedef struct _GtkBorder GtkBorder;
@@ -65,8 +79,6 @@ typedef struct _GtkStyle GtkStyle;
typedef struct _GtkTargetList GtkTargetList;
typedef struct _GtkThemeParts GtkThemeParts;
typedef struct _GtkWidget GtkWidget;
-typedef struct _GVariant GVariant;
-typedef union _GdkEvent GdkEvent;
#ifdef GTK_API_VERSION_2
typedef struct _GdkRectangle GdkRectangle;
@@ -77,4 +89,5 @@ typedef cairo_rectangle_int_t GdkRectangle;
#endif
+#endif
#endif /* GtkTypedefs_h */
diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp
index a83dbba..9b53e81 100644
--- a/JavaScriptCore/wtf/text/WTFString.cpp
+++ b/JavaScriptCore/wtf/text/WTFString.cpp
@@ -335,7 +335,8 @@ String String::format(const char *format, ...)
va_end(args);
- return buffer;
+ QByteArray ba = buffer.toUtf8();
+ return StringImpl::create(ba.constData(), ba.length());
#elif OS(WINCE)
va_list args;
diff --git a/JavaScriptCore/wtf/url/api/ParsedURL.cpp b/JavaScriptCore/wtf/url/api/ParsedURL.cpp
new file mode 100644
index 0000000..abe0061
--- /dev/null
+++ b/JavaScriptCore/wtf/url/api/ParsedURL.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ParsedURL.h"
+
+#include "URLComponent.h"
+#include "URLParser.h"
+
+namespace WTF {
+
+ParsedURL::ParsedURL(const URLString& spec)
+ : m_spec(spec)
+{
+ // FIXME: Handle non-standard URLs.
+ if (spec.string().isEmpty())
+ return;
+ URLParser<UChar>::parseStandardURL(spec.string().characters(), spec.string().length(), m_segments);
+}
+
+String ParsedURL::scheme() const
+{
+ return segment(m_segments.scheme);
+}
+
+String ParsedURL::username() const
+{
+ return segment(m_segments.username);
+}
+
+String ParsedURL::password() const
+{
+ return segment(m_segments.password);
+}
+
+String ParsedURL::host() const
+{
+ return segment(m_segments.host);
+}
+
+String ParsedURL::port() const
+{
+ return segment(m_segments.port);
+}
+
+String ParsedURL::path() const
+{
+ return segment(m_segments.path);
+}
+
+String ParsedURL::query() const
+{
+ return segment(m_segments.query);
+}
+
+String ParsedURL::fragment() const
+{
+ return segment(m_segments.fragment);
+}
+
+String ParsedURL::segment(const URLComponent& component) const
+{
+ if (!component.isValid())
+ return String();
+ return m_spec.string().substring(component.begin(), component.length());
+}
+
+}
diff --git a/JavaScriptCore/wtf/url/api/ParsedURL.h b/JavaScriptCore/wtf/url/api/ParsedURL.h
new file mode 100644
index 0000000..ebc19b7
--- /dev/null
+++ b/JavaScriptCore/wtf/url/api/ParsedURL.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ParsedURL_h
+#define ParsedURL_h
+
+#include "URLSegments.h"
+#include "URLString.h"
+
+namespace WTF {
+
+class URLComponent;
+
+class ParsedURL {
+public:
+ explicit ParsedURL(const URLString&);
+
+ // FIXME: Add a method for parsing non-canonicalized URLs.
+
+ String scheme() const;
+ String username() const;
+ String password() const;
+ String host() const;
+ String port() const;
+ String path() const;
+ String query() const;
+ String fragment() const;
+
+ URLString spec() { return m_spec; }
+
+private:
+ inline String segment(const URLComponent&) const;
+
+ URLString m_spec;
+ URLSegments m_segments;
+};
+
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/url/api/URLString.h b/JavaScriptCore/wtf/url/api/URLString.h
new file mode 100644
index 0000000..7395d49
--- /dev/null
+++ b/JavaScriptCore/wtf/url/api/URLString.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef URLString_h
+#define URLString_h
+
+#include "WTFString.h"
+
+namespace WTF {
+
+// URLString represents a string that's a canonicalized URL.
+class URLString {
+public:
+ URLString() { }
+
+ const String& string() const { return m_string;}
+
+private:
+ friend class ParsedURL;
+
+ // URLString can only be constructed by a ParsedURL.
+ explicit URLString(const String& string)
+ : m_string(string)
+ {
+ }
+
+ String m_string;
+};
+
+}
+
+#endif
+
diff --git a/JavaScriptCore/yarr/RegexJIT.h b/JavaScriptCore/yarr/RegexJIT.h
index 7f9c16e..5d587b2 100644
--- a/JavaScriptCore/yarr/RegexJIT.h
+++ b/JavaScriptCore/yarr/RegexJIT.h
@@ -73,6 +73,10 @@ public:
{
return reinterpret_cast<RegexJITCode>(m_ref.m_code.executableAddress())(input, start, length, output);
}
+
+#if ENABLE(REGEXP_TRACING)
+ void *getAddr() { return m_ref.m_code.executableAddress(); }
+#endif
private:
MacroAssembler::CodeRef m_ref;
diff --git a/JavaScriptGlue/ChangeLog b/JavaScriptGlue/ChangeLog
index 1e49a3f..3a50e56 100644
--- a/JavaScriptGlue/ChangeLog
+++ b/JavaScriptGlue/ChangeLog
@@ -1,3 +1,22 @@
+2010-09-09 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Added ListHashSet.h as an exported header in support of RegExp tracing.
+ https://bugs.webkit.org/show_bug.cgi?id=45401
+
+ * ForwardingHeaders/wtf/ListHashSet.h: Added.
+
+2010-09-07 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/8381749> -Wcast-align warning emitted when building with clang
+
+ Remove the -Wcast-align-warning since it isn't really useful, and clang is more aggressive about warning than gcc.
+
+ * Configurations/Base.xcconfig:
+
2010-08-26 Sam Weinig <sam@webkit.org>
Reviewed by Darin Adler.
diff --git a/JavaScriptGlue/Configurations/Base.xcconfig b/JavaScriptGlue/Configurations/Base.xcconfig
index ab6988a..036a80c 100644
--- a/JavaScriptGlue/Configurations/Base.xcconfig
+++ b/JavaScriptGlue/Configurations/Base.xcconfig
@@ -47,7 +47,7 @@ LINKER_DISPLAYS_MANGLED_NAMES = YES;
PREBINDING = NO;
VALID_ARCHS = i386 ppc x86_64 ppc64;
WARNING_CFLAGS = $(WARNING_CFLAGS_$(CURRENT_ARCH));
-WARNING_CFLAGS_BASE = -Wall -W -Wcast-align -Wchar-subscripts -Wformat-security -Wmissing-format-attribute -Wpointer-arith -Wwrite-strings -Wno-format-y2k -Wno-unused-parameter -Wundef -Wno-strict-aliasing;
+WARNING_CFLAGS_BASE = -Wall -W -Wchar-subscripts -Wformat-security -Wmissing-format-attribute -Wpointer-arith -Wwrite-strings -Wno-format-y2k -Wno-unused-parameter -Wundef -Wno-strict-aliasing;
WARNING_CFLAGS_ = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
WARNING_CFLAGS_i386 = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
WARNING_CFLAGS_ppc = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
diff --git a/JavaScriptGlue/Configurations/Version.xcconfig b/JavaScriptGlue/Configurations/Version.xcconfig
index 29f35ef..673e234 100644
--- a/JavaScriptGlue/Configurations/Version.xcconfig
+++ b/JavaScriptGlue/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 534;
-MINOR_VERSION = 7;
+MINOR_VERSION = 8;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/ListHashSet.h b/JavaScriptGlue/ForwardingHeaders/wtf/ListHashSet.h
new file mode 100644
index 0000000..4aef773
--- /dev/null
+++ b/JavaScriptGlue/ForwardingHeaders/wtf/ListHashSet.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/ListHashSet.h>
diff --git a/LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback-expected.txt b/LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback-expected.txt
new file mode 100644
index 0000000..6bf84d4
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback-expected.txt
@@ -0,0 +1,18 @@
+Tests that adding a new event listener from a callback works as expected.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback.html b/LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback.html
new file mode 100644
index 0000000..fa338f5
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/add-listener-from-callback.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/add-listener-from-callback.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/DeviceOrientation/multiple-frames-expected.txt b/LayoutTests/fast/dom/DeviceOrientation/multiple-frames-expected.txt
new file mode 100644
index 0000000..5f24e38
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/multiple-frames-expected.txt
@@ -0,0 +1,15 @@
+Tests using DeviceOrientation from multiple frames.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/DeviceOrientation/multiple-frames.html b/LayoutTests/fast/dom/DeviceOrientation/multiple-frames.html
new file mode 100644
index 0000000..f0e1e89
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/multiple-frames.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/multiple-frames.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events-expected.txt b/LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events-expected.txt
new file mode 100644
index 0000000..0d95dee
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events-expected.txt
@@ -0,0 +1,10 @@
+Tests that events are never fired sycnhronously from a call to window.addEventListener().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS hasAddEventListenerReturned is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events.html b/LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events.html
new file mode 100644
index 0000000..23ce6b2
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/no-synchronous-events.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/no-synchronous-events.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/DeviceOrientation/null-values-expected.txt b/LayoutTests/fast/dom/DeviceOrientation/null-values-expected.txt
new file mode 100644
index 0000000..cb739ae
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/null-values-expected.txt
@@ -0,0 +1,21 @@
+Tests using null values for some of the event properties.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/DeviceOrientation/null-values.html b/LayoutTests/fast/dom/DeviceOrientation/null-values.html
new file mode 100644
index 0000000..d21463c
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/null-values.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/null-values.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/add-listener-from-callback.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/add-listener-from-callback.js
new file mode 100644
index 0000000..381b89c
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/add-listener-from-callback.js
@@ -0,0 +1,48 @@
+description('Tests that adding a new event listener from a callback works as expected.');
+
+var mockEvent;
+function setMockOrientation(alpha, beta, gamma) {
+ mockEvent = {alpha: alpha, beta: beta, gamma: gamma};
+ if (window.layoutTestController)
+ layoutTestController.setMockDeviceOrientation(true, mockEvent.alpha, true, mockEvent.beta, true, mockEvent.gamma);
+ else
+ debug('This test can not be run without the LayoutTestController');
+}
+
+var deviceOrientationEvent;
+function checkOrientation(event) {
+ deviceOrientationEvent = event;
+ shouldBe('deviceOrientationEvent.alpha', 'mockEvent.alpha');
+ shouldBe('deviceOrientationEvent.beta', 'mockEvent.beta');
+ shouldBe('deviceOrientationEvent.gamma', 'mockEvent.gamma');
+}
+
+var firstListenerEvents = 0;
+function firstListener(event) {
+ checkOrientation(event);
+ if (++firstListenerEvents == 1)
+ setMockOrientation(11.1, 22.2, 33.3);
+ else if (firstListenerEvents > 2)
+ testFailed('Too many events for first listener.');
+ window.addEventListener('deviceorientation', secondListener);
+ maybeFinishTest();
+}
+
+var secondListenerEvents = 0;
+function secondListener(event) {
+ checkOrientation(event);
+ if (++secondListenerEvents > 1)
+ testFailed('Too many events for second listener.');
+ maybeFinishTest();
+}
+
+function maybeFinishTest() {
+ if (firstListenerEvents == 2 && secondListenerEvents == 1)
+ finishJSTest();
+}
+
+setMockOrientation(1.1, 2.2, 3.3);
+window.addEventListener('deviceorientation', firstListener);
+
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/basic-operation.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/basic-operation.js
index 6e68b06..b5ff5ba 100644
--- a/LayoutTests/fast/dom/DeviceOrientation/script-tests/basic-operation.js
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/basic-operation.js
@@ -1,4 +1,4 @@
-description("Tests the basic operation of DeviceOrientation using the mock.");
+description('Tests the basic operation of DeviceOrientation using the mock.');
var mockAlpha = 1.1;
var mockBeta = 2.2;
@@ -10,7 +10,7 @@ else
debug('This test can not be run without the LayoutTestController');
var deviceOrientationEvent;
-window.addEventListener("deviceorientation", function(e) {
+window.addEventListener('deviceorientation', function(e) {
deviceOrientationEvent = e;
shouldBe('deviceOrientationEvent.alpha', 'mockAlpha');
shouldBe('deviceOrientationEvent.beta', 'mockBeta');
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/create-event.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/create-event.js
index 0fe8774..706de70 100644
--- a/LayoutTests/fast/dom/DeviceOrientation/script-tests/create-event.js
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/create-event.js
@@ -1,4 +1,4 @@
-description("Tests that document.createEvent() works with DeviceOrientationEvent.");
+description('Tests that document.createEvent() works with DeviceOrientationEvent.');
var event = document.createEvent('DeviceOrientationEvent');
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/multiple-frames.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/multiple-frames.js
new file mode 100644
index 0000000..f8b8fb9
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/multiple-frames.js
@@ -0,0 +1,43 @@
+description('Tests using DeviceOrientation from multiple frames.');
+
+var deviceOrientationEvent;
+function checkOrientation(event) {
+ deviceOrientationEvent = event;
+ shouldBe('deviceOrientationEvent.alpha', 'mockEvent.alpha');
+ shouldBe('deviceOrientationEvent.beta', 'mockEvent.beta');
+ shouldBe('deviceOrientationEvent.gamma', 'mockEvent.gamma');
+}
+
+var hasMainFrameEventFired = false;
+function mainFrameListener(event) {
+ checkOrientation(event);
+ hasMainFrameEventFired = true;
+ maybeFinishTest();
+}
+
+var hasChildFrameEventFired = false;
+function childFrameListener(event) {
+ checkOrientation(event);
+ hasChildFrameEventFired = true;
+ maybeFinishTest();
+}
+
+function maybeFinishTest() {
+ if (hasMainFrameEventFired && hasChildFrameEventFired)
+ finishJSTest();
+}
+
+var mockEvent = {alpha: 1.1, beta: 2.2, gamma: 3.3};
+if (window.layoutTestController)
+ layoutTestController.setMockDeviceOrientation(true, mockEvent.alpha, true, mockEvent.beta, true, mockEvent.gamma);
+else
+ debug('This test can not be run without the LayoutTestController');
+
+var childFrame = document.createElement('iframe');
+document.body.appendChild(childFrame);
+childFrame.contentWindow.addEventListener('deviceorientation', childFrameListener);
+
+window.addEventListener('deviceorientation', mainFrameListener);
+
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/no-synchronous-events.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/no-synchronous-events.js
new file mode 100644
index 0000000..0f4bc51
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/no-synchronous-events.js
@@ -0,0 +1,16 @@
+description('Tests that events are never fired sycnhronously from a call to window.addEventListener().');
+
+if (window.layoutTestController)
+ layoutTestController.setMockDeviceOrientation(true, 1.1, true, 2.2, true, 3.3);
+else
+ debug('This test can not be run without the LayoutTestController');
+
+var hasAddEventListenerReturned = false;
+window.addEventListener('deviceorientation', function() {
+ shouldBeTrue('hasAddEventListenerReturned');
+ finishJSTest();
+});
+hasAddEventListenerReturned = true;
+
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/null-values.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/null-values.js
new file mode 100644
index 0000000..ccde66a
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/null-values.js
@@ -0,0 +1,56 @@
+description('Tests using null values for some of the event properties.');
+
+var mockEvent;
+function setMockOrientation(alpha, beta, gamma) {
+ mockEvent = {alpha: alpha, beta: beta, gamma: gamma};
+ if (window.layoutTestController)
+ layoutTestController.setMockDeviceOrientation(
+ null != mockEvent.alpha, null == mockEvent.alpha ? 0 : mockEvent.alpha,
+ null != mockEvent.beta, null == mockEvent.beta ? 0 : mockEvent.beta,
+ null != mockEvent.gamma, null == mockEvent.gamma ? 0 : mockEvent.gamma);
+ else
+ debug('This test can not be run without the LayoutTestController');
+}
+
+var deviceOrientationEvent;
+function checkOrientation(event) {
+ deviceOrientationEvent = event;
+ shouldBe('deviceOrientationEvent.alpha', 'mockEvent.alpha');
+ shouldBe('deviceOrientationEvent.beta', 'mockEvent.beta');
+ shouldBe('deviceOrientationEvent.gamma', 'mockEvent.gamma');
+}
+
+function firstListener(event) {
+ checkOrientation(event);
+ window.removeEventListener('deviceorientation', firstListener);
+
+ setMockOrientation(1.1, null, null);
+ window.addEventListener('deviceorientation', secondListener);
+}
+
+function secondListener(event) {
+ checkOrientation(event);
+ window.removeEventListener('deviceorientation', secondListener);
+
+ setMockOrientation(null, 2.2, null);
+ window.addEventListener('deviceorientation', thirdListener);
+}
+
+function thirdListener(event) {
+ checkOrientation(event);
+ window.removeEventListener('deviceorientation', thirdListener);
+
+ setMockOrientation(null, null, 3.3);
+ window.addEventListener('deviceorientation', fourthListener);
+}
+
+function fourthListener(event) {
+ checkOrientation(event);
+ finishJSTest();
+}
+
+setMockOrientation(null, null, null);
+window.addEventListener('deviceorientation', firstListener);
+
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/optional-event-properties.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/optional-event-properties.js
index 2936e72..900c94b 100644
--- a/LayoutTests/fast/dom/DeviceOrientation/script-tests/optional-event-properties.js
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/optional-event-properties.js
@@ -1,4 +1,4 @@
-description("Tests the optional properties of DeviceOrientationEvent. Each property should be null if not set, or set to null or undefined.");
+description('Tests the optional properties of DeviceOrientationEvent. Each property should be null if not set, or set to null or undefined.');
var event;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/updates.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/updates.js
new file mode 100644
index 0000000..f5ec029
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/updates.js
@@ -0,0 +1,37 @@
+description('Tests that updates to the orientation causes new events to fire.');
+
+var mockEvent;
+function setMockOrientation(alpha, beta, gamma) {
+ mockEvent = {alpha: alpha, beta: beta, gamma: gamma};
+ if (window.layoutTestController)
+ layoutTestController.setMockDeviceOrientation(true, mockEvent.alpha, true, mockEvent.beta, true, mockEvent.gamma);
+ else
+ debug('This test can not be run without the LayoutTestController');
+}
+
+var deviceOrientationEvent;
+function checkOrientation(event) {
+ deviceOrientationEvent = event;
+ shouldBe('deviceOrientationEvent.alpha', 'mockEvent.alpha');
+ shouldBe('deviceOrientationEvent.beta', 'mockEvent.beta');
+ shouldBe('deviceOrientationEvent.gamma', 'mockEvent.gamma');
+}
+
+function firstListener(event) {
+ checkOrientation(event);
+ window.removeEventListener('deviceorientation', firstListener);
+
+ setMockOrientation(11.1, 22.2, 33.3);
+ window.addEventListener('deviceorientation', updateListener);
+}
+
+function updateListener(event) {
+ checkOrientation(event);
+ finishJSTest();
+}
+
+setMockOrientation(1.1, 2.2, 3.3);
+window.addEventListener('deviceorientation', firstListener);
+
+window.jsTestIsAsync = true;
+window.successfullyParsed = true;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/script-tests/window-property.js b/LayoutTests/fast/dom/DeviceOrientation/script-tests/window-property.js
index 8e65059..885932b 100644
--- a/LayoutTests/fast/dom/DeviceOrientation/script-tests/window-property.js
+++ b/LayoutTests/fast/dom/DeviceOrientation/script-tests/window-property.js
@@ -1,9 +1,9 @@
-description("Tests that the window.DeviceOrientationEvent and window.ondeviceorientation properties are present.");
+description('Tests that the window.DeviceOrientationEvent and window.ondeviceorientation properties are present.');
function hasDeviceOrientationEventProperty()
{
for (var property in window) {
- if (property == "DeviceOrientationEvent")
+ if (property == 'DeviceOrientationEvent')
return true;
}
return false;
@@ -18,7 +18,7 @@ shouldBeTrue("window.hasOwnProperty('DeviceOrientationEvent')");
function hasOnDeviceOrientationProperty()
{
for (var property in window) {
- if (property == "ondeviceorientation")
+ if (property == 'ondeviceorientation')
return true;
}
return false;
diff --git a/LayoutTests/fast/dom/DeviceOrientation/updates-expected.txt b/LayoutTests/fast/dom/DeviceOrientation/updates-expected.txt
new file mode 100644
index 0000000..6e54f16
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/updates-expected.txt
@@ -0,0 +1,15 @@
+Tests that updates to the orientation causes new events to fire.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS deviceOrientationEvent.alpha is mockEvent.alpha
+PASS deviceOrientationEvent.beta is mockEvent.beta
+PASS deviceOrientationEvent.gamma is mockEvent.gamma
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/DeviceOrientation/updates.html b/LayoutTests/fast/dom/DeviceOrientation/updates.html
new file mode 100644
index 0000000..5f2ac3c
--- /dev/null
+++ b/LayoutTests/fast/dom/DeviceOrientation/updates.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/updates.js"></script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js b/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js
index c83daa4..af5275d 100644
--- a/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js
+++ b/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js
@@ -20,13 +20,15 @@ function touchcancelHandler() {
if (window.layoutTestController)
window.layoutTestController.waitUntilDone();
-if (window.eventSender) {
- document.addEventListener("touchcancel", touchcancelHandler, false);
- eventSender.addTouchPoint(touchX, touchY);
- eventSender.touchStart();
- eventSender.cancelTouchPoint(0);
- eventSender.touchCancel();
-} else
- debug("This test requires DumpRenderTree.");
+window.onload = function() {
+ if (window.eventSender) {
+ document.addEventListener("touchcancel", touchcancelHandler, false);
+ eventSender.addTouchPoint(touchX, touchY);
+ eventSender.touchStart();
+ eventSender.cancelTouchPoint(0);
+ eventSender.touchCancel();
+ } else
+ debug("This test requires DumpRenderTree.");
+}
var successfullyParsed = true;
diff --git a/LayoutTests/platform/android/Skipped b/LayoutTests/platform/android/Skipped
deleted file mode 100644
index f4ab335..0000000
--- a/LayoutTests/platform/android/Skipped
+++ /dev/null
@@ -1,2 +0,0 @@
-# Full Screen support is not yet enabled.
-fullscreen/
diff --git a/LayoutTests/storage/indexeddb/basics.html b/LayoutTests/storage/indexeddb/basics.html
index 24af453..9f5f20f 100644
--- a/LayoutTests/storage/indexeddb/basics.html
+++ b/LayoutTests/storage/indexeddb/basics.html
@@ -8,6 +8,35 @@
<body>
<p id="description"></p>
<div id="console"></div>
-<script src="script-tests/basics.js"></script>
+<script>
+
+description("Test IndexedDB's basics.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function openCallback()
+{
+ verifySuccessEvent(event);
+ done();
+}
+
+function test()
+{
+ shouldBeTrue("'indexedDB' in window");
+ shouldBeFalse("indexedDB == null");
+
+ // FIXME: Verify other IndexedDatabaseRequest constructors, once they're implemented.
+
+ result = evalAndLog("indexedDB.open('name', 'description')");
+ verifyResult(result);
+ result.onsuccess = openCallback;
+ result.onerror = unexpectedErrorCallback;
+}
+
+test();
+
+var successfullyParsed = true;
+
+</script>
</body>
</html>
diff --git a/LayoutTests/storage/indexeddb/database-basics-expected.txt b/LayoutTests/storage/indexeddb/database-basics-expected.txt
index 1321f4d..fc224cc 100644
--- a/LayoutTests/storage/indexeddb/database-basics-expected.txt
+++ b/LayoutTests/storage/indexeddb/database-basics-expected.txt
@@ -23,11 +23,6 @@ PASS 'readyState' in event.target is true
PASS event.target.readyState is event.target.DONE
db = event.result
-PASS db.name is "name"
-PASS db.objectStores is []
-PASS db.objectStores.length is 0
-PASS db.objectStores.contains('') is false
-
Testing setVersion.
db.setVersion("version a")
PASS 'onsuccess' in result is true
@@ -36,6 +31,18 @@ PASS 'abort' in result is true
PASS 'readyState' in result is true
An event should fire shortly...
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
db.setVersion("version b")
PASS 'onsuccess' in result is true
PASS 'onerror' in result is true
@@ -43,8 +50,47 @@ PASS 'abort' in result is true
PASS 'readyState' in result is true
An event should fire shortly...
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
PASS db.version is "version b"
+PASS db.name is "name"
+PASS db.objectStores is []
+PASS db.objectStores.length is 0
+PASS db.objectStores.contains('') is false
+db.createObjectStore("test123")
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'abort' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS db.objectStores is ['test123']
+PASS db.objectStores.length is 1
+PASS db.objectStores.contains('') is false
+PASS db.objectStores.contains('test456') is false
+PASS db.objectStores.contains('test123') is true
PASS successfullyParsed is true
TEST COMPLETE
-
diff --git a/LayoutTests/storage/indexeddb/database-basics.html b/LayoutTests/storage/indexeddb/database-basics.html
index 9c92194..b099a49 100644
--- a/LayoutTests/storage/indexeddb/database-basics.html
+++ b/LayoutTests/storage/indexeddb/database-basics.html
@@ -8,6 +8,80 @@
<body>
<p id="description"></p>
<div id="console"></div>
-<script src="script-tests/database-basics.js"></script>
+<script>
+
+description("Test the basics of IndexedDB's IDBDatabase.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function openSuccess()
+{
+ verifySuccessEvent(event);
+
+ var db = evalAndLog("db = event.result");
+ deleteAllObjectStores(db);
+
+ // We must do something asynchronous before anything synchronous since
+ // deleteAllObjectStores only schedules the object stores to be removed.
+ // We don't know for sure whether it's happened until an IDBRequest object
+ // that was created after the removes fires.
+
+ debug("Testing setVersion.");
+ result = evalAndLog('db.setVersion("version a")');
+ verifyResult(result);
+ result.onsuccess = setVersionAgain;
+ result.onError = unexpectedErrorCallback;
+}
+
+function setVersionAgain()
+{
+ verifySuccessEvent(event);
+
+ result = evalAndLog('db.setVersion("version b")');
+ verifyResult(result);
+ result.onsuccess = createObjectStore;
+ result.onError = unexpectedErrorCallback;
+}
+
+function createObjectStore()
+{
+ verifySuccessEvent(event);
+ shouldBeEqualToString("db.version", "version b");
+ shouldBeEqualToString("db.name", "name");
+ shouldBe("db.objectStores", "[]");
+ shouldBe("db.objectStores.length", "0");
+ shouldBe("db.objectStores.contains('')", "false");
+
+ result = evalAndLog('db.createObjectStore("test123")');
+ verifyResult(result);
+ result.onsuccess = checkObjectStore;
+ result.onError = unexpectedErrorCallback;
+}
+
+function checkObjectStore()
+{
+ verifySuccessEvent(event);
+ shouldBe("db.objectStores", "['test123']");
+ shouldBe("db.objectStores.length", "1");
+ shouldBe("db.objectStores.contains('')", "false");
+ shouldBe("db.objectStores.contains('test456')", "false");
+ shouldBe("db.objectStores.contains('test123')", "true");
+
+ done();
+}
+
+function test()
+{
+ result = evalAndLog("indexedDB.open('name', 'description')");
+ verifyResult(result);
+ result.onsuccess = openSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+test();
+
+var successfullyParsed = true;
+
+</script>
</body>
</html>
diff --git a/LayoutTests/storage/indexeddb/keyrange-expected.txt b/LayoutTests/storage/indexeddb/keyrange-expected.txt
index a510a80..6528a11 100644
--- a/LayoutTests/storage/indexeddb/keyrange-expected.txt
+++ b/LayoutTests/storage/indexeddb/keyrange-expected.txt
@@ -3,6 +3,33 @@ Test IndexedDB's KeyRange.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+PASS 'SINGLE' in IDBKeyRange is true
+PASS 'LEFT_OPEN' in IDBKeyRange is true
+PASS 'RIGHT_OPEN' in IDBKeyRange is true
+PASS 'LEFT_BOUND' in IDBKeyRange is true
+PASS 'RIGHT_BOUND' in IDBKeyRange is true
+PASS 'left' in IDBKeyRange is false
+PASS 'right' in IDBKeyRange is false
+PASS 'flags' in IDBKeyRange is false
+PASS 'only' in IDBKeyRange is true
+PASS 'leftBound' in IDBKeyRange is true
+PASS 'rightBound' in IDBKeyRange is true
+PASS 'bound' in IDBKeyRange is true
+
+instance = IDBKeyRange.only(1)
+PASS 'SINGLE' in instance is true
+PASS 'LEFT_OPEN' in instance is true
+PASS 'RIGHT_OPEN' in instance is true
+PASS 'LEFT_BOUND' in instance is true
+PASS 'RIGHT_BOUND' in instance is true
+PASS 'left' in instance is true
+PASS 'right' in instance is true
+PASS 'flags' in instance is true
+PASS 'only' in instance is false
+PASS 'leftBound' in instance is false
+PASS 'rightBound' in instance is false
+PASS 'bound' in instance is false
+
IDBKeyRange.only(1)
PASS keyRange.left is 1
PASS keyRange.right is 1
@@ -117,3 +144,4 @@ PASS rightFlags is keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND
PASS successfullyParsed is true
TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/keyrange.html b/LayoutTests/storage/indexeddb/keyrange.html
index d4ef58e..d60cb15 100644
--- a/LayoutTests/storage/indexeddb/keyrange.html
+++ b/LayoutTests/storage/indexeddb/keyrange.html
@@ -8,6 +8,117 @@
<body>
<p id="description"></p>
<div id="console"></div>
-<script src="script-tests/keyrange.js"></script>
+<script>
+
+description("Test IndexedDB's KeyRange.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function checkSingleKeyRange(value)
+{
+ keyRange = evalAndLog("IDBKeyRange.only(" + value + ")");
+ shouldBe("keyRange.left", "" + value);
+ shouldBe("keyRange.right", "" + value);
+ shouldBe("keyRange.flags", "keyRange.SINGLE");
+}
+
+function checkLeftBoundKeyRange(value, open)
+{
+ keyRange = evalAndLog("IDBKeyRange.leftBound(" + value + "," + open + ")");
+ shouldBe("keyRange.left", "" + value);
+ shouldBeNull("keyRange.right");
+ shouldBe("keyRange.flags", open ? "keyRange.LEFT_OPEN | keyRange.LEFT_BOUND" : "keyRange.LEFT_BOUND");
+}
+
+function checkRightBoundKeyRange(value, open)
+{
+ keyRange = evalAndLog("IDBKeyRange.rightBound(" + value + "," + open + ")");
+ shouldBe("keyRange.right", "" + value);
+ shouldBeNull("keyRange.left");
+ shouldBe("keyRange.flags", open ? "keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND" : "keyRange.RIGHT_BOUND");
+}
+
+function checkBoundKeyRange(left, right, openLeft, openRight)
+{
+ keyRange = evalAndLog("IDBKeyRange.bound(" + left + "," + right + "," + openLeft + "," + openRight + ")");
+ shouldBe("keyRange.left", "" + left);
+ shouldBe("keyRange.right", "" + right);
+ leftFlags = keyRange.flags & (keyRange.LEFT_OPEN | keyRange.LEFT_BOUND);
+ shouldBe("leftFlags", openLeft ? "keyRange.LEFT_OPEN | keyRange.LEFT_BOUND" : "keyRange.LEFT_BOUND");
+ rightFlags = keyRange.flags & (keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND);
+ shouldBe("rightFlags", openRight ? "keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND" : "keyRange.RIGHT_BOUND");
+}
+
+function test()
+{
+ shouldBeTrue("'SINGLE' in IDBKeyRange");
+ shouldBeTrue("'LEFT_OPEN' in IDBKeyRange");
+ shouldBeTrue("'RIGHT_OPEN' in IDBKeyRange");
+ shouldBeTrue("'LEFT_BOUND' in IDBKeyRange");
+ shouldBeTrue("'RIGHT_BOUND' in IDBKeyRange");
+ shouldBeFalse("'left' in IDBKeyRange");
+ shouldBeFalse("'right' in IDBKeyRange");
+ shouldBeFalse("'flags' in IDBKeyRange");
+ shouldBeTrue("'only' in IDBKeyRange");
+ shouldBeTrue("'leftBound' in IDBKeyRange");
+ shouldBeTrue("'rightBound' in IDBKeyRange");
+ shouldBeTrue("'bound' in IDBKeyRange");
+
+ debug("");
+
+ var instance = evalAndLog("instance = IDBKeyRange.only(1)");
+ shouldBeTrue("'SINGLE' in instance");
+ shouldBeTrue("'LEFT_OPEN' in instance");
+ shouldBeTrue("'RIGHT_OPEN' in instance");
+ shouldBeTrue("'LEFT_BOUND' in instance");
+ shouldBeTrue("'RIGHT_BOUND' in instance");
+ shouldBeTrue("'left' in instance");
+ shouldBeTrue("'right' in instance");
+ shouldBeTrue("'flags' in instance");
+ shouldBeFalse("'only' in instance");
+ shouldBeFalse("'leftBound' in instance");
+ shouldBeFalse("'rightBound' in instance");
+ shouldBeFalse("'bound' in instance");
+
+ debug("");
+
+ checkSingleKeyRange(1);
+ checkSingleKeyRange("'a'");
+
+ checkLeftBoundKeyRange(10, true);
+ checkLeftBoundKeyRange(11, false);
+ checkLeftBoundKeyRange(12);
+ checkLeftBoundKeyRange("'aa'", true);
+ checkLeftBoundKeyRange("'ab'", false);
+ checkLeftBoundKeyRange("'ac'");
+
+ checkRightBoundKeyRange(20, true);
+ checkRightBoundKeyRange(21, false);
+ checkRightBoundKeyRange(22);
+ checkRightBoundKeyRange("'ba'", true);
+ checkRightBoundKeyRange("'bb'", false);
+ checkRightBoundKeyRange("'bc'");
+
+ checkBoundKeyRange(30, 40);
+ checkBoundKeyRange(31, 41, false, false);
+ checkBoundKeyRange(32, 42, false, true);
+ checkBoundKeyRange(33, 43, true, false);
+ checkBoundKeyRange(34, 44, true, true);
+
+ checkBoundKeyRange("'aaa'", "'aba'", false, false);
+ checkBoundKeyRange("'aab'", "'abb'");
+ checkBoundKeyRange("'aac'", "'abc'", false, false);
+ checkBoundKeyRange("'aad'", "'abd'", false, true);
+ checkBoundKeyRange("'aae'", "'abe'", true, false);
+ checkBoundKeyRange("'aaf'", "'abf'", true, true);
+
+}
+
+test();
+
+var successfullyParsed = true;
+done();
+
+</script>
</body>
</html>
diff --git a/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt b/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
index 105058d..a60e857 100644
--- a/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
+++ b/LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
@@ -50,7 +50,28 @@ PASS store.name is "storeName"
PASS store.keyPath is null
PASS storeNames.contains('storeName') is true
PASS storeNames.length is 1
-store.add('value', 'key')
+event.result.createIndex('indexName', 'x')
+PASS 'onsuccess' in result is true
+PASS 'onerror' in result is true
+PASS 'abort' in result is true
+PASS 'readyState' in result is true
+An event should fire shortly...
+
+addIndexSuccess():
+Success event fired:
+PASS 'result' in event is true
+PASS 'code' in event is false
+PASS 'message' in event is false
+PASS 'source' in event is true
+PASS event.source != null is true
+PASS 'onsuccess' in event.target is true
+PASS 'onerror' in event.target is true
+PASS 'abort' in event.target is true
+PASS 'readyState' in event.target is true
+PASS event.target.readyState is event.target.DONE
+
+PASS event.source.indexNames.contains('indexName') is true
+event.source.add({x: 'value'}, 'key')
PASS 'onsuccess' in result is true
PASS 'onerror' in result is true
PASS 'abort' in result is true
@@ -92,7 +113,7 @@ PASS 'abort' in event.target is true
PASS 'readyState' in event.target is true
PASS event.target.readyState is event.target.DONE
-PASS event.result is "value"
+PASS event.result.x is "value"
store = event.source
store.remove('key')
PASS 'onsuccess' in result is true
@@ -118,3 +139,4 @@ PASS event.result is null
PASS successfullyParsed is true
TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/objectstore-basics.html b/LayoutTests/storage/indexeddb/objectstore-basics.html
index 09eb68c..8b696c4 100644
--- a/LayoutTests/storage/indexeddb/objectstore-basics.html
+++ b/LayoutTests/storage/indexeddb/objectstore-basics.html
@@ -8,6 +8,103 @@
<body>
<p id="description"></p>
<div id="console"></div>
-<script src="script-tests/objectstore-basics.js"></script>
+<script>
+
+description("Test the basics of IndexedDB's IDBObjectStore.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function test()
+{
+ result = evalAndLog("indexedDB.open('name', 'description')");
+ verifyResult(result);
+ result.onsuccess = openSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function openSuccess()
+{
+ debug("openSuccess():");
+ verifySuccessEvent(event);
+ db = evalAndLog("db = event.result");
+
+ deleteAllObjectStores(db);
+
+ result = evalAndLog("db.createObjectStore('storeName', null)");
+ verifyResult(result);
+ result.onsuccess = createSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function createSuccess()
+{
+ debug("createSuccess():");
+ verifySuccessEvent(event);
+ var store = evalAndLog("store = event.result");
+ var storeNames = evalAndLog("storeNames = db.objectStores");
+
+ shouldBeEqualToString("store.name", "storeName");
+ shouldBeNull("store.keyPath");
+ shouldBe("storeNames.contains('storeName')", "true");
+ shouldBe("storeNames.length", "1");
+ // FIXME: test all of object store's methods.
+
+ result = evalAndLog("event.result.createIndex('indexName', 'x')");
+ verifyResult(result);
+ result.onsuccess = addIndexSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function addIndexSuccess()
+{
+ debug("addIndexSuccess():");
+ verifySuccessEvent(event);
+ shouldBeTrue("event.source.indexNames.contains('indexName')");
+
+ result = evalAndLog("event.source.add({x: 'value'}, 'key')");
+ verifyResult(result);
+ result.onsuccess = addSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function addSuccess()
+{
+ debug("addSuccess():");
+ verifySuccessEvent(event);
+ shouldBeEqualToString("event.result", "key");
+ var store = evalAndLog("store = event.source");
+
+ result = evalAndLog("store.get('key')");
+ verifyResult(result);
+ result.onsuccess = getSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function getSuccess()
+{
+ debug("getSuccess():");
+ verifySuccessEvent(event);
+ shouldBeEqualToString("event.result.x", "value");
+ var store = evalAndLog("store = event.source");
+
+ result = evalAndLog("store.remove('key')");
+ verifyResult(result);
+ result.onsuccess = removeSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function removeSuccess()
+{
+ debug("removeSuccess():");
+ verifySuccessEvent(event);
+ shouldBeNull("event.result");
+ done();
+}
+
+test();
+
+var successfullyParsed = true;
+
+</script>
</body>
</html>
diff --git a/LayoutTests/storage/indexeddb/objectstore-cursor.html b/LayoutTests/storage/indexeddb/objectstore-cursor.html
index bc69b43..25e9456 100644
--- a/LayoutTests/storage/indexeddb/objectstore-cursor.html
+++ b/LayoutTests/storage/indexeddb/objectstore-cursor.html
@@ -195,10 +195,7 @@ function cursorIteration()
window.expectedIndex = ascending ? expectedIndex+1 : expectedIndex-1;
testWithinBounds();
- request = event.result.continue();
- // FIXME: The spec says we should not return an IDBRequest and instead re-use the original request.
- request.onsuccess = cursorIteration;
- request.onerror = unexpectedErrorCallback;
+ event.result.continue();
}
openDatabase(); // The first step.
diff --git a/LayoutTests/storage/indexeddb/open-cursor.html b/LayoutTests/storage/indexeddb/open-cursor.html
index f60365d..03d1da0 100644
--- a/LayoutTests/storage/indexeddb/open-cursor.html
+++ b/LayoutTests/storage/indexeddb/open-cursor.html
@@ -8,6 +8,92 @@
<body>
<p id="description"></p>
<div id="console"></div>
-<script src="script-tests/open-cursor.js"></script>
+<script>
+
+description("Test IndexedDB's openCursor.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function emptyCursorSuccess()
+{
+ debug("Empty cursor opened successfully.")
+ verifySuccessEvent(event);
+ // FIXME: check that we can iterate the cursor.
+ done();
+}
+
+function openEmptyCursor()
+{
+ debug("Opening an empty cursor.");
+ keyRange = IDBKeyRange.leftBound("InexistentKey");
+ result = evalAndLog("objectStore.openCursor(keyRange)");
+ verifyResult(result);
+ result.onsuccess = emptyCursorSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function cursorSuccess()
+{
+ debug("Cursor opened successfully.")
+ verifySuccessEvent(event);
+ // FIXME: check that we can iterate the cursor.
+ shouldBe("event.result.direction", "0");
+ shouldBe("event.result.key", "'myKey'");
+ shouldBe("event.result.value", "'myValue'");
+ debug("");
+ openEmptyCursor();
+}
+
+function openCursor()
+{
+ debug("Opening cursor");
+ keyRange = IDBKeyRange.leftBound("myKey");
+ result = evalAndLog("objectStore.openCursor(keyRange)");
+ verifyResult(result);
+ result.onsuccess = cursorSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function populateObjectStore(objectStore)
+{
+ result = evalAndLog("objectStore.add('myValue', 'myKey')");
+ verifyResult(result);
+ result.onsuccess = openCursor;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function createObjectStoreSuccess()
+{
+ verifySuccessEvent(event);
+ var objectStore = evalAndLog("objectStore = event.result");
+ populateObjectStore(objectStore);
+}
+
+function openSuccess()
+{
+ verifySuccessEvent(event);
+ var db = evalAndLog("db = event.result");
+
+ deleteAllObjectStores(db);
+
+ result = evalAndLog("db.createObjectStore('test')");
+ verifyResult(result);
+ result.onsuccess = createObjectStoreSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function test()
+{
+ result = evalAndLog("indexedDB.open('name', 'description')");
+ verifyResult(result);
+ result.onsuccess = openSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+test();
+
+var successfullyParsed = true;
+
+</script>
</body>
</html>
diff --git a/LayoutTests/storage/indexeddb/script-tests/TEMPLATE.html b/LayoutTests/storage/indexeddb/script-tests/TEMPLATE.html
deleted file mode 100644
index 865fadb..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/TEMPLATE.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
-<head>
-<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
-<script src="../../fast/js/resources/js-test-pre.js"></script>
-<script src="../../fast/js/resources/js-test-post-function.js"></script>
-<script src="resources/shared.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="YOUR_JS_FILE_HERE"></script>
-</body>
-</html>
diff --git a/LayoutTests/storage/indexeddb/script-tests/basics.js b/LayoutTests/storage/indexeddb/script-tests/basics.js
deleted file mode 100644
index cebd48f..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/basics.js
+++ /dev/null
@@ -1,26 +0,0 @@
-description("Test IndexedDB's basics.");
-if (window.layoutTestController)
- layoutTestController.waitUntilDone();
-
-function openCallback()
-{
- verifySuccessEvent(event);
- done();
-}
-
-function test()
-{
- shouldBeTrue("'indexedDB' in window");
- shouldBeFalse("indexedDB == null");
-
- // FIXME: Verify other IndexedDatabaseRequest constructors, once they're implemented.
-
- result = evalAndLog("indexedDB.open('name', 'description')");
- verifyResult(result);
- result.onsuccess = openCallback;
- result.onerror = unexpectedErrorCallback;
-}
-
-test();
-
-var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/script-tests/database-basics.js b/LayoutTests/storage/indexeddb/script-tests/database-basics.js
deleted file mode 100644
index 04ebbd3..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/database-basics.js
+++ /dev/null
@@ -1,51 +0,0 @@
-description("Test the basics of IndexedDB's IDBDatabase.");
-if (window.layoutTestController)
- layoutTestController.waitUntilDone();
-
-function openSuccess()
-{
- verifySuccessEvent(event);
-
- var db = evalAndLog("db = event.result");
- shouldBeEqualToString("db.name", "name");
- shouldBe("db.objectStores", "[]");
- shouldBe("db.objectStores.length", "0");
- shouldBe("db.objectStores.contains('')", "false");
- // FIXME: Test .item() once it's possible to get back a non-empty list.
-
- // FIXME: Test the other properties of IDBDatabase as they're written.
-
- debug("");
- debug("Testing setVersion.");
- result = evalAndLog('db.setVersion("version a")');
- verifyResult(result);
- result.onsuccess = setVersionAgain;
- result.onError = unexpectedErrorCallback;
-}
-
-function setVersionAgain()
-{
- result = evalAndLog('db.setVersion("version b")');
- verifyResult(result);
- result.onsuccess = checkVersion;
- result.onError = unexpectedErrorCallback;
-}
-
-function checkVersion()
-{
- shouldBeEqualToString("db.version", "version b");
-
- done();
-}
-
-function test()
-{
- result = evalAndLog("indexedDB.open('name', 'description')");
- verifyResult(result);
- result.onsuccess = openSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-test();
-
-var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/script-tests/keyrange.js b/LayoutTests/storage/indexeddb/script-tests/keyrange.js
deleted file mode 100644
index 907d817..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/keyrange.js
+++ /dev/null
@@ -1,76 +0,0 @@
-description("Test IndexedDB's KeyRange.");
-if (window.layoutTestController)
- layoutTestController.waitUntilDone();
-
-function checkSingleKeyRange(value)
-{
- keyRange = evalAndLog("IDBKeyRange.only(" + value + ")");
- shouldBe("keyRange.left", "" + value);
- shouldBe("keyRange.right", "" + value);
- shouldBe("keyRange.flags", "keyRange.SINGLE");
-}
-
-function checkLeftBoundKeyRange(value, open)
-{
- keyRange = evalAndLog("IDBKeyRange.leftBound(" + value + "," + open + ")");
- shouldBe("keyRange.left", "" + value);
- shouldBeNull("keyRange.right");
- shouldBe("keyRange.flags", open ? "keyRange.LEFT_OPEN | keyRange.LEFT_BOUND" : "keyRange.LEFT_BOUND");
-}
-
-function checkRightBoundKeyRange(value, open)
-{
- keyRange = evalAndLog("IDBKeyRange.rightBound(" + value + "," + open + ")");
- shouldBe("keyRange.right", "" + value);
- shouldBeNull("keyRange.left");
- shouldBe("keyRange.flags", open ? "keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND" : "keyRange.RIGHT_BOUND");
-}
-
-function checkBoundKeyRange(left, right, openLeft, openRight)
-{
- keyRange = evalAndLog("IDBKeyRange.bound(" + left + "," + right + "," + openLeft + "," + openRight + ")");
- shouldBe("keyRange.left", "" + left);
- shouldBe("keyRange.right", "" + right);
- leftFlags = keyRange.flags & (keyRange.LEFT_OPEN | keyRange.LEFT_BOUND);
- shouldBe("leftFlags", openLeft ? "keyRange.LEFT_OPEN | keyRange.LEFT_BOUND" : "keyRange.LEFT_BOUND");
- rightFlags = keyRange.flags & (keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND);
- shouldBe("rightFlags", openRight ? "keyRange.RIGHT_OPEN | keyRange.RIGHT_BOUND" : "keyRange.RIGHT_BOUND");
-}
-
-function test()
-{
- checkSingleKeyRange(1);
- checkSingleKeyRange("'a'");
-
- checkLeftBoundKeyRange(10, true);
- checkLeftBoundKeyRange(11, false);
- checkLeftBoundKeyRange(12);
- checkLeftBoundKeyRange("'aa'", true);
- checkLeftBoundKeyRange("'ab'", false);
- checkLeftBoundKeyRange("'ac'");
-
- checkRightBoundKeyRange(20, true);
- checkRightBoundKeyRange(21, false);
- checkRightBoundKeyRange(22);
- checkRightBoundKeyRange("'ba'", true);
- checkRightBoundKeyRange("'bb'", false);
- checkRightBoundKeyRange("'bc'");
-
- checkBoundKeyRange(30, 40);
- checkBoundKeyRange(31, 41, false, false);
- checkBoundKeyRange(32, 42, false, true);
- checkBoundKeyRange(33, 43, true, false);
- checkBoundKeyRange(34, 44, true, true);
-
- checkBoundKeyRange("'aaa'", "'aba'", false, false);
- checkBoundKeyRange("'aab'", "'abb'");
- checkBoundKeyRange("'aac'", "'abc'", false, false);
- checkBoundKeyRange("'aad'", "'abd'", false, true);
- checkBoundKeyRange("'aae'", "'abe'", true, false);
- checkBoundKeyRange("'aaf'", "'abf'", true, true);
-}
-
-test();
-
-var successfullyParsed = true;
-done();
diff --git a/LayoutTests/storage/indexeddb/script-tests/objectstore-basics.js b/LayoutTests/storage/indexeddb/script-tests/objectstore-basics.js
deleted file mode 100644
index 63675ad..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/objectstore-basics.js
+++ /dev/null
@@ -1,82 +0,0 @@
-description("Test the basics of IndexedDB's IDBObjectStore.");
-if (window.layoutTestController)
- layoutTestController.waitUntilDone();
-
-function test()
-{
- result = evalAndLog("indexedDB.open('name', 'description')");
- verifyResult(result);
- result.onsuccess = openSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function openSuccess()
-{
- debug("openSuccess():");
- verifySuccessEvent(event);
- db = evalAndLog("db = event.result");
-
- deleteAllObjectStores(db);
-
- result = evalAndLog("db.createObjectStore('storeName', null)");
- verifyResult(result);
- result.onsuccess = createSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function createSuccess()
-{
- debug("createSuccess():");
- verifySuccessEvent(event);
- var store = evalAndLog("store = event.result");
- var storeNames = evalAndLog("storeNames = db.objectStores");
-
- shouldBeEqualToString("store.name", "storeName");
- shouldBeNull("store.keyPath");
- shouldBe("storeNames.contains('storeName')", "true");
- shouldBe("storeNames.length", "1");
- // FIXME: test store.indexNames, as well as all object store's methods.
-
- result = evalAndLog("store.add('value', 'key')");
- verifyResult(result);
- result.onsuccess = addSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function addSuccess()
-{
- debug("addSuccess():");
- verifySuccessEvent(event);
- shouldBeEqualToString("event.result", "key");
- var store = evalAndLog("store = event.source");
-
- result = evalAndLog("store.get('key')");
- verifyResult(result);
- result.onsuccess = getSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function getSuccess()
-{
- debug("getSuccess():");
- verifySuccessEvent(event);
- shouldBeEqualToString("event.result", "value");
- var store = evalAndLog("store = event.source");
-
- result = evalAndLog("store.remove('key')");
- verifyResult(result);
- result.onsuccess = removeSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function removeSuccess()
-{
- debug("removeSuccess():");
- verifySuccessEvent(event);
- shouldBeNull("event.result");
- done();
-}
-
-test();
-
-var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/script-tests/open-cursor.js b/LayoutTests/storage/indexeddb/script-tests/open-cursor.js
deleted file mode 100644
index 53ea96b..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/open-cursor.js
+++ /dev/null
@@ -1,83 +0,0 @@
-description("Test IndexedDB's openCursor.");
-if (window.layoutTestController)
- layoutTestController.waitUntilDone();
-
-function emptyCursorSuccess()
-{
- debug("Empty cursor opened successfully.")
- verifySuccessEvent(event);
- // FIXME: check that we can iterate the cursor.
- done();
-}
-
-function openEmptyCursor()
-{
- debug("Opening an empty cursor.");
- keyRange = IDBKeyRange.leftBound("InexistentKey");
- result = evalAndLog("objectStore.openCursor(keyRange)");
- verifyResult(result);
- result.onsuccess = emptyCursorSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function cursorSuccess()
-{
- debug("Cursor opened successfully.")
- verifySuccessEvent(event);
- // FIXME: check that we can iterate the cursor.
- shouldBe("event.result.direction", "0");
- shouldBe("event.result.key", "'myKey'");
- shouldBe("event.result.value", "'myValue'");
- debug("");
- openEmptyCursor();
-}
-
-function openCursor()
-{
- debug("Opening cursor");
- keyRange = IDBKeyRange.leftBound("myKey");
- result = evalAndLog("objectStore.openCursor(keyRange)");
- verifyResult(result);
- result.onsuccess = cursorSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function populateObjectStore(objectStore)
-{
- result = evalAndLog("objectStore.add('myValue', 'myKey')");
- verifyResult(result);
- result.onsuccess = openCursor;
- result.onerror = unexpectedErrorCallback;
-}
-
-function createObjectStoreSuccess()
-{
- verifySuccessEvent(event);
- var objectStore = evalAndLog("objectStore = event.result");
- populateObjectStore(objectStore);
-}
-
-function openSuccess()
-{
- verifySuccessEvent(event);
- var db = evalAndLog("db = event.result");
-
- deleteAllObjectStores(db);
-
- result = evalAndLog("db.createObjectStore('test')");
- verifyResult(result);
- result.onsuccess = createObjectStoreSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function test()
-{
- result = evalAndLog("indexedDB.open('name', 'description')");
- verifyResult(result);
- result.onsuccess = openSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-test();
-
-var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/script-tests/transaction-basics.js b/LayoutTests/storage/indexeddb/script-tests/transaction-basics.js
deleted file mode 100644
index 58ac2a7..0000000
--- a/LayoutTests/storage/indexeddb/script-tests/transaction-basics.js
+++ /dev/null
@@ -1,47 +0,0 @@
-description("Test IndexedDB transaction basics.");
-if (window.layoutTestController)
- layoutTestController.waitUntilDone();
-
-function test()
-{
- shouldBeTrue("'indexedDB' in window");
- shouldBeFalse("indexedDB == null");
-
- result = evalAndLog("indexedDB.open('name', 'description')");
- verifyResult(result);
- result.onsuccess = openSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function openSuccess()
-{
- debug("createObjectStoreCallback():");
- verifySuccessEvent(event);
- db = evalAndLog("db = event.result");
-
- deleteAllObjectStores(db);
-
- result = evalAndLog("db.createObjectStore('storeName', null)");
- verifyResult(result);
- result.onsuccess = createSuccess;
- result.onerror = unexpectedErrorCallback;
-}
-
-function createSuccess()
-{
- verifySuccessEvent(event);
- transaction = evalAndLog("db.transaction()");
- transaction.onabort = abortCallback;
- var store = evalAndLog("store = transaction.objectStore('storeName')");
- shouldBeEqualToString("store.name", "storeName");
-}
-
-function abortCallback()
-{
- verifyAbortEvent(event);
- done();
-}
-
-test();
-
-var successfullyParsed = true;
diff --git a/LayoutTests/storage/indexeddb/transaction-basics.html b/LayoutTests/storage/indexeddb/transaction-basics.html
index a7238f6..cea5d5d 100644
--- a/LayoutTests/storage/indexeddb/transaction-basics.html
+++ b/LayoutTests/storage/indexeddb/transaction-basics.html
@@ -8,6 +8,56 @@
<body>
<p id="description"></p>
<div id="console"></div>
-<script src="script-tests/transaction-basics.js"></script>
+<script>
+
+description("Test IndexedDB transaction basics.");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function test()
+{
+ shouldBeTrue("'indexedDB' in window");
+ shouldBeFalse("indexedDB == null");
+
+ result = evalAndLog("indexedDB.open('name', 'description')");
+ verifyResult(result);
+ result.onsuccess = openSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function openSuccess()
+{
+ debug("createObjectStoreCallback():");
+ verifySuccessEvent(event);
+ db = evalAndLog("db = event.result");
+
+ deleteAllObjectStores(db);
+
+ result = evalAndLog("db.createObjectStore('storeName', null)");
+ verifyResult(result);
+ result.onsuccess = createSuccess;
+ result.onerror = unexpectedErrorCallback;
+}
+
+function createSuccess()
+{
+ verifySuccessEvent(event);
+ transaction = evalAndLog("db.transaction()");
+ transaction.onabort = abortCallback;
+ var store = evalAndLog("store = transaction.objectStore('storeName')");
+ shouldBeEqualToString("store.name", "storeName");
+}
+
+function abortCallback()
+{
+ verifyAbortEvent(event);
+ done();
+}
+
+test();
+
+var successfullyParsed = true;
+
+</script>
</body>
</html>
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index 7638798..196ec69 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -292,9 +292,16 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/HTMLTableRowsCollection.cpp \
html/HTMLViewSourceDocument.cpp \
html/ImageData.cpp \
+ html/ImageDocument.cpp \
+ html/MediaDocument.cpp \
html/ImageResizerThread.cpp \
+<<<<<<< HEAD
html/LabelsNodeList.cpp \
html/StepRange.cpp \
+=======
+ html/PluginDocument.cpp \
+ html/TextDocument.cpp \
+>>>>>>> webkit.org at r67178
html/TimeRanges.cpp \
html/ValidityState.cpp \
\
@@ -319,6 +326,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/parser/HTMLTokenizer.cpp \
html/parser/HTMLTreeBuilder.cpp \
html/parser/HTMLViewSourceParser.cpp \
+ html/parser/TextDocumentParser.cpp \
+ html/parser/TextViewSourceParser.cpp \
\
loader/Cache.cpp \
loader/CachedCSSStyleSheet.cpp \
@@ -330,7 +339,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
loader/CachedScript.cpp \
loader/CrossOriginAccessControl.cpp \
loader/CrossOriginPreflightResultCache.cpp \
- loader/DocLoader.cpp \
+ loader/CachedResourceLoader.cpp \
loader/DocumentLoader.cpp \
loader/DocumentThreadableLoader.cpp \
loader/DocumentWriter.cpp \
@@ -339,15 +348,12 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
loader/FrameLoader.cpp \
loader/FrameLoaderStateMachine.cpp \
loader/HistoryController.cpp \
- loader/ImageDocument.cpp \
loader/ImageLoader.cpp \
loader/MainResourceLoader.cpp \
- loader/MediaDocument.cpp \
loader/NavigationAction.cpp \
loader/NetscapePlugInStreamLoader.cpp \
loader/PingLoader.cpp \
loader/PlaceholderDocument.cpp \
- loader/PluginDocument.cpp \
loader/PolicyCallback.cpp \
loader/PolicyChecker.cpp \
loader/ProgressTracker.cpp \
@@ -358,7 +364,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
loader/SinkDocument.cpp \
loader/SubframeLoader.cpp \
loader/SubresourceLoader.cpp \
- loader/TextDocument.cpp \
loader/TextResourceDecoder.cpp \
loader/ThreadableLoader.cpp \
loader/WorkerThreadableLoader.cpp \
@@ -721,6 +726,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
rendering/RenderSVGResourceClipper.cpp \
rendering/RenderSVGResourceContainer.cpp \
rendering/RenderSVGResourceFilter.cpp \
+ rendering/RenderSVGResourceFilterPrimitive.cpp \
rendering/RenderSVGResourceGradient.cpp \
rendering/RenderSVGResourceLinearGradient.cpp \
rendering/RenderSVGResourceMarker.cpp \
diff --git a/WebCore/CMakeLists.txt b/WebCore/CMakeLists.txt
index 1d9159f..4fb3c0a 100644
--- a/WebCore/CMakeLists.txt
+++ b/WebCore/CMakeLists.txt
@@ -198,7 +198,6 @@ SET(WebCore_IDL_FILES
fileapi/File.idl
fileapi/FileList.idl
fileapi/FileReader.idl
- fileapi/FileWriter.idl
html/DataGridColumn.idl
html/DataGridColumnList.idl
@@ -941,6 +940,7 @@ SET(WebCore_SOURCES
html/DataGridColumn.cpp
html/DataGridColumnList.cpp
html/DateComponents.cpp
+ html/FTPDirectoryDocument.cpp
html/FormDataList.cpp
html/HTMLAllCollection.cpp
html/HTMLAnchorElement.cpp
@@ -1024,9 +1024,13 @@ SET(WebCore_SOURCES
html/HTMLUListElement.cpp
html/HTMLViewSourceDocument.cpp
html/ImageData.cpp
+ html/ImageDocument.cpp
html/ImageResizerThread.cpp
html/LabelsNodeList.cpp
+ html/MediaDocument.cpp
+ html/PluginDocument.cpp
html/StepRange.cpp
+ html/TextDocument.cpp
html/ValidityState.cpp
html/canvas/CanvasGradient.cpp
html/canvas/CanvasPattern.cpp
@@ -1047,6 +1051,8 @@ SET(WebCore_SOURCES
html/parser/HTMLTokenizer.cpp
html/parser/HTMLTreeBuilder.cpp
html/parser/HTMLViewSourceParser.cpp
+ html/parser/TextDocumentParser.cpp
+ html/parser/TextViewSourceParser.cpp
inspector/ConsoleMessage.cpp
inspector/InjectedScript.cpp
@@ -1080,26 +1086,22 @@ SET(WebCore_SOURCES
loader/CachedXSLStyleSheet.cpp
loader/CrossOriginAccessControl.cpp
loader/CrossOriginPreflightResultCache.cpp
- loader/DocLoader.cpp
+ loader/CachedResourceLoader.cpp
loader/DocumentLoader.cpp
loader/DocumentThreadableLoader.cpp
loader/DocumentWriter.cpp
- loader/FTPDirectoryDocument.cpp
loader/FTPDirectoryParser.cpp
loader/FormState.cpp
loader/FormSubmission.cpp
loader/FrameLoader.cpp
loader/FrameLoaderStateMachine.cpp
loader/HistoryController.cpp
- loader/ImageDocument.cpp
loader/ImageLoader.cpp
loader/MainResourceLoader.cpp
- loader/MediaDocument.cpp
loader/NavigationAction.cpp
loader/NetscapePlugInStreamLoader.cpp
loader/PingLoader.cpp
loader/PlaceholderDocument.cpp
- loader/PluginDocument.cpp
loader/PolicyCallback.cpp
loader/PolicyChecker.cpp
loader/ProgressTracker.cpp
@@ -1110,7 +1112,6 @@ SET(WebCore_SOURCES
loader/SinkDocument.cpp
loader/SubframeLoader.cpp
loader/SubresourceLoader.cpp
- loader/TextDocument.cpp
loader/TextResourceDecoder.cpp
loader/ThreadableLoader.cpp
loader/WorkerThreadableLoader.cpp
@@ -1198,7 +1199,9 @@ SET(WebCore_SOURCES
platform/LinkHash.cpp
platform/Logging.cpp
platform/MIMETypeRegistry.cpp
+ platform/ScrollAnimator.cpp
platform/Scrollbar.cpp
+ platform/ScrollbarClient.cpp
platform/ScrollbarThemeComposite.cpp
platform/ScrollView.cpp
platform/SharedBuffer.cpp
@@ -1582,6 +1585,7 @@ if (ENABLE_FILE_SYSTEM)
fileapi/EntryArray.idl
fileapi/EntryCallback.idl
fileapi/ErrorCallback.idl
+ fileapi/FileCallback.idl
fileapi/FileEntry.idl
fileapi/FileSystemCallback.idl
fileapi/Flags.idl
@@ -1590,6 +1594,16 @@ if (ENABLE_FILE_SYSTEM)
)
ENDIF ()
+if (ENABLE_FILE_WRITER)
+ LIST(APPEND WebCore_SOURCES
+ fileapi/FileWriter.cpp
+ )
+ LIST(APPEND WebCore_IDL_FILES
+ fileapi/FileWriterCallback.idl
+ fileapi/FileWriter.idl
+ )
+ENDIF ()
+
IF (ENABLE_SVG)
LIST(APPEND WebCore_SOURCES
bindings/js/JSSVGElementInstanceCustom.cpp
@@ -1615,6 +1629,7 @@ IF (ENABLE_SVG)
rendering/RenderSVGResourceClipper.cpp
rendering/RenderSVGResourceContainer.cpp
rendering/RenderSVGResourceFilter.cpp
+ rendering/RenderSVGResourceFilterPrimitive.cpp
rendering/RenderSVGResourceGradient.cpp
rendering/RenderSVGResourceLinearGradient.cpp
rendering/RenderSVGResourceMarker.cpp
diff --git a/WebCore/CMakeListsEfl.txt b/WebCore/CMakeListsEfl.txt
index 1741baa..530acf3 100644
--- a/WebCore/CMakeListsEfl.txt
+++ b/WebCore/CMakeListsEfl.txt
@@ -69,7 +69,7 @@ IF (WTF_PLATFORM_CAIRO)
platform/graphics/cairo/FontCairo.cpp
platform/graphics/cairo/FontCustomPlatformData.cpp
platform/graphics/cairo/FontPlatformDataCairo.cpp
- platform/graphics/cairo/GOwnPtrCairo.cpp
+ platform/graphics/cairo/OwnPtrCairo.cpp
platform/graphics/cairo/PlatformRefPtrCairo.cpp
platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
platform/graphics/cairo/GradientCairo.cpp
@@ -122,6 +122,22 @@ IF (WTF_USE_ICU_UNICODE)
)
ENDIF ()
+IF (ENABLE_VIDEO)
+ LIST(APPEND WebCore_INCLUDE_DIRECTORIES
+ "${WEBCORE_DIR}/platform/graphics/gstreamer"
+ )
+ LIST(APPEND WebCore_SOURCES
+ platform/graphics/gstreamer/DataSourceGStreamer.cpp
+ platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
+ platform/graphics/gstreamer/GStreamerGWorld.cpp
+ platform/graphics/gstreamer/ImageGStreamerCairo.cpp
+ platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+ platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
+ platform/graphics/gstreamer/VideoSinkGStreamer.cpp
+ platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
+ )
+ENDIF ()
+
LIST(APPEND WebCore_LIBRARIES
${Cairo_LIBRARIES}
${ECORE_X_LIBRARIES}
@@ -147,6 +163,15 @@ IF (WTF_USE_CURL)
)
ENDIF ()
+IF (ENABLE_VIDEO)
+ LIST(APPEND WebCore_LIBRARIES
+ ${GStreamer-App_LIBRARIES}
+ ${GStreamer-Interfaces_LIBRARIES}
+ ${GStreamer-Pbutils_LIBRARIES}
+ ${GStreamer-Video_LIBRARIES}
+ )
+ENDIF ()
+
LIST(APPEND WebCore_INCLUDE_DIRECTORIES
${Cairo_INCLUDE_DIRS}
${ECORE_X_INCLUDE_DIRS}
@@ -160,6 +185,16 @@ LIST(APPEND WebCore_INCLUDE_DIRECTORIES
${SQLITE_INCLUDE_DIRS}
)
+IF (ENABLE_VIDEO)
+ LIST(APPEND WebCore_INCLUDE_DIRECTORIES
+ ${GStreamer-App_INCLUDE_DIRS}
+ ${GStreamer-Interfaces_INCLUDE_DIRS}
+ ${GStreamer-Pbutils_INCLUDE_DIRS}
+ ${GStreamer-Video_INCLUDE_DIRS}
+ )
+ENDIF ()
+
+
IF (ENABLE_GLIB_SUPPORT)
LIST(APPEND WebCore_LIBRARIES
${GDK_LIBRARIES}
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 32a3cef..730308a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,5471 @@
+2010-09-10 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ roll out r66992 and r66997 - possibly introduced a perf slowdown in chromium tests
+ https://bugs.webkit.org/show_bug.cgi?id=45524
+
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::parametersForPlugin):
+ (WebCore::HTMLObjectElement::updateWidget):
+ * loader/SubframeLoader.cpp:
+ (WebCore::SubframeLoader::requestFrame):
+ * loader/SubframeLoader.h:
+
+2010-09-10 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Tony Chang.
+
+ Extract the code to find special ancestors in createMarkup into a function
+ https://bugs.webkit.org/show_bug.cgi?id=45449
+
+ Extracted the code to find special common ancestors in createMarkup as highestAncestorToWrapMarkup.
+ Also isolated the code to find ancestors required to retain structure and appearance into
+ ancestorToRetainStructureAndAppearance.
+
+ No new tests are added since this is a cleanup.
+
+ * editing/markup.cpp:
+ (WebCore::ancestorToRetainStructureAndAppearance): Added.
+ (WebCore::propertyMissingOrEqualToNone): Moved.
+ (WebCore::isElementPresentational): Moved.
+ (WebCore::shouldIncludeWrapperForFullySelectedRoot): Added. isSpecialAncestorBlock is merged into this function.
+ (WebCore::highestAncestorToWrapMarkup): Extracted from createMarkup.
+ (WebCore::createMarkup): Calls highestAncestorToWrapMarkup.
+
+2010-09-09 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Spurious null check in MediaDocumentParser
+ https://bugs.webkit.org/show_bug.cgi?id=45461
+
+ Trivial change. FrameLoader can never be null.
+
+ * html/MediaDocument.cpp:
+ (WebCore::MediaDocumentParser::createDocumentStructure):
+
+2010-09-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ REGRESSION: applying new font size causes font-size outside selection to change
+ https://bugs.webkit.org/show_bug.cgi?id=45026
+
+ The regression was caused by removeImplicitlyStyledElement not converting font size to CSS value properly.
+ Namely, it was treating font size as a pixel value for font-size property. Fixed this by adding fontSizeToCSSValue
+ which uses HTMLFontElement::cssValueFromFontSizeNumber and deployed it in removeImplicitlyStyledElement
+
+ Also fixed a bug in StyleChange::extractTextStyles that it ignores font-size property when the values were
+ relative terms such as x-small and -webkit-xxx-large. And replaced the logic to convert from pixel font size
+ to legacy font size by CSSStyleSelector::legacyFontSize.
+
+ Test: editing/style/push-down-font-styles.html
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::StyleChange::extractTextStyles): Fixed a bug. See above.
+ (WebCore::stringToCSSValue): Converts string to CSSValue.
+ (WebCore::fontSizeToCSSValue): Converts font size number (String) to CSSPrimitiveValue.
+ (WebCore::ApplyStyleCommand::removeImplicitlyStyledElement): Calls stringToCSSValue and fontSizeToCSSValue.
+ * css/CSSStyleSelector.h: Made fontSizeForKeyword public.
+
+2010-09-09 Kent Tamura <tkent@chromium.org>
+
+ Unreviewed, build fix for Qt.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+
+2010-09-09 Dominic Cooney <dominicc@google.com>
+
+ Reviewed by Kent Tamura.
+
+ Moves location.replace bindings logic into bindings/generic and
+ instantiates it for JSC and V8.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44891
+
+ Covered by existing location.replace tests.
+
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.vcproj/WebCoreCommon.vsprops:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/generic/BindingDOMWindow.h:
+ * bindings/generic/BindingFrame.h: Added.
+ (WebCore::::navigateIfAllowed):
+ * bindings/generic/BindingLocation.h: Added.
+ (WebCore::::replace):
+ * bindings/generic/GenericBinding.h:
+ (WebCore::completeURL):
+ * bindings/js/JSBinding.h: Added.
+ * bindings/js/JSBindingsAllInOne.cpp:
+ * bindings/js/JSDOMBinding.cpp:
+ (WebCore::shouldAllowNavigation):
+ (WebCore::toLexicalFrame):
+ (WebCore::toDynamicFrame):
+ (WebCore::processingUserGesture):
+ (WebCore::completeURL):
+ * bindings/js/JSLocationCustom.cpp:
+ (WebCore::navigateIfAllowed):
+ (WebCore::JSLocation::replace):
+ * bindings/js/specialization/JSBindingState.cpp: Added.
+ (WebCore::::getActiveFrame):
+ (WebCore::::getFirstFrame):
+ (WebCore::::processingUserGesture):
+ (WebCore::::allowsAccessFromFrame):
+ * bindings/js/specialization/JSBindingState.h: Added.
+ * bindings/v8/V8Binding.h:
+ * bindings/v8/V8Utilities.cpp:
+ (WebCore::completeURL):
+ (WebCore::navigateIfAllowed):
+ * bindings/v8/custom/V8LocationCustom.cpp:
+ (WebCore::V8Location::replaceCallback):
+ * bindings/v8/specialization/V8BindingState.cpp:
+ (WebCore::::allowsAccessFromFrame):
+ * bindings/v8/specialization/V8BindingState.h:
+
+2010-09-09 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Apply :invalid CSS class to <input type=number> with an unacceptable value
+ https://bugs.webkit.org/show_bug.cgi?id=45376
+
+ Apply :invalid CSS class to <input type=number> elements with an
+ unacceptable value in order to tell users that a value is not
+ valid.
+
+ Introducing Element::hasUnaccceptableValue(), and CSSStyleSelector
+ applies :invalid to not only elements with !isValidFormControlElement()
+ but also elements with hasUnaccceptableValue().
+
+ HTMLInputElement and RenderTextControlSingleLine need some changes
+ to update style and to avoid updating renderer value during style
+ update.
+
+ Test: fast/forms/input-number-unacceptable-style.html
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+ * dom/Element.h:
+ (WebCore::Element::hasUnacceptableValue):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::handleBlurEvent):
+ (WebCore::HTMLInputElement::hasUnacceptableValue):
+ * html/HTMLInputElement.h:
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::subtreeHasChanged):
+ (WebCore::RenderTextControlSingleLine::updateFromElement):
+
+2010-09-09 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ <input type=number> should not have an invalid number as its value
+ https://bugs.webkit.org/show_bug.cgi?id=43973
+
+ This change implements the value sanitization algorithm for
+ type=number, and remove validity.typeMismatch support for
+ type=number in order to improve HTML5 conformance.
+
+ HTMLInputElement::value for type=number always has a valid number
+ string or an empty string. However, the input field for it, a
+ RenderTextControlSingleLine, can have a non-number string. For
+ example, '-' is a non-number string, but a user needs to type
+ '-'. So, the string in the input field has never been committed to
+ HTMLInputElement until the string becomes a valid number string.
+
+ This change is also a preparation of supporting localized
+ numbers. A localized string in the input field would not be
+ matched with HTMLInputElement::value.
+
+ Test: fast/forms/input-number-commit-valid-only.html
+
+ * dom/InputElement.h: Add isAcceptableValue()
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::handleBlurEvent):
+ Set formControlValueMatchesRenderer false to clean an invalid value in the renderer.
+ (WebCore::HTMLInputElement::isAcceptableValue):
+ (WebCore::HTMLInputElement::sanitizeValue):
+ * html/HTMLInputElement.h:
+ * html/ValidityState.cpp:
+ (WebCore::ValidityState::typeMismatch): Always returns false for type=number.
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::subtreeHasChanged):
+ * wml/WMLInputElement.h:
+ (WebCore::WMLInputElement::isAcceptableValue):
+
+2010-09-09 Tony Gentilcore <tonyg@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Support <script async> as specified by HTML5
+ https://bugs.webkit.org/show_bug.cgi?id=45310
+
+ Tests: fast/dom/HTMLScriptElement/async-inline-script.html
+ fast/dom/HTMLScriptElement/async-onbeforeload.html
+ fast/dom/HTMLScriptElement/async-write.html
+ http/tests/misc/async-and-defer-script.html
+ http/tests/misc/script-async.html
+
+ * dom/AsyncScriptRunner.cpp:
+ (WebCore::AsyncScriptRunner::AsyncScriptRunner):
+ (WebCore::AsyncScriptRunner::~AsyncScriptRunner):
+ (WebCore::AsyncScriptRunner::executeScriptSoon): Increment the delay count when a task to execute scripts is queued up.
+ (WebCore::AsyncScriptRunner::timerFired): decrementLoadEventDelayCount handles calling checkCompleted().
+ * dom/AsyncScriptRunner.h:
+ (WebCore::AsyncScriptRunner::create):
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ * dom/ScriptElement.cpp:
+ (WebCore::ScriptElement::insertedIntoDocument): Treats async scripts just like a dynamically inserted script element rather than a parser inserted one.
+ * html/parser/HTMLScriptRunner.cpp:
+ (WebCore::HTMLScriptRunner::runScript):
+
+2010-09-09 Alexey Marinichev <amarinichev@chromium.org>
+
+ Reviewed by James Robinson.
+
+ [chromium] Disable subpixel rendering in Linux when GPU compositor is active
+ https://bugs.webkit.org/show_bug.cgi?id=45087
+
+ This extends windows-only logic to chromium linux as well.
+
+ * platform/graphics/chromium/ContentLayerChromium.cpp:
+ (WebCore::ContentLayerChromium::updateContents):
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::adjustTextRenderMode): Added a check to see if the compositor is active.
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::setRootLayerCanvasSize):
+ * platform/graphics/chromium/VideoLayerChromium.cpp:
+ (WebCore::VideoLayerChromium::updateContents):
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::ImageBuffer):
+ (WebCore::ImageBuffer::clip):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ Made setDrawingToImageBuffer and isDrawingToImageBuffer available to
+ Linux; removed all #if OS(WINDOWS) || OS(LINUX).
+ (WebCore::PlatformContextSkia::State::State):
+ (WebCore::PlatformContextSkia::PlatformContextSkia):
+ (WebCore::PlatformContextSkia::isDrawingToImageBuffer):
+ (WebCore::PlatformContextSkia::save):
+ (WebCore::PlatformContextSkia::beginLayerClippedToImage):
+ (WebCore::PlatformContextSkia::restore):
+ (WebCore::PlatformContextSkia::applyClipFromImage):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2010-09-09 Kinuko Yasuda <kinuko@chromium.org>
+
+ Unreviewed, Windows build fix.
+
+ * WebCore.vcproj/WebCore.vcproj:
+
+2010-09-09 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Jian Li.
+
+ [FileSystem] Add File and FileWriter accessor methods in FileEntry
+ https://bugs.webkit.org/show_bug.cgi?id=45440
+
+ Adding file() and createWrite() methods in FileEntry.
+ http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#the-fileentry-interface
+
+ No new tests; this patch doesn't have implementation yet.
+
+ * CMakeLists.txt:
+ * DerivedSources.cpp:
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pri:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * fileapi/FileEntry.cpp:
+ (WebCore::FileEntry::createWriter): Added.
+ (WebCore::FileEntry::file): Added.
+ * fileapi/FileEntry.h:
+ * fileapi/FileEntry.idl:
+ * fileapi/FileCallback.h: Added.
+ * fileapi/FileCallback.idl: Added.
+ * fileapi/FileWriterCallback.h: Added.
+ * fileapi/FileWriterCallback.idl: Added.
+
+2010-09-09 Yuzo Fujishima <yuzo@google.com>
+
+ Reviewed by Darin Adler.
+
+ Fix for Bug 24742 - CSS tokenizer allows color in 6 hex digit notation to be followed by the next token without separation
+ Stop checking in the flex definition the number of hexadecimal digits for a hex color.
+ Instead, rely on the checking in Color::parseHexColor().
+ The resultant grammar is actually more close to the one in http://www.w3.org/TR/CSS21/grammar.html .
+
+ https://bugs.webkit.org/show_bug.cgi?id=24742
+
+ Test: fast/css/invalid-hex-color.html
+
+ * css/tokenizer.flex:
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add AudioSourceNode files
+ https://bugs.webkit.org/show_bug.cgi?id=45010
+
+ No new tests since audio API is not yet implemented.
+
+ * webaudio/AudioSourceNode.h: Added.
+ (WebCore::AudioSourceNode::AudioSourceNode):
+ * webaudio/AudioSourceNode.idl: Added.
+
+2010-09-09 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Don't call deleteTexture on a texture attached to an FBO that is not currently bound
+ https://bugs.webkit.org/show_bug.cgi?id=45504
+
+ The OpenGL semantics for glDeleteTextures() are that if one of the specified texture is attached
+ to the currently bound FBO, that FBO's color attachment is removed. However, if the specified
+ texture is attached to a non-current FBO then OpenGL states explicitly that that FBO's color
+ attachment is not cleared and that the texture stays alive even though its ID is no longer
+ valid to use. This is not the behavior we want in DrawingBuffer - we actually want the
+ texture to be immediately deleted. This patch makes sure the DrawingBuffer's FBO is bound
+ before deleting its color attachment texture.
+
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBuffer::~DrawingBuffer):
+ (WebCore::DrawingBuffer::reset):
+
+2010-09-09 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Chromium mac build should exclude all Skia files in platform/graphics/skia/, not just some
+ https://bugs.webkit.org/show_bug.cgi?id=45516
+
+ This excludes platform/graphics/skia/*Skia.(h|cpp) by pattern instead of individual files.
+ None of these files should be compiled into the Chromium mac build and the old file list had
+ both omissions and stale entries.
+
+ * WebCore.gyp/WebCore.gyp:
+
+2010-09-09 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, rolling out r67145.
+ http://trac.webkit.org/changeset/67145
+ https://bugs.webkit.org/show_bug.cgi?id=45431
+
+ broke editing/inserting/5994480-2.html on Chromium Linux
+
+ * css/CSSStyleSelector.h:
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::StyleChange::init):
+ (WebCore::StyleChange::extractTextStyles):
+ (WebCore::ApplyStyleCommand::removeImplicitlyStyledElement):
+
+2010-09-09 Dumitru Daniliuc <dumi@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Removing an obsolete comment.
+ https://bugs.webkit.org/show_bug.cgi?id=40112
+
+ * bindings/generic/ActiveDOMCallback.cpp:
+
+2010-09-09 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Clear only the uploaded portion of the software backing store when in mixed mode
+ https://bugs.webkit.org/show_bug.cgi?id=45503
+
+ This clears out only the dirty region of the software backing store when uploading results
+ to hardware rather than clearing out the entire software backing store. This is a significant
+ performance improvement when the dirty rects are small relative to the whole canvas.
+
+ This also implements the non-swizzle path of copySubRect() using memcpy() to copy the rows, which
+ is another respectable performance increase.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ * platform/graphics/gpu/Texture.cpp:
+ (WebCore::copySubRect):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::prepareForSoftwareDraw):
+ (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
+ (WebCore::PlatformContextSkia::readbackHardwareToSoftware):
+
+2010-09-09 Kenneth Russell <kbr@google.com>
+
+ Reviewed by James Robinson.
+
+ Add math utilities for cubic curve processing
+ https://bugs.webkit.org/show_bug.cgi?id=45251
+
+ Adding mathematic utilities needed for the GPU accelerated path
+ rendering algorithm from GPU Gems 3. No tests yet; will be tested
+ in conjunction with later code.
+
+ * platform/graphics/gpu/LoopBlinnMathUtils.cpp: Added.
+ (WebCore::LoopBlinnMathUtils::roundToZero):
+ (WebCore::LoopBlinnMathUtils::approxEqual):
+ (WebCore::LoopBlinnMathUtils::linesIntersect):
+ (WebCore::LoopBlinnMathUtils::pointInTriangle):
+ (WebCore::LoopBlinnMathUtils::trianglesOverlap):
+ (WebCore::LoopBlinnMathUtils::chopCubicAt):
+ (WebCore::LoopBlinnMathUtils::xRayCrossesLine):
+ (WebCore::LoopBlinnMathUtils::numXRayCrossingsForCubic):
+ * platform/graphics/gpu/LoopBlinnMathUtils.h: Added.
+
+2010-09-09 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Dumitru Daniliuc.
+
+ Add Entry.getMetadata for FileSystem API
+ https://bugs.webkit.org/show_bug.cgi?id=45403
+
+ Add getMetadata to Entry.idl (I had missed to include this
+ in my previous Entry.idl patch.)
+
+ Also make some minor cleanups and nits fixes.
+
+ No new tests; layout test is going be added later.
+
+ * fileapi/DOMFileSystem.cpp: Bug fix.
+ * fileapi/MetadataCallback.h: Nits fix.
+ * fileapi/Entry.idl: Added getMetadata.
+ * fileapi/ErrorCallback.h: Nits fix.
+
+2010-09-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ REGRESSION: applying new font size causes font-size outside selection to change
+ https://bugs.webkit.org/show_bug.cgi?id=45026
+
+ The regression was caused by removeImplicitlyStyledElement not converting font size to CSS value properly.
+ Namely, it was treating font size as a pixel value for font-size property. Fixed this by adding fontSizeToCSSValue
+ which uses HTMLFontElement::cssValueFromFontSizeNumber and deployed it in removeImplicitlyStyledElement
+
+ Also fixed a bug in StyleChange::extractTextStyles that it ignores font-size property when the values were
+ relative terms such as x-small and -webkit-xxx-large. And replaced the logic to convert from pixel font size
+ to legacy font size by CSSStyleSelector::legacyFontSize.
+
+ Test: editing/style/push-down-font-styles.html
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::StyleChange::extractTextStyles): Fixed a bug. See above.
+ (WebCore::stringToCSSValue): Converts string to CSSValue.
+ (WebCore::fontSizeToCSSValue): Converts font size number (String) to CSSPrimitiveValue.
+ (WebCore::ApplyStyleCommand::removeImplicitlyStyledElement): Calls stringToCSSValue and fontSizeToCSSValue.
+ * css/CSSStyleSelector.h: Made fontSizeForKeyword public.
+
+2010-09-09 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r67126.
+ http://trac.webkit.org/changeset/67126
+ https://bugs.webkit.org/show_bug.cgi?id=45510
+
+ broke chromium mac compile, it also uses PlatformContextSkia
+ (Requested by jamesr on #webkit).
+
+ * platform/graphics/chromium/ContentLayerChromium.cpp:
+ (WebCore::ContentLayerChromium::updateContents):
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::adjustTextRenderMode):
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::setRootLayerCanvasSize):
+ * platform/graphics/chromium/VideoLayerChromium.cpp:
+ (WebCore::VideoLayerChromium::updateContents):
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::ImageBuffer):
+ (WebCore::ImageBuffer::clip):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::State::State):
+ (WebCore::PlatformContextSkia::PlatformContextSkia):
+ (WebCore::PlatformContextSkia::save):
+ (WebCore::PlatformContextSkia::restore):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2010-09-09 Simon Fraser <simon.fraser@apple.com>
+
+ Attempt to fix Qt build.
+
+ * WebCore.pro:
+
+2010-09-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45509
+ <rdar://problem/8142166> REGRESSION: WebView setDrawsBackground:NO no
+ longer works without setBackgroundColor:clearColor
+
+ r61215 caused RenderView to paint the viewport background when the
+ document element's renderer is known to not fill opaquely paint
+ the entire viewport, i.e. more often than it did before.
+
+ This exposed a latent, long-standing bug which was introduced
+ in r14638 (the RenderCanvas -> RenderView rename), where a call
+ to view()->isTransparent() was not converted to frameView()->isTransparent(),
+ yet happened to still compile because of RenderObject::isTransparent().
+
+ This resulted in us painting the viewport background, even when
+ WebView clients explicitly said that they wanted a transparent
+ WebView.
+
+ Fixed by calling frameView()->isTransparent(), as intended.
+
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::paintBoxDecorations):
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ audio engine: add Biquad files
+ https://bugs.webkit.org/show_bug.cgi?id=44795
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/Biquad.cpp: Added.
+ (WebCore::Biquad::Biquad):
+ (WebCore::Biquad::process):
+ (WebCore::Biquad::processFast):
+ (WebCore::Biquad::processSliceFast):
+ (WebCore::Biquad::reset):
+ (WebCore::Biquad::setLowpassParams):
+ (WebCore::Biquad::setHighpassParams):
+ (WebCore::Biquad::setLowShelfParams):
+ (WebCore::Biquad::setZeroPolePairs):
+ (WebCore::Biquad::setAllpassPole):
+ * platform/audio/Biquad.h: Added.
+ (WebCore::Biquad::~Biquad):
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add AudioBuffer files
+ https://bugs.webkit.org/show_bug.cgi?id=45003
+
+ No new tests since audio API is not yet implemented.
+
+ * webaudio/AudioBuffer.cpp: Added.
+ (WebCore::AudioBuffer::create):
+ (WebCore::AudioBuffer::createFromAudioFileData):
+ (WebCore::AudioBuffer::AudioBuffer):
+ (WebCore::AudioBuffer::releaseMemory):
+ (WebCore::AudioBuffer::getChannelData):
+ (WebCore::AudioBuffer::zero):
+ * webaudio/AudioBuffer.h: Added.
+ (WebCore::AudioBuffer::length):
+ (WebCore::AudioBuffer::duration):
+ (WebCore::AudioBuffer::sampleRate):
+ (WebCore::AudioBuffer::numberOfChannels):
+ (WebCore::AudioBuffer::gain):
+ (WebCore::AudioBuffer::setGain):
+ * webaudio/AudioBuffer.idl: Added.
+
+2010-09-09 Alexey Marinichev <amarinichev@chromium.org>
+
+ Reviewed by James Robinson.
+
+ [chromium] Disable subpixel rendering in Linux when GPU compositor is active
+ https://bugs.webkit.org/show_bug.cgi?id=45087
+
+ Covered by all tests that activate the compositor and contain text.
+
+ * platform/graphics/chromium/ContentLayerChromium.cpp:
+ (WebCore::ContentLayerChromium::updateContents):
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::adjustTextRenderMode): Added a check to see if the compositor is active.
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::setRootLayerCanvasSize):
+ * platform/graphics/chromium/VideoLayerChromium.cpp:
+ (WebCore::VideoLayerChromium::updateContents):
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::ImageBuffer):
+ (WebCore::ImageBuffer::clip):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ Made setDrawingToImageBuffer and isDrawingToImageBuffer available to
+ Linux; removed all #if OS(WINDOWS) || OS(LINUX).
+ (WebCore::PlatformContextSkia::State::State):
+ (WebCore::PlatformContextSkia::PlatformContextSkia):
+ (WebCore::PlatformContextSkia::isDrawingToImageBuffer):
+ (WebCore::PlatformContextSkia::save):
+ (WebCore::PlatformContextSkia::beginLayerClippedToImage):
+ (WebCore::PlatformContextSkia::restore):
+ (WebCore::PlatformContextSkia::applyClipFromImage):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2010-09-09 Simon Fraser <simon.fraser@apple.com>
+
+ Fix windows build by adding missing file.
+
+ * platform/graphics/win/LocalWindowsContext.h: Added.
+ (WebCore::LocalWindowsContext::LocalWindowsContext):
+ (WebCore::LocalWindowsContext::~LocalWindowsContext):
+ (WebCore::LocalWindowsContext::hdc):
+
+2010-09-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Scrollbars fail to render in composited iframes.
+ https://bugs.webkit.org/show_bug.cgi?id=45335
+
+ Add a stack-based class, LocalWindowsContext, which does a getWindowsContext/
+ releaseWindowsContext automatically.
+
+ Also fix getWindowsContext to create a bitmap context if mayCreateBitmap
+ is true, and if the context's HDC is null. This fixes scrollbar rendering
+ in compositing layers.
+
+ Use LocalWindowsContext in places where we had bare getWindowsContext() calls.
+
+ * platform/graphics/win/LocalWindowsContext.h
+ (WebCore::LocalWindowsContext::LocalWindowsContext):
+ (WebCore::LocalWindowsContext::~LocalWindowsContext):
+ (WebCore::LocalWindowsContext::hdc):
+ * platform/graphics/win/GraphicsContextCGWin.cpp:
+ (WebCore::GraphicsContext::releaseWindowsContext):
+ * platform/graphics/win/GraphicsContextWin.cpp:
+ (WebCore::GraphicsContext::getWindowsContext):
+ * platform/graphics/win/IconWin.cpp:
+ (WebCore::Icon::paint):
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
+ (WebCore::MediaPlayerPrivate::paint):
+ * platform/win/ScrollbarThemeWin.cpp:
+ (WebCore::ScrollbarThemeWin::paintTrackPiece):
+ (WebCore::ScrollbarThemeWin::paintButton):
+ * plugins/win/PluginViewWin.cpp:
+ (WebCore::PluginView::paintWindowedPluginIntoContext):
+ (WebCore::PluginView::paint):
+ * rendering/RenderThemeWin.cpp:
+ (WebCore::drawControl):
+
+2010-09-09 Vincent Scheib <scheib@chromium.org>
+
+ Reviewed by James Robinson.
+
+ [Chromium] Minimize uploads in canvas 2d mixed mode rendering
+ https://bugs.webkit.org/show_bug.cgi?id=45476
+
+ No new tests - change is for performance, logic fixes only apparent when running hardware acceleration.
+
+ - Enumeration values fixed, "CavasWillDraw" -> "CanvasDidDraw".
+ - markDirtyRect() plumbed through GraphicsContext to PlatformContextSkia.
+ - Texture::updateSubRect() added to allow uploading only a dirty rect.
+ - Logic fix in ImageBuffer::draw(), caused canvas to canvas copies to be incorrect.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::setAllAttributesToDefault):
+ (WebCore::CanvasRenderingContext2D::strokeRect):
+ (WebCore::CanvasRenderingContext2D::drawImage):
+ (WebCore::CanvasRenderingContext2D::didDraw):
+ - Logic fix for drawingContext()->markDirtyRect() call.
+ (WebCore::CanvasRenderingContext2D::putImageData):
+ (WebCore::CanvasRenderingContext2D::drawTextInternal):
+ - Logic fix for calls to "didDraw()", use peer method first.
+ * html/canvas/CanvasRenderingContext2D.h:
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::drawImageBuffer):
+ (WebCore::GraphicsContext::markDirtyRect):
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/gpu/Texture.cpp:
+ (WebCore::Texture::create):
+ (WebCore::Texture::load):
+ (WebCore::Texture::updateSubRect):
+ * platform/graphics/gpu/Texture.h:
+ * platform/graphics/gpu/TilingData.h:
+ (WebCore::TilingData::borderTexels):
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::clipConvexPolygon):
+ (WebCore::GraphicsContext::markDirtyRect):
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::draw):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::State::cloneInheritedProperties):
+ (WebCore::PlatformContextSkia::drawRect):
+ (WebCore::PlatformContextSkia::setFillColor):
+ (WebCore::PlatformContextSkia::setStrokeColor):
+ (WebCore::PlatformContextSkia::markDirtyRect):
+ (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ Just executing the plan that has long been described in Frame.h
+ to move a bunch of functions to Editor.
+
+ * WebCore.exp.in: Updated.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::fontForSelection):
+ (WebCore::Editor::textDirectionForSelection):
+ (WebCore::Editor::applyStyle):
+ (WebCore::Editor::selectionStartHasStyle):
+ (WebCore::Editor::selectionHasStyle):
+ (WebCore::Editor::selectionStartCSSPropertyValue):
+ (WebCore::Editor::Editor):
+ (WebCore::Editor::cut):
+ (WebCore::Editor::copy):
+ (WebCore::Editor::ignoreSpelling):
+ (WebCore::Editor::learnSpelling):
+ (WebCore::Editor::isSelectionMisspelled):
+ (WebCore::Editor::guessesForMisspelledSelection):
+ (WebCore::Editor::selectedText):
+ (WebCore::Editor::firstRectForRange):
+ (WebCore::Editor::shouldChangeSelection):
+ (WebCore::Editor::computeAndSetTypingStyle):
+ (WebCore::Editor::selectionComputedStyle):
+ (WebCore::Editor::textFieldDidBeginEditing):
+ (WebCore::Editor::textFieldDidEndEditing):
+ (WebCore::Editor::textDidChangeInTextField):
+ (WebCore::Editor::doTextFieldCommandFromEvent):
+ (WebCore::Editor::textWillBeDeletedInTextField):
+ (WebCore::Editor::textDidChangeInTextArea):
+ (WebCore::Editor::applyEditingStyleToBodyElement):
+ (WebCore::Editor::applyEditingStyleToElement):
+ (WebCore::Editor::styleForSelectionStart):
+ (WebCore::Editor::findString):
+ (WebCore::Editor::countMatchesForText):
+ (WebCore::Editor::setMarkedTextMatchesAreHighlighted):
+ (WebCore::Editor::respondToChangedSelection):
+ * editing/Editor.h:
+ * editing/mac/EditorMac.mm:
+ (WebCore::Editor::fontAttributesForSelectionStart):
+ (WebCore::Editor::baseWritingDirectionForSelectionStart):
+ Moved functions here.
+
+ * page/Frame.cpp:
+ (WebCore::Frame::Frame):
+ (WebCore::Frame::shouldChangeSelection):
+ * page/Frame.h:
+ * page/mac/FrameMac.mm:
+ Moved functions out of here.
+
+ * dom/InputElement.cpp:
+ (WebCore::InputElement::dispatchBlurEvent):
+ (WebCore::InputElement::aboutToUnload):
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::DeleteSelectionCommand::doApply):
+ * editing/EditorCommand.cpp:
+ (WebCore::executeToggleStyleInList):
+ (WebCore::executeDeleteToMark):
+ (WebCore::executeFindString):
+ (WebCore::executeSelectToMark):
+ (WebCore::executeSetMark):
+ (WebCore::executeSwapWithMark):
+ (WebCore::enabledVisibleSelectionAndMark):
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::setSelection):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::defaultEventHandler):
+ * page/ContextMenuController.cpp:
+ (WebCore::ContextMenuController::contextMenuItemSelected):
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::find):
+ * page/DragController.cpp:
+ (WebCore::DragController::startDrag):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::sendContextMenuEventForKey):
+ * page/Page.cpp:
+ (WebCore::Page::findString):
+ (WebCore::Page::markAllMatchesForText):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paintTextMatchMarker):
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::subtreeHasChanged):
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::subtreeHasChanged):
+ Changed call sites to use editor().
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add AudioDSPKernelProcessor files
+ https://bugs.webkit.org/show_bug.cgi?id=45211
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/AudioDSPKernelProcessor.cpp: Added.
+ (WebCore::AudioDSPKernelProcessor::AudioDSPKernelProcessor):
+ (WebCore::AudioDSPKernelProcessor::initialize):
+ (WebCore::AudioDSPKernelProcessor::uninitialize):
+ (WebCore::AudioDSPKernelProcessor::process):
+ (WebCore::AudioDSPKernelProcessor::reset):
+ (WebCore::AudioDSPKernelProcessor::setNumberOfChannels):
+ * platform/audio/AudioDSPKernelProcessor.h: Added.
+ (WebCore::AudioDSPKernelProcessor::numberOfChannels):
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add setRange() and zeroRange() methods to TypedArrayBase
+ https://bugs.webkit.org/show_bug.cgi?id=45419
+
+ No new tests since adding new methods which are not yet called anywhere.
+
+ * html/canvas/ArrayBufferView.cpp:
+ (WebCore::ArrayBufferView::setRangeImpl):
+ (WebCore::ArrayBufferView::zeroRangeImpl):
+ * html/canvas/ArrayBufferView.h:
+ * html/canvas/TypedArrayBase.h:
+ (WebCore::TypedArrayBase::setRange):
+ (WebCore::TypedArrayBase::zeroRange):
+
+2010-09-09 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] always send an Accept header
+
+ Ensure QtWebKit always sends an Accept header. This is required
+ for compatibility with sites that expect the header in requests
+ for subresources.
+
+ See https://bugs.webkit.org/show_bug.cgi?id=33242 for more.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45458
+
+ * platform/network/qt/ResourceRequestQt.cpp:
+ (WebCore::ResourceRequest::toNetworkRequest):
+
+2010-09-09 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Chris Marrin.
+
+ Add media element logging
+ https://bugs.webkit.org/show_bug.cgi?id=45469
+
+ Add logging at interesting points in a media element's lifecycle.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::urlForLogging):
+ (WebCore::boolString):
+ (WebCore::HTMLMediaElement::scheduleEvent):
+ (WebCore::HTMLMediaElement::asyncEventTimerFired):
+ (WebCore::HTMLMediaElement::canPlayType):
+ (WebCore::HTMLMediaElement::load):
+ (WebCore::HTMLMediaElement::prepareForLoad):
+ (WebCore::HTMLMediaElement::selectMediaResource):
+ (WebCore::HTMLMediaElement::loadResource):
+ (WebCore::HTMLMediaElement::isSafeToLoadURL):
+ (WebCore::HTMLMediaElement::waitForSourceChange):
+ (WebCore::HTMLMediaElement::noneSupported):
+ (WebCore::HTMLMediaElement::mediaEngineError):
+ (WebCore::HTMLMediaElement::cancelPendingEventsAndCallbacks):
+ (WebCore::HTMLMediaElement::setNetworkState):
+ (WebCore::HTMLMediaElement::setReadyState):
+ (WebCore::HTMLMediaElement::rewind):
+ (WebCore::HTMLMediaElement::returnToRealtime):
+ (WebCore::HTMLMediaElement::addPlayedRange):
+ (WebCore::HTMLMediaElement::seek):
+ (WebCore::HTMLMediaElement::finishSeek):
+ (WebCore::HTMLMediaElement::setPlaybackRate):
+ (WebCore::HTMLMediaElement::setWebkitPreservesPitch):
+ (WebCore::HTMLMediaElement::setAutoplay):
+ (WebCore::HTMLMediaElement::setPreload):
+ (WebCore::HTMLMediaElement::play):
+ (WebCore::HTMLMediaElement::playInternal):
+ (WebCore::HTMLMediaElement::pause):
+ (WebCore::HTMLMediaElement::pauseInternal):
+ (WebCore::HTMLMediaElement::setLoop):
+ (WebCore::HTMLMediaElement::setControls):
+ (WebCore::HTMLMediaElement::setVolume):
+ (WebCore::HTMLMediaElement::setMuted):
+ (WebCore::HTMLMediaElement::togglePlayState):
+ (WebCore::HTMLMediaElement::beginScrubbing):
+ (WebCore::HTMLMediaElement::endScrubbing):
+ (WebCore::HTMLMediaElement::selectNextSourceChild):
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerVolumeChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerMuteChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerDurationChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerRateChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerPlaybackStateChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerSawUnsupportedTracks):
+ (WebCore::HTMLMediaElement::mediaPlayerSizeChanged):
+ (WebCore::HTMLMediaElement::mediaPlayerRenderingModeChanged):
+ (WebCore::HTMLMediaElement::updatePlayState):
+ (WebCore::HTMLMediaElement::userCancelledLoad):
+ (WebCore::HTMLMediaElement::stop):
+ (WebCore::HTMLMediaElement::suspend):
+ (WebCore::HTMLMediaElement::resume):
+ (WebCore::HTMLMediaElement::hasPendingActivity):
+ (WebCore::HTMLMediaElement::mediaVolumeDidChange):
+ (WebCore::HTMLMediaElement::createMediaPlayerProxy):
+ (WebCore::HTMLMediaElement::enterFullscreen):
+ (WebCore::HTMLMediaElement::exitFullscreen):
+ (WebCore::HTMLMediaElement::setClosedCaptionsVisible):
+ (WebCore::HTMLMediaElement::mediaCanStart):
+ (WebCore::HTMLMediaElement::setShouldDelayLoadEvent):
+
+2010-09-09 Anton Muhin <antonm@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [v8] bypass caches when query memory usage from post GC and in crash handler.
+ https://bugs.webkit.org/show_bug.cgi?id=45036
+
+ Second part of the whole change: now use API introduced in
+ http://trac.webkit.org/changeset/66818 and now backed by Chromium.
+
+ * bindings/v8/V8DOMWindowShell.cpp:
+ (WebCore::reportFatalErrorInV8):
+ * bindings/v8/V8GCController.cpp:
+ (WebCore::V8GCController::gcEpilogue):
+
+2010-09-09 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by James Robinson.
+
+ Make sure skia is not Chromium specific
+ https://bugs.webkit.org/show_bug.cgi?id=39672
+
+ FontCustomPlatformData is not Chromium-specific. Move it to platform/skia.
+
+ No new tests because this is pure refactoring.
+
+ * WebCore.gyp/WebCore.gyp:
+ * WebCore.gypi:
+ * platform/graphics/chromium/FontCustomPlatformData.cpp: Removed.
+ * platform/graphics/chromium/FontCustomPlatformData.h: Removed.
+ * platform/graphics/skia/FontCustomPlatformData.cpp: Copied from WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp.
+ * platform/graphics/skia/FontCustomPlatformData.h: Copied from WebCore/platform/graphics/chromium/FontCustomPlatformData.h.
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Chris Fleizach.
+
+ Add AudioDSPKernel files
+ https://bugs.webkit.org/show_bug.cgi?id=45319
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/AudioDSPKernel.h: Added.
+ (WebCore::AudioDSPKernel::AudioDSPKernel):
+ (WebCore::AudioDSPKernel::~AudioDSPKernel):
+ (WebCore::AudioDSPKernel::sampleRate):
+ (WebCore::AudioDSPKernel::nyquist):
+ (WebCore::AudioDSPKernel::processor):
+
+2010-09-09 Chris Rogers <crogers@google.com>
+
+ Reviewed by Chris Fleizach.
+
+ Add AudioProcessor.h
+ https://bugs.webkit.org/show_bug.cgi?id=45206
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/AudioProcessor.h: Added.
+ (WebCore::AudioProcessor::AudioProcessor):
+ (WebCore::AudioProcessor::~AudioProcessor):
+ (WebCore::AudioProcessor::isInitialized):
+ (WebCore::AudioProcessor::sampleRate):
+
+2010-09-09 Kenneth Russell <kbr@google.com>
+
+ Reviewed by James Robinson.
+
+ Add cubic texture coordinate computation
+ https://bugs.webkit.org/show_bug.cgi?id=45250
+
+ Adding the texture coordinate computation for cubic curves per the
+ GPU Gems 3 chapter. No tests yet; will be tested in conjunction
+ with later code.
+
+ * platform/graphics/gpu/LoopBlinnConstants.h: Added.
+ * platform/graphics/gpu/LoopBlinnTextureCoords.cpp: Added.
+ (WebCore::LoopBlinnTextureCoords::compute):
+ * platform/graphics/gpu/LoopBlinnTextureCoords.h: Added.
+ (WebCore::LoopBlinnTextureCoords::Result::Result):
+ (WebCore::LoopBlinnTextureCoords::LoopBlinnTextureCoords):
+
+2010-09-09 Kenneth Russell <kbr@google.com>
+
+ Reviewed by James Robinson.
+
+ Add cubic curve classifier
+ https://bugs.webkit.org/show_bug.cgi?id=45249
+
+ Adding the cubic curve classification algorithm per the GPU Gems 3
+ chapter. No tests yet; will be tested in conjunction with later code.
+
+ * platform/graphics/gpu/LoopBlinnClassifier.cpp: Added.
+ (WebCore::LoopBlinnClassifier::classify):
+ * platform/graphics/gpu/LoopBlinnClassifier.h: Added.
+ (WebCore::LoopBlinnClassifier::Result::Result):
+ (WebCore::LoopBlinnClassifier::LoopBlinnClassifier):
+
+2010-09-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ QueryCommandValue('FontSize') returns pixel values instead of IE font numbers
+ https://bugs.webkit.org/show_bug.cgi?id=21033
+
+ Modified selectionStartCSSPropertyValue to return legacy font size instead of pixel size.
+ To implement the conversion between pixel font size and legacy font size,
+ added legacyFontSize to CSSStyleSelector with a helper static function findNearestLegacyFontSize.
+
+ Fixed a bug in selectionComputedStyle where it obtains the style of the previous editing position
+ even when the selection is a range. This change revealed a crash in executeToggleStyleInList,
+ which was also fixed.
+
+ Test: editing/execCommand/query-font-size.html
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword): Corrected style.
+ (WebCore::CSSComputedStyleDeclaration::useFixedFontDefaultSize): Added.
+ * css/CSSComputedStyleDeclaration.h:
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::fontSizeForKeyword): Renamed fixed/monospace to shouldUseFixedDefaultSize.
+ (WebCore::findNearestLegacyFontSize): Added, a helper for legacyFontSize.
+ (WebCore::CSSStyleSelector::legacyFontSize): Added.
+ * css/CSSStyleSelector.h:
+ * editing/Editor.cpp:
+ (WebCore::Editor::selectionStartCSSPropertyValue): Added a conversion from pixel to legacy font size.
+ * editing/EditorCommand.cpp:
+ (WebCore::executeToggleStyleInList): Crash fix.
+ * page/Frame.cpp:
+ (WebCore::Frame::selectionComputedStyle): See above.
+
+2010-09-09 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Give WebKit clients a way to replace window.screen
+ to foil attempts to track users with it.
+
+ This allows clients to overload the values returned by the
+ Screen object through the JSC manipulation API (such as
+ QWebFrame::addToJavaScriptWindowObject() in Qt). Clients will
+ want to do this when they do not want to reveal too much
+ explicit information about the user's desktop configuration.
+
+ https://bugs.webkit.org/show_bug.cgi?id=41802
+
+ * page/DOMWindow.idl:
+
+2010-09-09 Kenneth Russell <kbr@google.com>
+
+ Reviewed by James Robinson.
+
+ Memory leak in red/black tree
+ https://bugs.webkit.org/show_bug.cgi?id=45472
+
+ Fixed memory leak in red/black tree where it was using operator
+ new directly to allocate its internal nodes rather than the arena
+ with which it was configured. Added allocateObject variant to
+ arena supporting single-argument constructors. Added test to
+ red/black tree unit tests to cover this functionality, and
+ refactored TrackedAllocator into helper file to share between
+ arena and red/black tree tests.
+
+ * platform/graphics/gpu/PODArena.h:
+ (WebCore::PODArena::allocateObject):
+ (WebCore::PODArena::allocateBase):
+ * platform/graphics/gpu/PODIntervalTree.h:
+ (WebCore::PODIntervalTree::PODIntervalTree):
+ * platform/graphics/gpu/PODRedBlackTree.h:
+ (WebCore::PODRedBlackTree::add):
+
+2010-09-09 Dean Jackson <dino@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Fill mode is broken with multiple keyframes
+ https://bugs.webkit.org/show_bug.cgi?id=41209
+
+ With a forward fill mode the animation would tick after
+ the end of the animation, causing the fractional
+ duration of the animation to wrap. This meant the last
+ style update would happen using the incorrect keyframes.
+ The solution was to put clamps in for the elapsed time
+ and current iteration count.
+
+ Tests: animations/fill-mode-missing-from-to-keyframes.html
+ animations/fill-mode-multiple-keyframes.html
+
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::fetchIntervalEndpointsForProperty):
+
+2010-09-09 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by David Kilzer.
+
+ AX: Support AccessibilityTextMarkers in DRT
+ https://bugs.webkit.org/show_bug.cgi?id=44778
+
+ Provide support in DRT for accessing and manipulating the text marker system that AX exposes.
+ This will allow future bug fixes in the text marker system to be adequately tested.
+
+ Tests: platform/mac/accessibility/element-for-text-marker.html
+ platform/mac/accessibility/text-marker-length.html
+
+ * accessibility/mac/AccessibilityObjectWrapper.mm:
+ (-[AccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+
+2010-09-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ REGRESSION(r58875-r59046): Scrollable content drawn in wrong layer with Flash 10.1
+ https://bugs.webkit.org/show_bug.cgi?id=40743
+
+ We can't do partial compositing layer updates on scrolling if we have to look
+ for overlap, because the overlap map needs to be populated by traversing the
+ compositing layer hierarchy from the root.
+
+ Test: compositing/layer-creation/scroll-partial-update.html
+
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateCompositingLayers):
+
+2010-09-09 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [GTK] testmimehandling falsely succeeds testing Ogg mime type
+ https://bugs.webkit.org/show_bug.cgi?id=45349
+
+ Advertize audio/x-vorbis+ogg so MediaDocuments loading local ogg
+ files work as well.
+
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::mimeTypeCache):
+
+2010-09-09 Adam Barth <abarth@webkit.org>
+
+ Move FTPDirectoryDocument, ImageDocument, MediaDocument, and
+ PluginDocument from WebCore/loader to WebCore/html. These classes are
+ subclasses of HTMLDocument. They don't belong in the loader. Further
+ cleanup patches to follow.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/FTPDirectoryDocument.cpp: Copied from WebCore/loader/FTPDirectoryDocument.cpp.
+ * html/FTPDirectoryDocument.h: Copied from WebCore/loader/FTPDirectoryDocument.h.
+ * html/ImageDocument.cpp: Copied from WebCore/loader/ImageDocument.cpp.
+ * html/ImageDocument.h: Copied from WebCore/loader/ImageDocument.h.
+ * html/MediaDocument.cpp: Copied from WebCore/loader/MediaDocument.cpp.
+ * html/MediaDocument.h: Copied from WebCore/loader/MediaDocument.h.
+ * html/PluginDocument.cpp: Copied from WebCore/loader/PluginDocument.cpp.
+ * html/PluginDocument.h: Copied from WebCore/loader/PluginDocument.h.
+ * loader/FTPDirectoryDocument.cpp: Removed.
+ * loader/FTPDirectoryDocument.h: Removed.
+ * loader/ImageDocument.cpp: Removed.
+ * loader/ImageDocument.h: Removed.
+ * loader/MediaDocument.cpp: Removed.
+ * loader/MediaDocument.h: Removed.
+ * loader/PluginDocument.cpp: Removed.
+ * loader/PluginDocument.h: Removed.
+
+2010-09-09 Andrey Kosyakov <caseq@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: use string representation of resource type in extension API
+ Fixed Resoruce.Type.toString() to handle Resource.Type.Media.
+ https://bugs.webkit.org/show_bug.cgi?id=45286
+
+ Test: inspector/extensions-resources.html
+
+ * English.lproj/localizedStrings.js: Added "media".
+ * inspector/front-end/ExtensionServer.js: Added webInspector.resources.Types. Return resource types as strings.
+ (WebInspector.ExtensionServer.prototype._convertResource):
+ (WebInspector.ExtensionServer.prototype._buildExtensionAPIInjectedScript):
+ * inspector/front-end/Resource.js: Added toUIString(), changed toString() to return locale-independent representation.
+ (WebInspector.Resource.Type.toUIString):
+ (WebInspector.Resource.Type.toString):
+
+2010-09-09 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Fixed incorrect Symbian scoping.
+
+ The missing install functionality is only true for mmp based systems.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45268
+
+ * WebCore.pro:
+
+2010-09-09 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Dirk Schulze.
+
+ [WML] Add a parameter to fix build break.
+ https://bugs.webkit.org/show_bug.cgi?id=45437
+
+ In WMLSelectElement.h, the setSelectedIndexByUser() needs to have one more parameter.
+ Because, parent class's setSelectedIndexByUser() has one more param.
+
+ * wml/WMLSelectElement.h:
+
+2010-09-09 Ryuan Choi <ryuan.choi@samsung.com>
+
+ Unreviewed attempt to fix EFL build after r67001.
+
+ [EFL] Regression (67001) Build break
+ https://bugs.webkit.org/show_bug.cgi?id=45422
+
+ * platform/efl/ScrollbarEfl.cpp:
+ (scrollbarEflEdjeMessage):
+
+2010-09-08 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Tony Chang.
+
+ MarkupAccumulator should be broken down into two classes
+ https://bugs.webkit.org/show_bug.cgi?id=44854
+
+ Extracted wrapWithNode, wrapWithStyleNode, stringValueForRange, renderedText, removeExteriorStyles,
+ shouldAnnotate, m_shouldAnnotate, and m_reversedPrecedingMarkup from MarkupAccumulator to create
+ StyledMarkupAccumulator in order to isolate annotation related code and prepending of text.
+
+ Isolating MarkupAccumulator as a separate class has two advantages:
+ 1. Isolated serialization code is easier to understand and easier to security-review.
+ 2. Embedder can use MarkupAccumulator to implement "Save as" feature.
+
+ Also made takeResults, appendText, and appendElement in MarkupAccumulator virtual to override in
+ StyledMarkupAccumulator because prepending text requires overriding takeResults, appendText needs
+ to append only rendered text when shouldAnnotate() is true, and appendElement requires a different
+ behavior when shouldAnnotate() is true or when called inside wrapWithNode with convertBlocksToInlines = true.
+
+ No new tests are added since this is a cleanup.
+
+ * editing/markup.cpp:
+ (WebCore::MarkupAccumulator::MarkupAccumulator): Removed shouldAnnotate from argument.
+ (WebCore::MarkupAccumulator::~MarkupAccumulator): Added.
+ (WebCore::StyledMarkupAccumulator::): Added.
+ (WebCore::StyledMarkupAccumulator::StyledMarkupAccumulator): Added.
+ (WebCore::StyledMarkupAccumulator::appendElement): Added to support annotation.
+ (WebCore::StyledMarkupAccumulator::shouldAnnotate): Moved from MarkupAccumulator.
+ (WebCore::MarkupAccumulator::appendStartTag): No longer takes convertBlocksToInlines and RangeFullySelectsNode.
+ (WebCore::StyledMarkupAccumulator::wrapWithStyleNode): Moved from MarkupAccumulator.
+ (WebCore::MarkupAccumulator::takeResults): No longer accumulates prepended text, and made virtual.
+ (WebCore::StyledMarkupAccumulator::takeResults): Added to support prepended text.
+ (WebCore::MarkupAccumulator::shouldAddNamespaceAttribute): Takes a reference to Attribute instead of a pointer.
+ (WebCore::MarkupAccumulator::entityMaskForText): Extracted from appendText.
+ (WebCore::MarkupAccumulator::appendText): No longer deals with annotation.
+ (WebCore::StyledMarkupAccumulator::appendText): Added to support annotation.
+ (WebCore::StyledMarkupAccumulator::stringValueForRange): Moved from MarkupAccumulator.
+ (WebCore::StyledMarkupAccumulator::renderedText): Moved from MarkupAccumulator.
+ (WebCore::MarkupAccumulator::appendElement): No longer deals with annotation.
+ (WebCore::StyledMarkupAccumulator::wrapWithNode): Moved from MarkupAccumulator.
+ (WebCore::StyledMarkupAccumulator::removeExteriorStyles): Moved from MarkupAccumulator.
+ (WebCore::MarkupAccumulator::appendOpenTag): Added.
+ (WebCore::MarkupAccumulator::appendCloseTag): Added.
+ (WebCore::MarkupAccumulator::appendAttribute): Added.
+ (WebCore::MarkupAccumulator::appendStartMarkup): No longer takes convertBlocksToInlines and RangeFullySelectsNode.
+ (WebCore::serializeNodes): Takes StyledMarkupAccumulator.
+ (WebCore::createMarkup): Range version uses StyledMarkupAccumulator and node version uses MarkupAccumulator.
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Not reviewed, layout test fix.
+
+ Fix flaky layout test results caused by not initializing members correctly.
+ https://bugs.webkit.org/show_bug.cgi?id=45411
+
+ * platform/ScrollAnimator.cpp:
+ (WebCore::ScrollAnimator::ScrollAnimator):
+ (WebCore::ScrollAnimator::~ScrollAnimator):
+ * platform/ScrollAnimator.h:
+
+2010-09-08 MORITA Hajime <morrita@google.com>
+
+ Reviewed by Tony Chang.
+
+ spelling underline gets lost on backspace
+ https://bugs.webkit.org/show_bug.cgi?id=41423
+
+ moveParagraphs() did make a DOM range by serializing source range
+ and deserializing it back, and markers are gone during the process.
+ This change marks that DOM range again.
+
+ Test: editing/spelling/spelling-backspace-between-lines.html
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::moveParagraphs):
+ * editing/Editor.cpp:
+ (WebCore::Editor::clearMisspellingsAndBadGrammar): Added.
+ (WebCore::Editor::markMisspellingsAndBadGrammar): Added.
+ * editing/Editor.h:
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ text/plain documents that start with \n trigger ASSERT
+ https://bugs.webkit.org/show_bug.cgi?id=45409
+
+ Because the TextDocumentParser uses a <pre> element to show the text,
+ it ran into a requirement from HTML5 to skip any initial \n character
+ tokens inside a <pre> element. We don't want the behavior for
+ TextDocuments, so I've loosened our ASSERTs and added a comment and a
+ test to document the correct behavior.
+
+ Test: fast/tokenizer/text-plain.html
+
+ * html/parser/HTMLTokenizer.cpp:
+ (WebCore::HTMLTokenizer::nextToken):
+
+2010-09-08 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Always do 2d canvas clearRect() in hardware
+ https://bugs.webkit.org/show_bug.cgi?id=45415
+
+ r67003 forced Canvas 2d's clearRect() to happen in software if a gradient/shadow/etc was
+ active. This is subtly wrong for mixed mode rendering since it results in only the
+ software backing store being cleared and not the hardware. This forces clearRect() to
+ happen in hardware. Since we upload mixed mode results before doing any hardware draw
+ this means we always clear everything.
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::clearRect):
+
+2010-09-08 Dean Jackson <dino@apple.com>
+
+ Unreviewed attempt to fix the Mac builds.
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseAnimationTimingFunction):
+
+2010-09-08 Dean Jackson <dino@apple.com>
+
+ Unreviewed attempt to fix QT build.
+
+ * platform/graphics/qt/GraphicsLayerQt.cpp:
+ (WebCore::solveStepsFunction):
+ (WebCore::applyTimingFunction):
+
+2010-09-08 Dean Jackson <dino@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Implement steps() timing function for animations
+ https://bugs.webkit.org/show_bug.cgi?id=44541
+
+ Tests: animations/timing-functions.html
+ transitions/steps-timing-function.html
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::getTimingFunctionValue):
+ - when creating computed style we now test what
+ type of timing function it being used
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseCubicBezierTimingFunctionValue):
+ - rename this method from parseTimingFunctionValue
+ (WebCore::CSSParser::parseAnimationTimingFunction):
+ - support parsing the steps() function
+ * css/CSSParser.h:
+ - method rename
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::mapAnimationTimingFunction):
+ - handle 'step-start' and 'step-end' identifiers. Also
+ now use ::create when constructing objects
+ * css/CSSTimingFunctionValue.cpp:
+ (WebCore::CSSLinearTimingFunctionValue::cssText):
+ (WebCore::CSSCubicBezierTimingFunctionValue::cssText):
+ (WebCore::CSSStepsTimingFunctionValue::cssText):
+ - new text output for computed style. We now produce
+ the text 'linear' when appropriate.
+ * css/CSSTimingFunctionValue.h:
+ (WebCore::CSSTimingFunctionValue::isLinearTimingFunctionValue):
+ (WebCore::CSSTimingFunctionValue::isCubicBezierTimingFunctionValue):
+ (WebCore::CSSTimingFunctionValue::isStepsTimingFunctionValue):
+ (WebCore::CSSTimingFunctionValue::CSSTimingFunctionValue):
+ (WebCore::CSSTimingFunctionValue::isTimingFunctionValue):
+ (WebCore::CSSLinearTimingFunctionValue::create):
+ (WebCore::CSSLinearTimingFunctionValue::isLinearTimingFunctionValue):
+ (WebCore::CSSLinearTimingFunctionValue::CSSLinearTimingFunctionValue):
+ (WebCore::CSSCubicBezierTimingFunctionValue::create):
+ (WebCore::CSSCubicBezierTimingFunctionValue::isCubicBezierTimingFunctionValue):
+ (WebCore::CSSCubicBezierTimingFunctionValue::CSSCubicBezierTimingFunctionValue):
+ (WebCore::CSSStepsTimingFunctionValue::create):
+ (WebCore::CSSStepsTimingFunctionValue::numberOfSteps):
+ (WebCore::CSSStepsTimingFunctionValue::stepAtStart):
+ (WebCore::CSSStepsTimingFunctionValue::isStepsTimingFunctionValue):
+ (WebCore::CSSStepsTimingFunctionValue::CSSStepsTimingFunctionValue):
+ - CSSTimingFunction is now a pure virtual ref-counted base class, with
+ subclasses for each of the three supported timing functions.
+ * css/CSSValueKeywords.in:
+ - new keywords step-start and step-end
+ * page/animation/AnimationBase.cpp:
+ (WebCore::solveStepsFunction):
+ - produces the output value from a stepping function
+ (WebCore::AnimationBase::progress):
+ - now has to switch based on timing function type
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::fetchIntervalEndpointsForProperty):
+ - use ref-counted access
+ * platform/animation/Animation.cpp:
+ (WebCore::Animation::animationsMatch):
+ - change timing function comparison for operator==
+ * platform/animation/Animation.h:
+ (WebCore::Animation::timingFunction):
+ (WebCore::Animation::setTimingFunction):
+ (WebCore::Animation::initialAnimationTimingFunction):
+ - move to ref-counted timing function class
+ * platform/animation/TimingFunction.h:
+ (WebCore::TimingFunction::~TimingFunction):
+ (WebCore::TimingFunction::isLinearTimingFunction):
+ (WebCore::TimingFunction::isCubicBezierTimingFunction):
+ (WebCore::TimingFunction::isStepsTimingFunction):
+ (WebCore::TimingFunction::TimingFunction):
+ (WebCore::LinearTimingFunction::create):
+ (WebCore::LinearTimingFunction::~LinearTimingFunction):
+ (WebCore::LinearTimingFunction::operator==):
+ (WebCore::LinearTimingFunction::LinearTimingFunction):
+ (WebCore::CubicBezierTimingFunction::create):
+ (WebCore::CubicBezierTimingFunction::~CubicBezierTimingFunction):
+ (WebCore::CubicBezierTimingFunction::operator==):
+ (WebCore::CubicBezierTimingFunction::CubicBezierTimingFunction):
+ (WebCore::StepsTimingFunction::create):
+ (WebCore::StepsTimingFunction::~StepsTimingFunction):
+ (WebCore::StepsTimingFunction::operator==):
+ (WebCore::StepsTimingFunction::numberOfSteps):
+ (WebCore::StepsTimingFunction::stepAtStart):
+ (WebCore::StepsTimingFunction::StepsTimingFunction):
+ - TimingFunction is now a ref-counted pure virtual base class,
+ with three subclasses representing the types of timing functions
+ that are supported.
+ * platform/graphics/GraphicsLayer.h:
+ (WebCore::AnimationValue::AnimationValue):
+ (WebCore::FloatAnimationValue::FloatAnimationValue):
+ (WebCore::TransformAnimationValue::TransformAnimationValue):
+ - use PassRefPtr in function parameters
+ * platform/graphics/qt/GraphicsLayerQt.cpp:
+ (WebCore::solveStepsFunction):
+ (WebCore::applyTimingFunction):
+ (WebCore::AnimationQt::AnimationQt):
+ (WebCore::AnimationQt::updateCurrentTime):
+ - implement the timing function switch for QT
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::getCAMediaTimingFunction):
+ - update for new timing function interface
+ (WebCore::animationHasStepsTimingFunction):
+ - new method to make sure animations with steps() functions
+ never try to execute in Core Animation
+ (WebCore::GraphicsLayerCA::addAnimation):
+ - test for steps() timing function
+ (WebCore::GraphicsLayerCA::timingFunctionForAnimationValue):
+ * rendering/style/RenderStyleConstants.h:
+ - remove old RenderStyle enum for timing function types
+
+2010-09-08 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed trivial fix after r66960.
+
+ * WebCore.pro: loader/TextDocument.h renamed to html/TextDocument.h
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ move-during-parse-parent.html crashes
+ https://bugs.webkit.org/show_bug.cgi?id=45210
+
+ When inserting elements into the tree, they need to be associated with
+ their parent's document, not the document for which the parser is
+ running. These two are different when the parent has been moved to a
+ different document during parsing.
+
+ Test: fast/parser/move-during-parsing.html
+
+ * html/parser/HTMLConstructionSite.cpp:
+ (WebCore::HTMLConstructionSite::insertComment):
+ (WebCore::HTMLConstructionSite::insertCommentOnHTMLHtmlElement):
+ (WebCore::HTMLConstructionSite::insertScriptElement):
+ (WebCore::HTMLConstructionSite::insertTextNode):
+ (WebCore::HTMLConstructionSite::createElement):
+ (WebCore::HTMLConstructionSite::createHTMLElement):
+
+2010-09-08 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ Fix increases required alignment of target type warning on ARM
+ https://bugs.webkit.org/show_bug.cgi?id=45301
+
+ No new tests needed.
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneDeserializer::readLittleEndian):
+ (WebCore::CloneDeserializer::readString):
+ * plugins/PluginDatabase.cpp:
+ (WebCore::readTime):
+
+2010-09-08 Antonio Gomes <agomes@rim.com>
+
+ Reviewed by Daniel Bates.
+
+ Make FocusController::focusedOrMainFrame method const
+ https://bugs.webkit.org/show_bug.cgi?id=45406
+
+ No new tests.
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::focusedOrMainFrame):
+ * page/FocusController.h:
+
+2010-09-08 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Fix a problem in createCanonicalUUIDString that causes the last digit
+ missing on Linux.
+ https://bugs.webkit.org/show_bug.cgi?id=45412
+
+ This is caused by not including the final null character into the count
+ that is provided to fgets.
+
+ This is covered by the existing test: send-form-data-with-sliced-file.html.
+
+ * platform/UUID.cpp:
+ (WebCore::createCanonicalUUIDString):
+
+2010-09-08 Nico Weber <thakis@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ chromium/mac: Fix overrelease in ImageLayerChromium
+ https://bugs.webkit.org/show_bug.cgi?id=45360
+
+ Only release colorSpace if we created it.
+
+ * platform/graphics/chromium/ImageLayerChromium.cpp:
+ (WebCore::ImageLayerChromium::updateContents):
+
+2010-09-08 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ Remove some unnecessary duplicate calls to string functions
+
+ https://bugs.webkit.org/show_bug.cgi?id=45314
+
+ * platform/network/curl/ResourceHandleManager.cpp:
+ (WebCore::parseDataUrl):
+ * websockets/WebSocketChannel.cpp:
+ (WebCore::WebSocketChannel::send):
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Not reviewed, fallout from http://trac.webkit.org/changeset/67001
+
+ Fix compile failures and add svn:eol-style on two new files.
+
+ * platform/ScrollAnimator.h: Added property svn:eol-style.
+ * platform/ScrollAnimatorWin.cpp: Added property svn:eol-style.
+ * platform/win/PopupMenuWin.cpp: Fix compile errors.
+ (WebCore::PopupMenuWin::scrollToRevealSelection):
+ (WebCore::PopupMenuWin::scrollSize):
+
+2010-09-08 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Force canvas 2d draw calls to happen in software if a gradient, pattern, shadow, or clip are active
+ https://bugs.webkit.org/show_bug.cgi?id=45405
+
+ This forces all draw calls to happen in software instead of hardware if there is a fill pattern, gradient,
+ shadow, or clip applied; at least until we can handle these in hardware. Otherwise the pattern/gradient/etc
+ is completely ignored by the hardware drawing routine and we render incorrectly.
+
+ The test is slightly convervative - for example it will force drawImage() calls to happen in software if a
+ fill gradient is set even though it's irrelevant. This doesn't seem to be an issue in practice and we
+ can tighten the checks later if needed.
+
+ Tested by fast/canvas/canvas-incremental-repaint.html.
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::canvasClip):
+ (WebCore::GraphicsContext::fillRect):
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::draw):
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::BitmapImage::draw):
+ (WebCore::BitmapImageSingleFrameSkia::draw):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::State::State):
+ (WebCore::PlatformContextSkia::canvasClipPath):
+ (WebCore::PlatformContextSkia::canAccelerate):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Reviewed by David Hyatt.
+
+ Add smooth scrolling framework, and a Windows implementation.
+ https://bugs.webkit.org/show_bug.cgi?id=32356
+
+ * CMakeLists.txt: Add ScrollAnimator.
+ * GNUmakefile.am: Add ScrollAnimator.
+ * WebCore.gyp/WebCore.gyp: Add Windows ScrollAnimator.
+ * WebCore.gypi: Add ScrollAnimator.
+ * WebCore.pro: Add ScrollAnimator.
+ * WebCore.vcproj/WebCore.vcproj: Add ScrollAnimator.
+ * WebCore.xcodeproj/project.pbxproj: Add ScrollAnimator.
+ * platform/ScrollAnimator.cpp: Added base implementation that does no animation.
+ (WebCore::ScrollAnimator::create):
+ (WebCore::ScrollAnimator::scroll):
+ (WebCore::ScrollAnimator::setScrollPositionAndStopAnimation):
+ * platform/ScrollAnimator.h: Added base implementation that does no animation.
+ (WebCore::ScrollAnimator::ScrollAnimator):
+ (WebCore::ScrollAnimator::~ScrollAnimator):
+ * platform/ScrollAnimatorWin.cpp: Added Windows subclass that animates scrolls.
+ (WebCore::ScrollAnimator::create):
+ (WebCore::ScrollAnimatorWin::PerAxisData::PerAxisData):
+ (WebCore::ScrollAnimatorWin::ScrollAnimatorWin):
+ (WebCore::ScrollAnimatorWin::~ScrollAnimatorWin):
+ (WebCore::ScrollAnimatorWin::scroll):
+ (WebCore::ScrollAnimatorWin::setScrollPositionAndStopAnimation):
+ (WebCore::ScrollAnimatorWin::accelerationTime):
+ (WebCore::ScrollAnimatorWin::animationTimerFired):
+ (WebCore::ScrollAnimatorWin::stopAnimationTimerIfNeeded):
+ (WebCore::ScrollAnimatorWin::animateScroll):
+ * platform/ScrollAnimatorWin.h: Added Windows subclass that animates scrolls.
+ * platform/ScrollView.cpp: Implement new ScrollbarClient functions. Allow wheel scrolls to be animated.
+ (WebCore::ScrollView::scrollSize):
+ (WebCore::ScrollView::setScrollOffsetFromAnimation):
+ (WebCore::ScrollView::updateScrollbars):
+ (WebCore::ScrollView::wheelEvent):
+ * platform/ScrollView.h: Implement new ScrollbarClient functions.
+ * platform/Scrollbar.cpp: Allow ScrollAnimator to handle scrolls if present.
+ (WebCore::Scrollbar::setValue):
+ (WebCore::Scrollbar::scroll):
+ (WebCore::Scrollbar::moveThumb):
+ (WebCore::Scrollbar::setCurrentPos):
+ (WebCore::Scrollbar::mouseMoved):
+ * platform/Scrollbar.h:
+ * platform/ScrollbarClient.cpp: Added to avoid having to make ScrollAnimator.h non-private.
+ (WebCore::ScrollbarClient::ScrollbarClient):
+ (WebCore::ScrollbarClient::~ScrollbarClient):
+ (WebCore::ScrollbarClient::scroll):
+ (WebCore::ScrollbarClient::setScrollPositionAndStopAnimation):
+ * platform/ScrollbarClient.h: Add hooks for ScrollAnimator.
+ (WebCore::ScrollbarClient::convertFromScrollbarToContainingView):
+ (WebCore::ScrollbarClient::convertFromContainingViewToScrollbar):
+ * platform/gtk/MainFrameScrollbarGtk.cpp:
+ (MainFrameScrollbarGtk::gtkValueChanged):
+ * platform/qt/ScrollbarQt.cpp: Use scroll() in preference to setValue().
+ (WebCore::Scrollbar::contextMenu):
+ * platform/win/PopupMenuWin.cpp: Implement new ScrollbarClient functions.
+ (WebCore::PopupMenuWin::scrollSize):
+ (WebCore::PopupMenuWin::setScrollOffsetFromAnimation):
+ * platform/win/PopupMenuWin.h: Implement new ScrollbarClient functions.
+ * rendering/RenderDataGrid.cpp: Implement new ScrollbarClient functions.
+ (WebCore::RenderDataGrid::scrollSize):
+ (WebCore::RenderDataGrid::setScrollOffsetFromAnimation):
+ * rendering/RenderDataGrid.h: Implement new ScrollbarClient functions.
+ * rendering/RenderLayer.cpp: Implement new ScrollbarClient functions.
+ (WebCore::RenderLayer::scrollToOffset):
+ (WebCore::RenderLayer::scrollSize):
+ (WebCore::RenderLayer::setScrollOffsetFromAnimation):
+ (WebCore::RenderLayer::updateScrollInfoAfterLayout):
+ * rendering/RenderLayer.h: Implement new ScrollbarClient functions.
+ * rendering/RenderListBox.cpp: Implement new ScrollbarClient functions.
+ (WebCore::RenderListBox::scrollToRevealElementAtListIndex):
+ (WebCore::RenderListBox::scrollSize):
+ (WebCore::RenderListBox::setScrollOffsetFromAnimation):
+ (WebCore::RenderListBox::setScrollTop):
+ * rendering/RenderListBox.h: Implement new ScrollbarClient functions.
+
+2010-09-08 Ryosuke Niwa <rniwa@webkit.org>
+
+ Reviewed by Tony Chang.
+
+ applyInlineStyleToRange needs cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=45008
+
+ Removed rangeIsEmpty and extracted the entire loop into applyInlineStyleToNodeRange.
+ applyInlineStyleToRange is now a wrapper that fixes range and passes it on to applyInlineStyleToNodeRange.
+
+ No new tests are added since this is a cleanup.
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::applyInlineStyleToRange): Cleaned up.
+ (WebCore::ApplyStyleCommand::applyInlineStyleToNodeRange): Extracted from applyInlineStyleToRange.
+ * editing/ApplyStyleCommand.h:
+
+2010-09-08 Andy Estes <aestes@apple.com>
+
+ Rubber-stamped by Darin Adler.
+
+ Incorporate additional feedback from
+ https://bugs.webkit.org/show_bug.cgi?id=45364.
+
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::parametersForPlugin): Rename urlParam to
+ urlParameter.
+ * loader/SubframeLoader.h: Add argument names to the definition of
+ SubframeLoader::resourceWillUsePlugin().
+
+2010-09-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ Support SerializedScriptValue in WebKit2
+ https://bugs.webkit.org/show_bug.cgi?id=45340
+
+ Add a new constructor that allows WebKit2 to create a SerializedScriptValue
+ directly from serialized data.
+
+ * WebCore.exp.in:
+ * bindings/js/SerializedScriptValue.h:
+ (WebCore::SerializedScriptValue::adopt):
+ (WebCore::SerializedScriptValue::data):
+
+2010-09-08 Andy Estes <aestes@apple.com>
+
+ Reviewed by Eric Carlson.
+
+ Fallback content should be rendered when an <object> doesn't specify a
+ data, type or classid attribute.
+ https://bugs.webkit.org/show_bug.cgi?id=45364
+ <rdar://problem/8375816>
+
+ HTML5 says that if no data or type attribute is specified on an <object>,
+ fallback content should be rendered. However, WebKit has traditionally
+ supported specifying a URL and MIME type in <param> elements.
+
+ To more closely match the spec while maintaining compatibility with
+ content that relied on our old behavior, we will continue to load
+ a resource specified by <param> elements if we can determine a priori
+ that it will be handled by a plug-in.
+
+ If we can't make this determination, and the <object> element has no
+ "data" or "type" attribute, the <param> elements will be ignored and
+ fallback content will be rendered. Otherwise, there is no change in
+ behavior.
+
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::parametersForPlugin): If an empty url is
+ passed to this function and a <param> exists that specifies a url that
+ references a plug-in resource, set it to url, making it the url that
+ will be loaded by the <object> element.
+ (WebCore::HTMLObjectElement::updateWidget): If no type attribute was
+ specified, but there is a classid attribute, try to map the classid to
+ a MIME type. This needs to be done before calling
+ HTMLObjectElement::parametersForPlugin().
+ * loader/SubframeLoader.cpp:
+ (WebCore::SubframeLoader::resourceWillUsePlugin): Make a public method
+ that determines if a resource will load a plug-in based on its url and
+ MIME type. This is equivalent to calling
+ SubframeLoader::shouldUsePlugin(), but does not burden the caller with
+ the details of fallback content.
+ * loader/SubframeLoader.h:
+
+2010-09-08 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: add breakpoints to source frame after content is loaded.
+ https://bugs.webkit.org/show_bug.cgi?id=43056
+
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel.prototype._resourceLoadingFinished):
+ (WebInspector.ScriptsPanel.prototype._showScriptOrResource):
+ * inspector/front-end/SourceView.js:
+ (WebInspector.SourceView.prototype._contentLoaded):
+
+2010-09-08 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Canvas: Remove unnecessary null-check of canvas() in getImageData()
+ https://bugs.webkit.org/show_bug.cgi?id=45394
+
+ canvas() is already dereferenced earlier in the function so there is
+ no use in checking it for null later.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::getImageData):
+
+2010-09-08 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Eric Carlson.
+
+ [GStreamer] cache media duration in READY instead of PLAYING
+ https://bugs.webkit.org/show_bug.cgi?id=39053
+
+ New cacheDuration private method used to in updateStates() and
+ durationChanged().
+
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivateGStreamer::updateStates):
+ (WebCore::MediaPlayerPrivateGStreamer::cacheDuration):
+ (WebCore::MediaPlayerPrivateGStreamer::durationChanged):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+
+2010-09-08 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Need a WebSocket implementation
+ https://bugs.webkit.org/show_bug.cgi?id=45197
+
+ Add a GIO-based WebSocket implementation. This does not yet support
+ SSL sockets or proxies, but these should be possible to add as support
+ arrives in GLib/GIO for them.
+
+ * platform/network/soup/SocketStreamHandle.h:
+ * platform/network/soup/SocketStreamHandleSoup.cpp: Add a GIO-based WebSocket implementation.
+ (WebCore::isActiveHandle): Added.
+ (WebCore::deactivateHandle): Added.
+ (WebCore::SocketStreamHandle::SocketStreamHandle): Filled out stub.
+ (WebCore::SocketStreamHandle::~SocketStreamHandle): Ditto.
+ (WebCore::SocketStreamHandle::connected): Added.
+ (WebCore::SocketStreamHandle::readBytes): Added.
+ (WebCore::SocketStreamHandle::writeReady): Added.
+ (WebCore::SocketStreamHandle::platformSend): Filled out stub.
+ (WebCore::SocketStreamHandle::platformClose): Filled out stub.
+ (WebCore::SocketStreamHandle::beginWaitingForSocketWritability): Added.
+ (WebCore::SocketStreamHandle::stopWaitingForSocketWritability):
+ (WebCore::connectedCallback): Added.
+ (WebCore::readReadyCallback): Added.
+ (WebCore::writeReadyCallback): Added.
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Dirk Schulze.
+
+ [Cairo] Actually use the antialias parameter of GraphicsContext::clipConvexPolygon
+ https://bugs.webkit.org/show_bug.cgi?id=45355
+
+ r63864 added an additional boolean parameter to GraphicsContext::clipConvexPolygon,
+ which determines whether or not to render the render the clip with anti-aliasing
+ or not. The Cairo implementation now uses that parameter to determine the argument
+ to pass to cairo_set_antialias(...) when clipping.
+
+ Test: This is tested by many tests in fast/borders.
+
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::clipConvexPolygon): Actually use the boolean antialias parameter.
+
+2010-09-08 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [EFL] Support to enable HTML5's Video based on gstreamer in WebKit-EFL
+ https://bugs.webkit.org/show_bug.cgi?id=44098
+
+ To support video of HTML5 based on gstreamer, add files regarding gstreamer to
+ CMakeListsEfl.txt.
+
+ * CMakeListsEfl.txt:
+
+2010-09-08 Jan E Hanssen <jhanssen@sencha.com>
+
+ Reviewed by Dirk Schulze.
+
+ [Qt] PathQt should use the QPainterPath functionality for calculations
+ https://bugs.webkit.org/show_bug.cgi?id=43837
+
+ Change PathQt to use the built-in functionality of QPainterPath for
+ calculating length(), pointAtLength() and normalAngleAtLength().
+
+ * platform/graphics/Path.cpp:
+ * platform/graphics/qt/PathQt.cpp:
+ (WebCore::Path::length):
+ (WebCore::Path::pointAtLength):
+ (WebCore::Path::normalAngleAtLength):
+
+2010-09-08 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Dirk Schulze.
+
+ [WML] Remove create() function in WMLTaskElement because of build break.
+ https://bugs.webkit.org/show_bug.cgi?id=44954
+
+ Remove create() function in WMLTaskElement.cpp because of build breaks.
+
+ * wml/WMLTaskElement.cpp:
+ * wml/WMLTaskElement.h:
+
+2010-09-08 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Dirk Schulze.
+
+ [WML] Add create functions to WML.
+ https://bugs.webkit.org/show_bug.cgi?id=44950
+
+ There are missing definitions of create function in WML area.
+ So, there are build breaks when enabling WML. The create functions and the construction
+ are added. In addition, a style error and duplicated adoptRef usage are fixed.
+
+ * wml/WMLDocument.h:
+ (WebCore::WMLDocument::create):
+ * wml/WMLFormControlElement.h:
+ * wml/WMLIntrinsicEvent.cpp:
+ (WebCore::WMLIntrinsicEvent::WMLIntrinsicEvent):
+ * wml/WMLIntrinsicEvent.h:
+
+2010-09-08 Nico Weber <thakis@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ chromium/mac: Fix crash with compositor due to missing current NSGraphicsContext
+ https://bugs.webkit.org/show_bug.cgi?id=45354
+
+ * platform/graphics/chromium/ContentLayerChromium.cpp:
+ (WebCore::ContentLayerChromium::updateContents): Set a current local context.
+
+2010-09-08 Justin Schuh <jschuh@chromium.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ NULL deref when use target is reset, then set to display:none
+ https://bugs.webkit.org/show_bug.cgi?id=45345
+
+ Move the NULL check on shadowRoot earlier in SVGUseElement::recalcStyle
+
+ Test: svg/custom/use-display-none.svg
+
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::recalcStyle):
+
+2010-08-30 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Handle MediaQueryExp memory management exclusively with smart pointers
+ https://bugs.webkit.org/show_bug.cgi?id=44874
+
+ Gace MediaQueryExp a create function, made the constructor private, and followed
+ the implications. The one tricky bit was using a non-copying sort to sort
+ the Vector<OwnPtr<MediaQueryExp> > in the MediaQuery constructor.
+
+ * ForwardingHeaders/wtf/NonCopyingSort.h: Added.
+ * css/CSSGrammar.y:
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::~CSSParser):
+ (WebCore::CSSParser::createFloatingMediaQueryExp):
+ (WebCore::CSSParser::createFloatingMediaQueryExpList):
+ (WebCore::CSSParser::sinkFloatingMediaQueryExpList):
+ (WebCore::CSSParser::createFloatingMediaQuery):
+ * css/CSSParser.h:
+ * css/MediaList.cpp:
+ * css/MediaQuery.cpp:
+ (WebCore::expressionCompare):
+ (WebCore::MediaQuery::MediaQuery):
+ (WebCore::MediaQuery::~MediaQuery):
+ * css/MediaQuery.h:
+ (WebCore::MediaQuery::expressions):
+ * css/MediaQueryEvaluator.cpp:
+ (WebCore::MediaQueryEvaluator::eval):
+ * css/MediaQueryExp.h:
+ (WebCore::MediaQueryExp::create):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ Remove unused member variable from DecodedDocumentParser
+ https://bugs.webkit.org/show_bug.cgi?id=45379
+
+ This member variable isn't used because of the recent split of
+ TextDocumentParser and TextViewSourceParser.
+
+ * dom/DecodedDataDocumentParser.cpp:
+ (WebCore::DecodedDataDocumentParser::DecodedDataDocumentParser):
+ * dom/DecodedDataDocumentParser.h:
+ * dom/ScriptableDocumentParser.cpp:
+ (WebCore::ScriptableDocumentParser::ScriptableDocumentParser):
+ * dom/ScriptableDocumentParser.h:
+
+2010-09-08 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ Fix warning in rendering/RenderBlock.cpp.
+ https://bugs.webkit.org/show_bug.cgi?id=45373
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::hitTestColumns): Suggested parentheses added around && within ||
+
+2010-09-08 Mario Sanchez Prada <msanchez@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [Gtk] A list item's number/bullet should not be a child of that list item
+ https://bugs.webkit.org/show_bug.cgi?id=45190
+
+ Ignore list markers and prefix them to the text for the item
+
+ * accessibility/gtk/AccessibilityObjectAtk.cpp:
+ (WebCore::AccessibilityObject::accessibilityPlatformIncludesObject):
+ Make list markers ignore accessibility for the GTK port.
+ * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
+ (webkit_accessible_text_get_text): Prefix the text of a marker
+ along with the accessible text for its list item's AtkObject
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Rubber-stamped by Eric Seidel.
+
+ Rename DocLoader to CachedResourceLoader because that's what it does.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSCursorImageValue.cpp:
+ (WebCore::CSSCursorImageValue::cachedImage):
+ * css/CSSCursorImageValue.h:
+ * css/CSSFontFaceSource.cpp:
+ (WebCore::CSSFontFaceSource::getFontData):
+ * css/CSSFontSelector.cpp:
+ (WebCore::CSSFontSelector::cachedResourceLoader):
+ (WebCore::CSSFontSelector::addFontFaceRule):
+ * css/CSSFontSelector.h:
+ * css/CSSImageValue.cpp:
+ (WebCore::CSSImageValue::cachedImage):
+ * css/CSSImageValue.h:
+ * css/CSSImportRule.cpp:
+ (WebCore::CSSImportRule::insertedIntoParent):
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::loadPendingImages):
+ * css/CSSStyleSheet.h:
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::~Document):
+ (WebCore::Document::implicitClose):
+ * dom/Document.h:
+ (WebCore::Document::cachedResourceLoader):
+ * dom/ProcessingInstruction.cpp:
+ (WebCore::ProcessingInstruction::checkStyleSheet):
+ * dom/ScriptElement.cpp:
+ (WebCore::ScriptElementData::requestScript):
+ * dom/XMLDocumentParser.cpp:
+ * dom/XMLDocumentParser.h:
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::matchFunc):
+ (WebCore::shouldAllowExternalLoad):
+ (WebCore::openFunc):
+ (WebCore::XMLDocumentParser::doWrite):
+ (WebCore::XMLDocumentParser::endElementNs):
+ (WebCore::XMLDocumentParser::initializeParserContext):
+ (WebCore::XMLDocumentParser::doEnd):
+ (WebCore::xmlDocPtrForString):
+ * dom/XMLDocumentParserQt.cpp:
+ (WebCore::XMLDocumentParser::parseEndElement):
+ * dom/XMLDocumentParserScope.cpp:
+ (WebCore::XMLDocumentParserScope::XMLDocumentParserScope):
+ (WebCore::XMLDocumentParserScope::~XMLDocumentParserScope):
+ * dom/XMLDocumentParserScope.h:
+ * editing/Editor.cpp:
+ (WebCore::Editor::paste):
+ * editing/mac/EditorMac.mm:
+ (WebCore::Editor::paste):
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::process):
+ * html/parser/CSSPreloadScanner.cpp:
+ (WebCore::CSSPreloadScanner::emitRule):
+ * html/parser/HTMLPreloadScanner.cpp:
+ (WebCore::HTMLNames::PreloadTask::preload):
+ * html/parser/HTMLScriptRunner.cpp:
+ (WebCore::HTMLScriptRunner::requestPendingScript):
+ * inspector/InspectorResource.cpp:
+ (WebCore::InspectorResource::cachedResource):
+ * loader/Cache.cpp:
+ (WebCore::Cache::requestResource):
+ (WebCore::Cache::requestUserCSSStyleSheet):
+ (WebCore::Cache::revalidateResource):
+ (WebCore::Cache::addCachedResourceLoader):
+ (WebCore::Cache::removeCachedResourceLoader):
+ * loader/Cache.h:
+ * loader/CachedCSSStyleSheet.h:
+ * loader/CachedFont.cpp:
+ (WebCore::CachedFont::load):
+ (WebCore::CachedFont::beginLoadIfNeeded):
+ * loader/CachedFont.h:
+ * loader/CachedImage.cpp:
+ (WebCore::CachedImage::load):
+ (WebCore::CachedImage::maximumDecodedImageSize):
+ * loader/CachedImage.h:
+ * loader/CachedResource.cpp:
+ (WebCore::CachedResource::CachedResource):
+ (WebCore::CachedResource::~CachedResource):
+ (WebCore::CachedResource::load):
+ * loader/CachedResource.h:
+ (WebCore::CachedResource::load):
+ (WebCore::CachedResource::setCachedResourceLoader):
+ * loader/CachedResourceLoader.cpp: Copied from WebCore/loader/DocLoader.cpp.
+ (WebCore::CachedResourceLoader::CachedResourceLoader):
+ (WebCore::CachedResourceLoader::~CachedResourceLoader):
+ (WebCore::CachedResourceLoader::frame):
+ (WebCore::CachedResourceLoader::checkForReload):
+ (WebCore::CachedResourceLoader::requestImage):
+ (WebCore::CachedResourceLoader::requestFont):
+ (WebCore::CachedResourceLoader::requestCSSStyleSheet):
+ (WebCore::CachedResourceLoader::requestUserCSSStyleSheet):
+ (WebCore::CachedResourceLoader::requestScript):
+ (WebCore::CachedResourceLoader::requestXSLStyleSheet):
+ (WebCore::CachedResourceLoader::requestLinkPrefetch):
+ (WebCore::CachedResourceLoader::canRequest):
+ (WebCore::CachedResourceLoader::requestResource):
+ (WebCore::CachedResourceLoader::printAccessDeniedMessage):
+ (WebCore::CachedResourceLoader::setAutoLoadImages):
+ (WebCore::CachedResourceLoader::cachePolicy):
+ (WebCore::CachedResourceLoader::removeCachedResource):
+ (WebCore::CachedResourceLoader::setLoadInProgress):
+ (WebCore::CachedResourceLoader::checkCacheObjectStatus):
+ (WebCore::CachedResourceLoader::incrementRequestCount):
+ (WebCore::CachedResourceLoader::decrementRequestCount):
+ (WebCore::CachedResourceLoader::requestCount):
+ (WebCore::CachedResourceLoader::preload):
+ (WebCore::CachedResourceLoader::checkForPendingPreloads):
+ (WebCore::CachedResourceLoader::requestPreload):
+ (WebCore::CachedResourceLoader::clearPreloads):
+ (WebCore::CachedResourceLoader::clearPendingPreloads):
+ (WebCore::CachedResourceLoader::printPreloadStats):
+ * loader/CachedResourceLoader.h: Copied from WebCore/loader/DocLoader.h.
+ * loader/CachedScript.h:
+ * loader/CachedXSLStyleSheet.h:
+ * loader/DocLoader.cpp: Removed.
+ * loader/DocLoader.h: Removed.
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::isLoadingInAPISense):
+ (WebCore::DocumentLoader::subresource):
+ (WebCore::DocumentLoader::getSubresources):
+ * loader/FrameLoader.cpp:
+ (WebCore::numRequests):
+ (WebCore::FrameLoader::stopLoading):
+ (WebCore::FrameLoader::didBeginDocument):
+ * loader/HistoryController.cpp:
+ (WebCore::HistoryController::createItem):
+ * loader/ImageLoader.cpp:
+ (WebCore::ImageLoader::updateFromElement):
+ * loader/Request.cpp:
+ (WebCore::Request::Request):
+ * loader/Request.h:
+ (WebCore::Request::cachedResourceLoader):
+ * loader/loader.cpp:
+ (WebCore::Loader::load):
+ (WebCore::Loader::cancelRequests):
+ (WebCore::Loader::Host::servePendingRequests):
+ (WebCore::Loader::Host::didFinishLoading):
+ (WebCore::Loader::Host::didFail):
+ (WebCore::Loader::Host::didReceiveResponse):
+ (WebCore::Loader::Host::cancelPendingRequests):
+ (WebCore::Loader::Host::cancelRequests):
+ * loader/loader.h:
+ * page/DragController.cpp:
+ (WebCore::DragController::concludeEditDrag):
+ * page/Frame.cpp:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::checkStopDelayingDeferredRepaints):
+ (WebCore::FrameView::updateDeferredRepaintDelay):
+ * page/Settings.cpp:
+ (WebCore::setLoadsImagesAutomaticallyInAllFrames):
+ * platform/android/TemporaryLinkStubs.cpp:
+ (WebCore::CheckCacheObjectStatus):
+ * platform/network/android/ResourceHandleAndroid.cpp:
+ (WebCore::ResourceHandle::start):
+ * platform/network/cf/ResourceHandleCFNet.cpp:
+ * platform/network/curl/ResourceHandleCurl.cpp:
+ * platform/network/mac/ResourceHandleMac.mm:
+ * platform/network/qt/ResourceHandleQt.cpp:
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ * platform/network/win/ResourceHandleWin.cpp:
+ * svg/SVGFEImageElement.cpp:
+ (WebCore::SVGFEImageElement::requestImageResource):
+ * svg/SVGFontFaceUriElement.cpp:
+ (WebCore::SVGFontFaceUriElement::loadFont):
+ * workers/Worker.cpp:
+ * xml/XSLImportRule.cpp:
+ (WebCore::XSLImportRule::loadSheet):
+ * xml/XSLStyleSheet.h:
+ * xml/XSLStyleSheetLibxslt.cpp:
+ (WebCore::XSLStyleSheet::cachedResourceLoader):
+ (WebCore::XSLStyleSheet::parseString):
+ * xml/XSLStyleSheetQt.cpp:
+ (WebCore::XSLStyleSheet::cachedResourceLoader):
+ * xml/XSLTProcessor.cpp:
+ * xml/XSLTProcessorLibxslt.cpp:
+ (WebCore::docLoaderFunc):
+ (WebCore::setXSLTLoadCallBack):
+ (WebCore::xmlDocPtrFromNode):
+ (WebCore::XSLTProcessor::transformToString):
+
+2010-09-06 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Eric Carlson.
+
+ Add mediaPlayerPlaybackStateChanged to MediaPlayerClient
+
+ https://bugs.webkit.org/show_bug.cgi?id=45263
+
+ The platform backend may change state, for example as a result
+ of an external plugin controlling the backend, so we need to
+ react to this situation by syncing up the WebCore state with the
+ platform backend.
+
+ We call playInternal()/pauseInternal() depending on the backend
+ state, to trigger the corresponding DOM events to match the state.
+
+ updatePlayState() is then refactored to take into account the
+ situation where the backend is already in the correct state but
+ WebCore is not, so that we update the playback progress timer
+ and set m_playing correctly.
+
+ updatePlayState() changes Should be covered by existing tests.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::mediaPlayerPlaybackStateChanged):
+ (WebCore::HTMLMediaElement::updatePlayState):
+ * html/HTMLMediaElement.h:
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::playbackStateChanged):
+ * platform/graphics/MediaPlayer.h:
+ (WebCore::MediaPlayerClient::mediaPlayerPlaybackStateChanged):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ TextDocument doesn't belong in WebCore/loader
+ https://bugs.webkit.org/show_bug.cgi?id=45346
+
+ TextDocument has nothing to do with loading. It turns out that it
+ should be in WebCore/html because TextDocument is actually a subclass
+ of HTMLDocument (in quirks mode, no less).
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/TextDocument.cpp: Renamed from WebCore/loader/TextDocument.cpp.
+ (WebCore::TextDocument::TextDocument):
+ (WebCore::TextDocument::createParser):
+ * html/TextDocument.h: Renamed from WebCore/loader/TextDocument.h.
+ (WebCore::TextDocument::create):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Create TextViewSourceParser
+ https://bugs.webkit.org/show_bug.cgi?id=45343
+
+ Rather than have the view source document set a flag on
+ HTMLViewSourceParser to indicate whether we're parsing a text document,
+ this patch creates a TextViewSourceParser for parsing text documents in
+ view-source mode. Like the TextDocumentParser, the
+ TextViewSourceParser implements this functionality by subclassing its
+ HTML counterpart.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/HTMLViewSourceDocument.cpp:
+ (WebCore::HTMLViewSourceDocument::createParser):
+ * html/parser/HTMLViewSourceParser.cpp:
+ * html/parser/HTMLViewSourceParser.h:
+ (WebCore::HTMLViewSourceParser::tokenizer):
+ * html/parser/TextViewSourceParser.cpp: Added.
+ (WebCore::TextViewSourceParser::TextViewSourceParser):
+ (WebCore::TextViewSourceParser::~TextViewSourceParser):
+ * html/parser/TextViewSourceParser.h: Added.
+ (WebCore::TextViewSourceParser::create):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Move HTMLInputStream to WebCore/html/parser
+ https://bugs.webkit.org/show_bug.cgi?id=45339
+
+ I forgot to move this file before.
+
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/parser/HTMLInputStream.h: Renamed from WebCore/html/HTMLInputStream.h.
+ (WebCore::HTMLInputStream::HTMLInputStream):
+ (WebCore::HTMLInputStream::appendToEnd):
+ (WebCore::HTMLInputStream::insertAtCurrentInsertionPoint):
+ (WebCore::HTMLInputStream::hasInsertionPoint):
+ (WebCore::HTMLInputStream::markEndOfFile):
+ (WebCore::HTMLInputStream::haveSeenEndOfFile):
+ (WebCore::HTMLInputStream::current):
+ (WebCore::HTMLInputStream::splitInto):
+ (WebCore::HTMLInputStream::mergeFrom):
+ (WebCore::InsertionPointRecord::InsertionPointRecord):
+ (WebCore::InsertionPointRecord::~InsertionPointRecord):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ TextDocument should come in from the cold
+ https://bugs.webkit.org/show_bug.cgi?id=45334
+
+ Previously, TextDocument reinvented the wheel to parse text. This
+ patch replaces TextDocument's hand-rolled parser with a parser built on
+ the HTML parser infrustructure, which gives us that stuff for free. I
+ also disentangled TextDocument from HTMLViewSourceDocument.
+
+ In a future patch, I'll move TextDocument out of the "loader" directory.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/HTMLViewSourceDocument.cpp:
+ (WebCore::HTMLViewSourceDocument::createParser):
+ * html/HTMLViewSourceDocument.h:
+ * html/parser/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::constructTreeFromToken):
+ (WebCore::HTMLTreeBuilder::constructTreeFromAtomicToken):
+ * html/parser/HTMLTreeBuilder.h:
+ * html/parser/HTMLViewSourceParser.cpp:
+ (WebCore::HTMLViewSourceParser::forcePlaintext):
+ * html/parser/HTMLViewSourceParser.h:
+ * html/parser/TextDocumentParser.cpp: Added.
+ (WebCore::TextDocumentParser::TextDocumentParser):
+ (WebCore::TextDocumentParser::~TextDocumentParser):
+ (WebCore::TextDocumentParser::insertFakePreElement):
+ * html/parser/TextDocumentParser.h: Added.
+ (WebCore::TextDocumentParser::create):
+ * loader/TextDocument.cpp:
+ * loader/TextDocument.h:
+
+2010-09-06 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ Implement MediaPlayerPrivate::platformMedia() for the Qt port
+
+ https://bugs.webkit.org/show_bug.cgi?id=45264
+
+ * platform/graphics/MediaPlayer.h:
+ * platform/graphics/qt/MediaPlayerPrivateQt.cpp:
+ (WebCore::MediaPlayerPrivate::platformMedia):
+ * platform/graphics/qt/MediaPlayerPrivateQt.h:
+
+2010-09-08 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Dirk Schulze.
+
+ An individual renderer should be assigned to each SVGFE*Element class
+ https://bugs.webkit.org/show_bug.cgi?id=43954
+
+ RenderSVGResourceFilterPrimitive renderer is added to
+ the project, and assigned to each object, which class is
+ derived from SVGFilterPrimitiveStandardAttributes. The patch
+ mainly contains build system changes, and it fixes one layout
+ test in svg/dynamic-updates.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isSVGResourceFilterPrimitive):
+ * rendering/RenderSVGResourceFilterPrimitive.cpp: Added.
+ (WebCore::RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive):
+ * rendering/RenderSVGResourceFilterPrimitive.h: Added.
+ (WebCore::RenderSVGResourceFilterPrimitive::isSVGResourceFilterPrimitive):
+ * rendering/SVGRenderTreeAsText.cpp:
+ (WebCore::writeSVGContainer):
+ * svg/SVGFEDiffuseLightingElement.cpp:
+ (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
+ * svg/SVGFELightElement.cpp:
+ (WebCore::SVGFELightElement::svgAttributeChanged):
+ (WebCore::SVGFELightElement::childrenChanged):
+ * svg/SVGFEOffsetElement.cpp:
+ (WebCore::SVGFEOffsetElement::svgAttributeChanged):
+ * svg/SVGFilterElement.h:
+ * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged):
+ (WebCore::SVGFilterPrimitiveStandardAttributes::childrenChanged):
+ (WebCore::SVGFilterPrimitiveStandardAttributes::createRenderer):
+ * svg/SVGFilterPrimitiveStandardAttributes.h:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::invalidate):
+
+2010-09-07 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Dan Bernstein.
+
+ DatasetDOMStringMap does not have the right memory model
+ https://bugs.webkit.org/show_bug.cgi?id=45358
+
+ Test: fast/dom/dataset-gc.html
+
+ * bindings/js/JSElementCustom.cpp:
+ (WebCore::JSElement::markChildren):
+ Mark the dataset if it exists.
+
+ * dom/Element.cpp:
+ (WebCore::Element::optionalDataset):
+ * dom/Element.h:
+ Expose a way to get the dataset or null (depending on if anyone thing
+ has forced its creation yet).
+
+2010-09-07 Jan E Hanssen <jhanssen@sencha.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Add a separate Path::closeCanvasSubpath() function for canvas paths
+ https://bugs.webkit.org/show_bug.cgi?id=45331
+
+ This is needed due to an adverse effect of the fix in 44061 that causes
+ certain paths not to be closed. This is not important for canvas paths
+ but it is for SVG paths, so splitting up the code in a generic (SVG)
+ case and one specialized for canvas.
+
+ Test: svg/dom/path-totalLength.html
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::closePath):
+ * platform/graphics/Path.h:
+ (WebCore::Path::closeCanvasSubpath):
+ * platform/graphics/qt/PathQt.cpp:
+ (WebCore::Path::closeSubpath):
+ (WebCore::Path::closeCanvasSubpath):
+
+2010-09-07 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Chris Marrin.
+
+ Transform animations always run in software now
+ https://bugs.webkit.org/show_bug.cgi?id=45341
+
+ After r66339 we always fell into software animation, because we
+ failed to detect transform or opacity properties in the keyframes,
+ so would send an empty list of values to the GraphicsLayer.
+
+ Fixed by using CSSProperty values, rather than GraphicsLayer
+ values, when detecting the presence of properties in the keyframes.
+
+ Test: manual-tests/transition-accelerated.html
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::startAnimation):
+
+2010-09-07 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ audio engine: add FFTFrame files
+ https://bugs.webkit.org/show_bug.cgi?id=34827
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/FFTFrame.cpp: Added.
+ (WebCore::FFTFrame::doPaddedFFT):
+ (WebCore::FFTFrame::createInterpolatedFrame):
+ (WebCore::FFTFrame::interpolateFrequencyComponents):
+ (WebCore::FFTFrame::extractAverageGroupDelay):
+ (WebCore::FFTFrame::addConstantGroupDelay):
+ (WebCore::FFTFrame::print):
+ * platform/audio/FFTFrame.h: Added.
+ (WebCore::FFTFrame::fftSize):
+ (WebCore::FFTFrame::log2FFTSize):
+ (WebCore::FFTFrame::dspSplitComplex):
+ * platform/audio/mac/FFTFrameMac.cpp: Added.
+ (WebCore::FFTFrame::FFTFrame):
+ (WebCore::FFTFrame::~FFTFrame):
+ (WebCore::FFTFrame::multiply):
+ (WebCore::FFTFrame::doFFT):
+ (WebCore::FFTFrame::doInverseFFT):
+ (WebCore::FFTFrame::fftSetupForSize):
+ (WebCore::FFTFrame::cleanup):
+ (WebCore::FFTFrame::realData):
+ (WebCore::FFTFrame::imagData):
+
+2010-09-07 Brent Fulgham <bfulgham@webkit.org>
+
+ Build fix, no review.
+
+ Provide stubs to allow WebKit.dll to build
+ for the WinCairo port.
+
+ * platform/network/curl/ResourceRequest.h:
+ (WebCore::ResourceRequest::ResourceRequest):
+ * platform/network/curl/ResourceResponse.h:
+ (WebCore::ResourceResponse::cfURLResponse):
+
+2010-09-07 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add AudioArray.h
+ https://bugs.webkit.org/show_bug.cgi?id=45204
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/AudioArray.h: Added.
+ (WebCore::AudioArray::AudioArray):
+ (WebCore::AudioArray::zero):
+ (WebCore::AudioArray::zeroRange):
+ (WebCore::AudioArray::copyToRange):
+
+2010-09-07 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Oliver Hunt.
+
+ pushState and replaceState do not clone RegExp objects correctly
+ https://bugs.webkit.org/show_bug.cgi?id=44718
+
+ Add RegExp support to the JSC implementation of SerializedScriptValue
+ (it stores the pattern and flags read from a RegExpObject, and creates
+ a new one on deserialization).
+
+ Tests: fast/loader/stateobjects/pushstate-object-types.html
+
+ * ForwardingHeaders/runtime/RegExp.h: Added.
+ * ForwardingHeaders/runtime/RegExpObject.h: Added.
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneSerializer::dumpIfTerminal):
+ (WebCore::CloneDeserializer::readTerminal):
+
+2010-09-07 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ Fix compile errors in DrawingBuffer if USE(ACCELERATED_COMPOSITING) is not set
+ https://bugs.webkit.org/show_bug.cgi?id=45324
+
+ Adds appropriate #if guards around code that has to deal directly with the compositor.
+ DrawingBuffer can still be used without the compositor as an off-screen rendering
+ region.
+
+ To test, compile without USE(ACCELERATED_COMPOSITING).
+
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBuffer::~DrawingBuffer):
+ (WebCore::DrawingBuffer::reset):
+ * platform/graphics/gpu/DrawingBuffer.h:
+
+2010-09-03 Joseph Pecoraro <joepeck@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Provide a way to trigger a <select multiple> onchange event on changes
+ https://bugs.webkit.org/show_bug.cgi?id=45192
+
+ Test: LayoutTests/platform/mac/fast/objc/dom-html-select-activate.html
+
+ This provides a way for a WebKit client using the Obj-C DOM bindings to
+ trigger the "change" on a listbox select (<select multiple> or <select>
+ with size > 1). This is because when a select is rendered as a listbox
+ "change" events are triggered by mouse down events.
+
+ This adds -[DOMHTMLSelectElement _activateItemAtIndex:allowMultipleSelection:]
+ to allow for handling multiple selections if the select element is a
+ multi-select.
+
+ * bindings/objc/DOMHTML.mm:
+ (-[DOMHTMLSelectElement _activateItemAtIndex:allowMultipleSelection:]):
+ * bindings/objc/DOMPrivate.h: unified the Category name. Was "FormsAutocomplete" now all are "FormAutocomplete".
+ * dom/SelectElement.h:
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::setSelectedIndexByUser): listboxs need to be treated specially to fire their "change" event.
+ * html/HTMLSelectElement.h:
+ * wml/WMLSelectElement.cpp:
+ (WebCore::WMLSelectElement::setSelectedIndexByUser):
+
+2010-09-07 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Minor WKCACFLayerRenderer cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=45201
+
+ Call initD3DGeometry() from createRenderer, rather than duplicating the code.
+
+ No behavior changes.
+
+ * platform/graphics/win/WKCACFLayerRenderer.cpp:
+ (WebCore::WKCACFLayerRenderer::createRenderer):
+
+2010-09-07 Vangelis Kokkevis <vangelis@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Reset the owner of PlatformLayer's once the GraphicsLayer they are associated with
+ gets destroyed.
+ https://bugs.webkit.org/show_bug.cgi?id=45329
+
+ Test: Fixes UI test failures downstream for all the Media tests when run on the buildbots (machines without GPUs).
+
+ * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+ (WebCore::GraphicsLayerChromium::~GraphicsLayerChromium):
+
+2010-09-07 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/8381749> -Wcast-align warning emitted when building with clang
+
+ Remove the -Wcast-align-warning since it isn't really useful, and clang is more aggressive about warning than gcc.
+
+ * Configurations/Base.xcconfig:
+
+2010-09-07 Abhishek Arya <inferno@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Remove redundant bounds check in originalText(). Add bounds check
+ to previousCharacter(). No need of start() > 0 check since m_start
+ is unsigned and we already do start() null check inside function.
+ https://bugs.webkit.org/show_bug.cgi?id=45303
+
+ Test: fast/text/one-letter-transform-crash.html
+
+ * rendering/RenderTextFragment.cpp:
+ (WebCore::RenderTextFragment::originalText):
+ (WebCore::RenderTextFragment::previousCharacter):
+
+2010-09-07 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ Regression in JPEG texture uploads on Mac OS X
+ https://bugs.webkit.org/show_bug.cgi?id=45316
+
+ Fixed regression introduced in
+ https://bugs.webkit.org/show_bug.cgi?id=44566 . Added regression
+ test covering this case to gl-teximage.html in Khronos repository
+ and synced test with WebKit's version.
+
+ * platform/graphics/cg/GraphicsContext3DCG.cpp:
+ (WebCore::GraphicsContext3D::getImageData):
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Add rendering/ColumnInfo.h to the sources list.
+
+ * GNUmakefile.am:
+
+2010-09-07 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45317, encapsulate multi-column rectangle information.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/ColumnInfo.h: Added.
+ (WebCore::ColumnInfo::ColumnInfo):
+ (WebCore::ColumnInfo::desiredColumnWidth):
+ (WebCore::ColumnInfo::setDesiredColumnWidth):
+ (WebCore::ColumnInfo::desiredColumnCount):
+ (WebCore::ColumnInfo::setDesiredColumnCount):
+ (WebCore::ColumnInfo::columnCount):
+ (WebCore::ColumnInfo::columnRectAt):
+ (WebCore::ColumnInfo::clearColumns):
+ (WebCore::ColumnInfo::addColumnRect):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintColumnRules):
+ (WebCore::RenderBlock::paintColumnContents):
+ (WebCore::RenderBlock::lowestPosition):
+ (WebCore::RenderBlock::rightmostPosition):
+ (WebCore::RenderBlock::leftmostPosition):
+ (WebCore::RenderBlock::hitTestColumns):
+ (WebCore::RenderBlock::setDesiredColumnCountAndWidth):
+ (WebCore::RenderBlock::desiredColumnWidth):
+ (WebCore::RenderBlock::desiredColumnCount):
+ (WebCore::RenderBlock::columnInfo):
+ (WebCore::RenderBlock::layoutColumns):
+ (WebCore::RenderBlock::adjustPointToColumnContents):
+ (WebCore::RenderBlock::adjustRectForColumns):
+ (WebCore::RenderBlock::adjustForColumns):
+ * rendering/RenderBlock.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintChildLayerIntoColumns):
+ (WebCore::RenderLayer::hitTestChildLayerColumns):
+
+2010-09-07 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ <rdar://problem/7794761> Floats inside of multicol fail to hit test
+ https://bugs.webkit.org/show_bug.cgi?id=44730
+
+ Test: fast/multicol/hit-test-float.html
+
+ Factored float hit-testing out of nodeAtPoint so that hitTestColumns could
+ call it with column-adjusted coordinates.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::nodeAtPoint):
+ (WebCore::RenderBlock::hitTestFloats):
+ (WebCore::RenderBlock::hitTestColumns):
+ * rendering/RenderBlock.h:
+
+2010-09-07 François Sausset <sausset@gmail.com>
+
+ Reviewed by Beth Dakin.
+
+ <math> element should be centered when display attribute set to block.
+ https://bugs.webkit.org/show_bug.cgi?id=44206
+
+ Test: mathml/presentation/attributes.xhtml
+
+ * css/mathml.css:
+ (math[display="block"]):
+
+2010-09-07 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Media elements should derive from ActiveDOMObjects
+ https://bugs.webkit.org/show_bug.cgi?id=45306
+ <rdar://problem/7929062>
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize ActiveDOMObject
+ (WebCore::HTMLMediaElement::stop): Call suspend, we want to do the same thing in both cases.
+ (WebCore::HTMLMediaElement::suspend): Rename from documentWillBecomeInactive.
+ (WebCore::HTMLMediaElement::resume): Rename from documentDidBecomeActive.
+ (WebCore::HTMLMediaElement::hasPendingActivity): Return true if the event queue is not empty
+ so the element can't be collected before they are sent.
+ * html/HTMLMediaElement.h:
+ (WebCore::HTMLMediaElement::canSuspend):
+
+2010-09-07 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Unreviewed, rolling out r66886.
+ http://trac.webkit.org/changeset/66886
+ https://bugs.webkit.org/show_bug.cgi?id=45112
+
+ Made
+
+ * platform/chromium/GeolocationServiceChromium.cpp:
+ * platform/chromium/GeolocationServiceChromium.h:
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Small build fix. Remove libWebCoreJS from CLEAN_FILES, as it
+ is no longer built.
+
+ * GNUmakefile.am: Remove reference to libWebCoreJS.
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] [REGRESSION] r66848 caused a crash in testwebview
+ https://bugs.webkit.org/show_bug.cgi?id=45298
+
+ No new tests as this fixes a test failure.
+
+ * platform/gtk/ScrollViewGtk.cpp:
+ (WebCore::ScrollView::setGtkAdjustments): Don't actually attach the
+ scrollbar adjustments unless this is a main frame ScrollView. If we do
+ Scrollbars will be cast incorrectly to MainFrameScrollbarGtk, causing
+ a segfault.
+
+2010-09-07 Kristian Monsen <kristianm@google.com>
+
+ Reviewed by Steve Block.
+
+ Compile fix for Android.
+ https://bugs.webkit.org/show_bug.cgi?id=45292
+ Explicitly add needed header for
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK as they do not get
+ included through other headers on Android.
+
+ No new tests, just a compile fix.
+
+ * bindings/scripts/CodeGeneratorV8.pm:
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Fix some feature guards
+ https://bugs.webkit.org/show_bug.cgi?id=45302
+
+ No new tests as this is just a build change.
+
+ * platform/graphics/gstreamer/DataSourceGStreamer.cpp: Guard with #if ENABLE(VIDEO)
+ * platform/graphics/gstreamer/DataSourceGStreamer.h: Ditto.
+ * platform/graphics/gstreamer/GOwnPtrGStreamer.cpp: Ditto.
+ * platform/graphics/gstreamer/GOwnPtrGStreamer.h: Ditto.
+ * platform/graphics/gstreamer/GStreamerGWorld.cpp: Ditto.
+ * platform/graphics/gstreamer/GStreamerGWorld.h: Ditto.
+ * platform/graphics/gstreamer/ImageGStreamer.h: Ditto.
+ * platform/graphics/gstreamer/ImageGStreamerCG.mm: Ditto.
+ * platform/graphics/gstreamer/ImageGStreamerCairo.cpp: Ditto.
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: Ditto.
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Ditto.
+ * platform/graphics/gstreamer/PlatformVideoWindow.h: Ditto.
+ * platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp: Ditto.
+ * platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp: Ditto.
+ * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: Ditto.
+ * platform/graphics/gstreamer/VideoSinkGStreamer.h: Ditto.
+ * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp: Ditto.
+ * platform/graphics/gstreamer/WebKitWebSourceGStreamer.h: Ditto.
+ * platform/gtk/GeolocationServiceGtk.cpp: Guard with ENABLE(GEOLOCATION)
+ * platform/gtk/GeolocationServiceGtk.h: Ditto.
+
+2010-09-07 Jonathan Dixon <joth@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Access to out-of-scope WebGeolocationServiceBridgeImpl
+ https://bugs.webkit.org/show_bug.cgi?id=45112
+
+ Add missing virtual destructor to the abstract base class.
+
+ * platform/chromium/GeolocationServiceChromium.cpp:
+ (WebCore::GeolocationServiceBridge::~GeolocationServiceBridge):
+ * platform/chromium/GeolocationServiceChromium.h:
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] [REGRESSION] r66848 caused a crash in testwebview
+ https://bugs.webkit.org/show_bug.cgi?id=45298
+
+ No new tests as this fixes a test failure.
+
+ * platform/gtk/ScrollViewGtk.cpp:
+ (WebCore::ScrollView::setGtkAdjustments): Don't actually attach the
+ scrollbar adjustments unless this is a main frame ScrollView. If we do
+ Scrollbars will be cast incorrectly to MainFrameScrollbarGtk, causing
+ a segfault.
+
+2010-09-07 Adam Langley <agl@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ [chromium] Fix complex text word spacing on Linux.
+
+ I broke complex text word spacing with r66689. I misnamed a
+ variable in the original code |glyphIndex| when it was
+ actually indexing code points. That meant that I compared it
+ against the wrong limit when working around Harfbuzz issues
+ and neatly disabled word spacing.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45191
+
+ Test: fast/text/atsui-spacing-features.html
+
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::TextRunWalker::setGlyphXPositions):
+
+2010-09-07 Satish Sampath <satish@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Fix speech button's hit test logic for RTL rendering.
+ https://bugs.webkit.org/show_bug.cgi?id=45288
+
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::forwardEvent):
+
+2010-09-07 Satish Sampath <satish@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Ignore programmatic clicks on speech input button for security reasons.
+ https://bugs.webkit.org/show_bug.cgi?id=45181
+
+ Test: fast/speech/speech-button-ignore-generated-events.html
+
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::InputFieldSpeechButtonElement::defaultEventHandler):
+
+2010-09-07 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] tst_QWebFrame::connectAndDisconnect() fails on WebKit trunk because __qt_sender__ is never set
+ https://bugs.webkit.org/show_bug.cgi?id=44697
+
+ When the signal handler is a JS function, __qt_sender__ is stuffed into a temporary
+ object that's pushed onto the function's scope before the function is invoked, and
+ popped again afterwards.
+
+ We were pushing this new scope object _after_ calling JSFunction::getCallData(),
+ and relying on JSC::call() to use the fresh scope chain from the function object.
+ However, this is no longer the case; JSC::call() uses the scope chain passed in
+ the CallData argument. Hence, we need to set up the scope before the function's
+ CallData is queried.
+
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::QtConnectionObject::execute):
+
+2010-09-07 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ Add ENABLE(INSPECTOR) guard in InspectorController::inspectorControllerForNode
+ https://bugs.webkit.org/show_bug.cgi?id=45272
+
+ Build fix.
+
+ * inspector/InspectorController.h:
+ (WebCore::InspectorController::inspectorControllerForNode):
+
+2010-09-07 Joerg Bornemann <joerg.bornemann@nokia.com>
+
+ Reviewed by Ariya Hidayat.
+
+ Fix QtWebKit linker error on Windows CE 6.
+ https://bugs.webkit.org/show_bug.cgi?id=43442
+
+ Doesn't affect any tests.
+
+ * WebCore.pro:
+
+2010-09-07 James Kozianski <koz@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ Crash rendering <meter/> with percent padding
+ https://bugs.webkit.org/show_bug.cgi?id=45081
+
+ Avoids a crash caused by RenderMeter checking its own dimensions to
+ determine whether it needs layout. The crash is avoided by removing
+ the check and always calling setNeedsLayout(true).
+
+ Test: fast/dom/HTMLMeterElement/meter-percent-size.html
+
+ * rendering/RenderIndicator.cpp:
+ (WebCore::RenderIndicator::updateFromElement):
+ * rendering/RenderIndicator.h:
+
+2010-09-06 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ OOB read with svg polyline
+ https://bugs.webkit.org/show_bug.cgi?id=45279
+
+ In principle, attributeChanged can do anything. If we supported more
+ DOM mutation events, it could even run JavaScript. That means we need
+ to be prepared for the attribute map to change when running
+ attributeChanged. This patch makes this loop resilient to the
+ attribute map changing by storing the list of changed attributes on the
+ stack.
+
+ Test: fast/parser/changing-attrbutes-crash.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::setAttributeMap):
+
+2010-09-06 Oliver Hunt <oliver@apple.com>
+
+ Windows build fix
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneSerializer::write):
+
+2010-09-06 Oliver Hunt <oliver@apple.com>
+
+ Windows build fix
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneSerializer::write):
+
+2010-09-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ SerializedScriptValue needs to use a flat storage mechanism
+ https://bugs.webkit.org/show_bug.cgi?id=45244
+
+ Rewrite the old tree to tree serialization logic to use
+ flat storage. Unfortunately this basically required a
+ complete rewrite.
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneBase::CloneBase):
+ (WebCore::CloneBase::shouldTerminate):
+ (WebCore::CloneBase::ticksUntilNextCheck):
+ (WebCore::CloneBase::didTimeOut):
+ (WebCore::CloneBase::throwStackOverflow):
+ (WebCore::CloneBase::throwInterruptedException):
+ (WebCore::CloneBase::fail):
+ (WebCore::CloneSerializer::serialize):
+ (WebCore::CloneSerializer::CloneSerializer):
+ (WebCore::CloneSerializer::isArray):
+ (WebCore::CloneSerializer::startObject):
+ (WebCore::CloneSerializer::startArray):
+ (WebCore::CloneSerializer::endObject):
+ (WebCore::CloneSerializer::getSparseIndex):
+ (WebCore::CloneSerializer::getProperty):
+ (WebCore::CloneSerializer::dumpImmediate):
+ (WebCore::CloneSerializer::dumpString):
+ (WebCore::CloneSerializer::dumpIfTerminal):
+ (WebCore::CloneSerializer::write):
+ (WebCore::CloneSerializer::writeLittleEndian):
+ (WebCore::CloneSerializer::writeStringIndex):
+ (WebCore::CloneDeserializer::deserializeString):
+ (WebCore::CloneDeserializer::deserialize):
+ (WebCore::CloneDeserializer::CloneDeserializer):
+ (WebCore::CloneDeserializer::throwValidationError):
+ (WebCore::CloneDeserializer::isValid):
+ (WebCore::CloneDeserializer::readLittleEndian):
+ (WebCore::CloneDeserializer::read):
+ (WebCore::CloneDeserializer::readStringIndex):
+ (WebCore::CloneDeserializer::readString):
+ (WebCore::CloneDeserializer::readStringData):
+ (WebCore::CloneDeserializer::readTag):
+ (WebCore::CloneDeserializer::putProperty):
+ (WebCore::CloneDeserializer::readFile):
+ (WebCore::CloneDeserializer::readTerminal):
+ (WebCore::SerializedScriptValue::~SerializedScriptValue):
+ (WebCore::SerializedScriptValue::SerializedScriptValue):
+ (WebCore::SerializedScriptValue::create):
+ (WebCore::SerializedScriptValue::toString):
+ (WebCore::SerializedScriptValue::deserialize):
+ (WebCore::SerializedScriptValue::nullValue):
+ * bindings/js/SerializedScriptValue.h:
+ * dom/MessagePortChannel.cpp:
+ (WebCore::MessagePortChannel::EventData::EventData):
+ * workers/WorkerMessagingProxy.cpp:
+ (WebCore::MessageWorkerContextTask::MessageWorkerContextTask):
+ (WebCore::MessageWorkerTask::MessageWorkerTask):
+
+2010-09-06 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] ScrollbarThemeGtk should be enabled for interior frame scrollbars
+ https://bugs.webkit.org/show_bug.cgi?id=45046
+
+ Make interior frame scrollbars "fully-fake," which means they do not rely
+ at all on GTK+ for painting or behavior, but instead are typical WebCore
+ scrollbars drawn according to the GTK+ theme. Move ScrollbarGtk to
+ MainFrameScrollbarGtk and remove all logic in that file dealing with interior
+ frame scrollbars.
+
+ No new tests, as this is already covered by pixel tests for scrollbars,
+ which were added in r66605.
+
+ * GNUmakefile.am: Update sources list.
+ * platform/ScrollView.h: Change the adjustment members to be smart pointers.
+ * platform/Scrollbar.cpp: Enable THUMB_POSITION_AFFECTS_BUTTONS for GTK+ as well.
+ * platform/gtk/MainFrameScrollbarGtk.cpp: Added.
+ (MainFrameScrollbarGtk::create): Create a MainFrameScrollbarGtk instead of ScrollbarGtk.
+ (MainFrameScrollbarGtk::MainFrameScrollbarGtk):
+ (MainFrameScrollbarGtk::~MainFrameScrollbarGtk):
+ (MainFrameScrollbarGtk::attachAdjustment):
+ (MainFrameScrollbarGtk::detachAdjustment):
+ (MainFrameScrollbarGtk::updateThumbPosition):
+ (MainFrameScrollbarGtk::updateThumbProportion):
+ (MainFrameScrollbarGtk::gtkValueChanged):
+ (MainFrameScrollbarGtk::paint):
+ * platform/gtk/MainFrameScrollbarGtk.h: Added.
+ * platform/gtk/ScrollViewGtk.cpp:
+ (WebCore::ScrollView::platformInit): Remove unnecessary initialization
+ because of smart pointer change.
+ (WebCore::ScrollView::createScrollbar): Instead of creating ScrollbarGtk for
+ interior frame scrollbars, create a normal WebCore scrollbar.
+ (WebCore::ScrollView::setGtkAdjustments): Added an extra assert which ensures
+ that this method is never called with a non-null adjustment on an interior frame
+ scrollbar.
+ (WebCore::ScrollView::platformAddChild): Remove logic for interior frame scrollbars.
+ (WebCore::ScrollView::platformRemoveChild): Remove logic for interior frame scrollbars.
+ (WebCore::ScrollView::visibleContentRect): Use a more accurate guard for detecting
+ transitionary states when accessing parent widgets. Explcitly guard against interior
+ frame ScrollView's trying to determine size based on parent widgets.
+ (WebCore::ScrollView::setScrollbarModes): This method was out of sync with the one
+ it copy-and-pasted from. Update it and change the logic to do the right thing for
+ interior frame scrollbars.
+ * platform/gtk/ScrollbarGtk.cpp: Removed.
+ * platform/gtk/ScrollbarGtk.h: Removed.
+
+2010-09-06 Justin Schuh <jschuh@chromium.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Make SVG PendingResources use RefPtr
+ https://bugs.webkit.org/show_bug.cgi?id=43587
+
+ Convert SVGDocumentExtensions::m_pendingResources to use a RefPtr for
+ pending elements instead of a raw pointer so that pending elements can't
+ be freed prematurely.
+
+ Test: svg/custom/use-invalid-pattern.svg
+
+ * rendering/RenderSVGResourceContainer.cpp:
+ (WebCore::RenderSVGResourceContainer::registerResource):
+ * svg/SVGDocumentExtensions.cpp:
+ (WebCore::SVGDocumentExtensions::addPendingResource):
+ (WebCore::SVGDocumentExtensions::removePendingResource):
+ * svg/SVGDocumentExtensions.h:
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::insertedIntoDocument):
+
+2010-09-06 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] ScrollbarThemeGtk should support secondary steppers
+ https://bugs.webkit.org/show_bug.cgi?id=44791
+
+ Add support to ScrollbarThemeGtk for drawing alternate steppers. Adjust
+ the algorithms for calculating forward and back button rects, if they
+ are active in the theme. Expose this information via GtkScrollbarMetrics.
+
+ * platform/gtk/ScrollbarThemeGtk.cpp:
+ (WebCore::ScrollbarThemeGtk::updateThemeProperties): Access the secondary stepper properties
+ of GtkScrollbarMetrics when updating the style cache.
+ (WebCore::ScrollbarThemeGtk::backButtonRect): Account for alternate steppers.
+ (WebCore::ScrollbarThemeGtk::forwardButtonRect): Ditto.
+ (WebCore::ScrollbarThemeGtk::trackRect): Ditto.
+ (WebCore::ScrollbarThemeGtk::paintButton): Ditto.
+ * platform/gtk/ScrollbarThemeGtk.h:
+ * platform/gtk/gtk2drawing.c: Expose whether or not the style uses alternate steppers
+ via GtkScrollbarMetrics.
+ * platform/gtk/gtkdrawing.h: Added fields to GtkScrollbarMetrics.
+
+2010-09-06 Tony Gentilcore <tonyg@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Implement HTML5 definition of document.readyState
+ https://bugs.webkit.org/show_bug.cgi?id=45119
+
+ The legacy behavior was "loading" -> "loaded" -> "complete". The new
+ HTML5 behavior is "loading" -> "interactive" -> "complete". There is
+ some potential for this to cause compat problems if for instance a
+ page expects readyState to be "loaded" during the DOMContentLoaded event.
+
+ Test: fast/dom/Document/readystate.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document): Initial value is Complete because according to http://www.whatwg.org/specs/web-apps/current-work/#dom-document-readystate,
+ when a Document is created the initial value is "complete" unless it has a parser associated with it, in which case it is "loading".
+ So the ctor starts it Complete, and when the parser is created it is flipped to Loading.
+ (WebCore::Document::readyState):
+ (WebCore::Document::setReadyState):
+ (WebCore::Document::implicitOpen):
+ (WebCore::Document::finishedParsing): Ensure that XML and HTML parser have transition to Stopping state.
+ * dom/Document.h:
+ * dom/DocumentParser.cpp:
+ (WebCore::DocumentParser::prepareToStopParsing): Previously this was being called when parsing had stopped.
+ It is better to ensure it is only called while parsing.
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::end): Transition to stopping before calling document finishedParsiong().
+ * html/parser/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::prepareToStopParsing): Set state to interactive before running deferred scripts.
+ This method is also called when parsing fragments, so we need to ensure it isn't done in that case.
+ (WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd): Added. Break out this part s that notifyFinished doesn't go through
+ the additional steps of pumping tokenizer, setting the state, etc.
+ (WebCore::HTMLDocumentParser::notifyFinished): Now that prepareToStopParsing is split up, we must protect. It also makes sense to add a couple of ASSERTs.
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::stopLoading): It looks like an aborted load should never transition to "complete" according the HTML5. I've left the legacy behavior for now though.
+ (WebCore::FrameLoader::checkCompleted): The FrameLoader now sets the state on the Document instead of the Document polling the FrameLoader.
+
+2010-09-06 Anton Muhin <antonm@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [v8] Inline hot methods for V8 to WebCore and back conversions
+ https://bugs.webkit.org/show_bug.cgi?id=45270
+
+ Inline fast paths of hot functions performing conversions from V8 wrappers
+ to WebCore native objects and back.
+ That slightly increases the size of binary (within 0.1% for both Ubuntu
+ and Windows, but those builds are slightly different from official ones),
+ but gives performance boost (3--5% on Windows, up to 8% on Ubuntu).
+
+ * bindings/scripts/CodeGeneratorV8.pm:
+ * bindings/v8/V8DOMWindowShell.cpp:
+ (WebCore::V8DOMWindowShell::initContextIfNeeded):
+ * bindings/v8/V8DOMWindowShell.h:
+ * bindings/v8/V8DOMWrapper.cpp:
+ (WebCore::V8DOMWrapper::getWrapperSlow):
+ * bindings/v8/V8DOMWrapper.h:
+ (WebCore::V8DOMWrapper::getWrapper):
+ * bindings/v8/custom/V8NodeCustom.cpp:
+ (WebCore::toV8Slow):
+
+2010-09-06 Shane Stephens <shanestephens@google.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ [Crash] <animateMotion> element directly inside <symbol> element causes crash when referenced by <use>
+ https://bugs.webkit.org/show_bug.cgi?id=44750
+
+ Fixes crash by checking for null transforms and skipping update step
+ when appropriate.
+
+ Test: svg/dom/symbol-embeddedAnimation.svg
+
+ * svg/SVGAnimateMotionElement.cpp:
+ (WebCore::SVGAnimateMotionElement::applyResultsToTarget):
+
+2010-09-06 Xan Lopez <xlopez@igalia.com>
+
+ Rubber-stamped by Tor Arne Vestbø.
+
+ WebCore already generates a focus-{out,in} events on its setFocus
+ method, there's no need to duplicate it here. Previously this was
+ needed because we were not catching all possible names of focus
+ events in PluginView::handleEvent and were missing the ones
+ WebCore does, but this has been fixed in r66827.
+
+ * plugins/qt/PluginViewQt.cpp:
+ (WebCore::PluginView::setFocus):
+
+2010-09-06 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66823.
+ http://trac.webkit.org/changeset/66823
+ https://bugs.webkit.org/show_bug.cgi?id=45266
+
+ Windows build fails with unknown reason (Requested by zherczeg
+ on #webkit).
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderObject.h:
+ * rendering/RenderSVGResourceFilterPrimitive.cpp: Removed.
+ * rendering/RenderSVGResourceFilterPrimitive.h: Removed.
+ * rendering/SVGRenderTreeAsText.cpp:
+ (WebCore::writeSVGContainer):
+ * svg/SVGFEDiffuseLightingElement.cpp:
+ (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
+ * svg/SVGFELightElement.cpp:
+ (WebCore::SVGFELightElement::svgAttributeChanged):
+ (WebCore::SVGFELightElement::childrenChanged):
+ * svg/SVGFEOffsetElement.cpp:
+ (WebCore::SVGFEOffsetElement::svgAttributeChanged):
+ * svg/SVGFilterElement.h:
+ (WebCore::SVGFilterElement::invalidateFilter):
+ * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged):
+ (WebCore::SVGFilterPrimitiveStandardAttributes::childrenChanged):
+ * svg/SVGFilterPrimitiveStandardAttributes.h:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::rendererIsNeeded):
+
+2010-09-06 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [GTK] Provide Keyboard Events to Windowless plugins
+ https://bugs.webkit.org/show_bug.cgi?id=44613
+
+ Fix keyboard event delivery for windowless plugins.
+
+ Based on a patch by Bharathwaaj.
+
+ * plugins/PluginView.cpp:
+ (WebCore::PluginView::handleEvent): also take into account
+ focused{in,out} events
+ * plugins/gtk/PluginViewGtk.cpp:
+ (WebCore::PluginView::handleKeyboardEvent): we want the keyval
+ here, not the hardware keycode
+ (WebCore::PluginView::handleMouseEvent): focus the pluginview on mouse events
+
+2010-09-06 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ WebInspector: it'd be nice to be able to pass undefined argument as a callback to InspectorBackend functions.
+
+ There are some places where callback is passing via some wrapper. In that case sendMessageToBackend
+ will be called with additional argument for callback but with undefined value.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45265
+
+ * inspector/CodeGeneratorInspector.pm:
+
+2010-09-06 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Dirk Schulze.
+
+ An individual renderer should be assigned to each SVGFE*Element class
+ https://bugs.webkit.org/show_bug.cgi?id=43954
+
+ RenderSVGResourceFilterPrimitive renderer is added to
+ the project, and assigned to each object, which class is
+ derived from SVGFilterPrimitiveStandardAttributes. The patch
+ mainly contains build system changes, and it fixes one layout
+ test in svg/dynamic-updates.
+
+ * Android.mk:
+ * CMakeLists.txt:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isSVGResourceFilterPrimitive):
+ * rendering/RenderSVGResourceFilterPrimitive.cpp: Added.
+ (WebCore::RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive):
+ * rendering/RenderSVGResourceFilterPrimitive.h: Added.
+ (WebCore::RenderSVGResourceFilterPrimitive::isSVGResourceFilterPrimitive):
+ * rendering/SVGRenderTreeAsText.cpp:
+ (WebCore::writeSVGContainer):
+ * svg/SVGFEDiffuseLightingElement.cpp:
+ (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
+ * svg/SVGFELightElement.cpp:
+ (WebCore::SVGFELightElement::svgAttributeChanged):
+ (WebCore::SVGFELightElement::childrenChanged):
+ * svg/SVGFEOffsetElement.cpp:
+ (WebCore::SVGFEOffsetElement::svgAttributeChanged):
+ * svg/SVGFilterElement.h:
+ * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged):
+ (WebCore::SVGFilterPrimitiveStandardAttributes::childrenChanged):
+ (WebCore::SVGFilterPrimitiveStandardAttributes::createRenderer):
+ * svg/SVGFilterPrimitiveStandardAttributes.h:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::invalidate):
+
+2010-09-06 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Reviewed by Dirk Schulze.
+
+ [WML] Use RenderImageResource in WMLImageElement.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=44952
+
+ The hasImage() and setCachedImage() were moved to RenderImageResource class.
+ So, WML also should use the functions from RenderImageResource.
+
+ * wml/WMLImageElement.cpp:
+ (WebCore::WMLImageElement::attach):
+
+2010-08-26 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Add index insertion support to IndexedDB.
+ https://bugs.webkit.org/show_bug.cgi?id=44695
+
+ Whenever you insert an item into an ObjectStore, it should use all
+ indexes' key paths to insert corresponding entries into each index.
+ Also data should be deleted out of the index when it goes away.
+
+ Not much testing yet since there's no way to directly observe indexes.
+ More will be in next patch.
+
+ * storage/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::removeObjectStore):
+ * storage/IDBFactoryBackendImpl.cpp:
+ (WebCore::createTables):
+ * storage/IDBIndex.idl:
+ * storage/IDBIndexBackendImpl.cpp:
+ (WebCore::whereClause):
+ (WebCore::bindWhereClause):
+ (WebCore::IDBIndexBackendImpl::addingKeyAllowed):
+ * storage/IDBIndexBackendImpl.h:
+ (WebCore::IDBIndexBackendImpl::id):
+ * storage/IDBKey.cpp:
+ (WebCore::IDBKey::whereSyntax):
+ (WebCore::IDBKey::bind):
+ (WebCore::IDBKey::bindWithNulls):
+ * storage/IDBKey.h:
+ * storage/IDBObjectStore.idl:
+ * storage/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::whereClause):
+ (WebCore::bindWhereClause):
+ (WebCore::IDBObjectStoreBackendImpl::get):
+ (WebCore::fetchKeyFromKeyPath):
+ (WebCore::putObjectStoreData):
+ (WebCore::putIndexData):
+ (WebCore::IDBObjectStoreBackendImpl::put):
+ (WebCore::IDBObjectStoreBackendImpl::remove):
+ (WebCore::IDBObjectStoreBackendImpl::createIndex):
+ (WebCore::doDelete):
+ (WebCore::IDBObjectStoreBackendImpl::removeIndex):
+ (WebCore::IDBObjectStoreBackendImpl::openCursor):
+ * storage/IDBObjectStoreBackendImpl.h:
+
+2010-09-06 Anton Muhin <antonm@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [v8] bypass caches when query memory usage from post GC and in crash handler.
+ https://bugs.webkit.org/show_bug.cgi?id=45036
+
+ Add Chromium-specific API to query actual memory usage which bypasses any caches.
+
+ * platform/chromium/ChromiumBridge.h:
+
+2010-09-06 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Rename SecurityOrigin::canLoad to canDisplay
+ https://bugs.webkit.org/show_bug.cgi?id=45214
+
+ canLoad is a pretty opaque name. This function is really about whether
+ you can display the contents of the URL in an iframe, an image, or a
+ plugin.
+
+ * WebCore.exp.in:
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::isSafeToLoadURL):
+ * loader/Cache.cpp:
+ (WebCore::Cache::requestResource):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadFrameRequest):
+ * loader/PingLoader.cpp:
+ (WebCore::PingLoader::loadImage):
+ * loader/SubframeLoader.cpp:
+ (WebCore::SubframeLoader::loadMediaPlayerProxyPlugin):
+ (WebCore::SubframeLoader::createJavaAppletWidget):
+ (WebCore::SubframeLoader::loadSubframe):
+ (WebCore::SubframeLoader::loadPlugin):
+ * loader/SubresourceLoader.cpp:
+ (WebCore::SubresourceLoader::create):
+ * page/SecurityOrigin.cpp:
+ (WebCore::SecurityOrigin::canDisplay):
+ * page/SecurityOrigin.h:
+ * plugins/PluginView.cpp:
+ (WebCore::PluginView::load):
+
+2010-08-31 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: browser crashes on attempt to evaluate "alert(1)" while staying on a breakpoint
+ https://bugs.webkit.org/show_bug.cgi?id=44943
+
+ Test: inspector/debugger-suspend-active-dom-objects.html
+
+ * page/PageGroupLoadDeferrer.cpp:
+ (WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer):
+
+2010-09-05 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Add unit tests for red-black tree and (POD) arena
+ https://bugs.webkit.org/show_bug.cgi?id=45060
+
+ * platform/graphics/gpu/PODArena.h: Made DefaultChunkSize public so unit tests can access it. Fixed copyright header.
+ * platform/graphics/gpu/PODInterval.h: Fixed copyright header.
+ * platform/graphics/gpu/PODIntervalTree.h: Fixed copyright header.
+ * platform/graphics/gpu/PODRedBlackTree.h: Fixed copyright header.
+
+2010-09-05 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Nate Chapin.
+
+ Add the concept of class methods to bindings (for IndexedDB's IDBKeyRange).
+ https://bugs.webkit.org/show_bug.cgi?id=45044
+
+ IndexedDB's IDBKeyRange has what, in other languages, are called class
+ methods. In javaScript terms, these are methods only accessible from their
+ constructor and not instances. This change adds such support to V8. There
+ are already other features required for IndexedDB that JSC doesn't yet
+ support, so I'll add this to the list of todo items in the master bug
+ for that.
+
+ The bindings tests cover this. My next patch will change WebCore to use
+ this and it'll have associated layout tests.
+
+ * bindings/scripts/CodeGeneratorV8.pm:
+ * bindings/scripts/test/CPP/WebDOMTestObj.cpp:
+ (WebDOMTestObj::classMethod):
+ (WebDOMTestObj::classMethodWithOptional):
+ * bindings/scripts/test/CPP/WebDOMTestObj.h:
+ * bindings/scripts/test/GObject/WebKitDOMTestObj.cpp:
+ (webkit_dom_test_obj_class_method):
+ (webkit_dom_test_obj_class_method_with_optional):
+ * bindings/scripts/test/GObject/WebKitDOMTestObj.h:
+ * bindings/scripts/test/JS/JSTestObj.cpp:
+ (WebCore::jsTestObjPrototypeFunctionStaticMethod):
+ (WebCore::jsTestObjPrototypeFunctionStaticMethodWithOptional):
+ * bindings/scripts/test/JS/JSTestObj.h:
+ * bindings/scripts/test/ObjC/DOMTestObj.h:
+ * bindings/scripts/test/ObjC/DOMTestObj.mm:
+ (-[DOMTestObj classMethod]):
+ (-[DOMTestObj classMethodWithOptional:]):
+ * bindings/scripts/test/TestObj.idl:
+ * bindings/scripts/test/V8/V8TestObj.cpp:
+ (WebCore::TestObjInternal::classMethodCallback):
+ (WebCore::TestObjInternal::classMethodWithOptionalCallback):
+ (WebCore::ConfigureV8TestObjTemplate):
+ * storage/IDBKeyRange.idl:
+
+2010-09-05 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Add IndexedDB objects' constructors to window
+ https://bugs.webkit.org/show_bug.cgi?id=44599
+
+ Also add a forgotten constant to IDBTransaction, and
+ change IDBKeyRange over to using the V8Static attribute
+ so it actually behaves as it's supposed to.
+
+ * bindings/generic/RuntimeEnabledFeatures.h:
+ (WebCore::RuntimeEnabledFeatures::iDBCursorEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBDatabaseEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBDatabaseErrorEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBDatabaseExceptionEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBErrorEventEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBEventEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBFactoryEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBIndexEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBKeyRangeEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBObjectStoreEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBRequestEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBSuccessEventEnabled):
+ (WebCore::RuntimeEnabledFeatures::iDBTransactionEnabled):
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::clear):
+ (WebCore::DOMWindow::indexedDB):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+ * storage/IDBKeyRange.idl:
+ * storage/IDBTransaction.h:
+ * storage/IDBTransaction.idl:
+
+2010-09-04 Justin Schuh <jschuh@chromium.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Prevent premature deletion of svg use shadow tree
+ https://bugs.webkit.org/show_bug.cgi?id=43260
+
+ Test: svg/custom/use-invalid-style.svg
+
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::insertedIntoDocument):
+ (WebCore::SVGUseElement::removedFromDocument):
+ (WebCore::SVGUseElement::detach):
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Create and provide access to NetworkingContext in FrameLoader.
+
+ In the WebKit layer we added specific implementations of FrameNetworkingContext
+ so each port's FrameLoaderClient can add any port specific information to NetworkingContext
+ The NetworkingContext is, therefore, created by a FrameLoaderClient and stored
+ in the FrameLoader for each frame created. People must always use it
+ by calling FrameLoader::networkingContext() and never through their FrameLoaderClient.
+ The lifetime cycle of NetworkingContext is kept by a RefPtr, so the object is RefCounted.
+
+ It is still a preparation to NetworkingContext to be activated and
+ work for all ports.
+
+ * WebCore.exp.in:
+ * loader/EmptyClients.h:
+ (WebCore::EmptyFrameLoaderClient::createNetworkingContext):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::~FrameLoader):
+ (WebCore::FrameLoader::init):
+ (WebCore::FrameLoader::networkingContext):
+ * loader/FrameLoader.h:
+ * loader/FrameLoaderClient.h:
+
+2010-09-03 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ V8/JS bindings should not perform type checks if the parameter has Callback attribute
+ https://bugs.webkit.org/show_bug.cgi?id=45143
+
+ No new tests, should not affect existing idls.
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * bindings/scripts/CodeGeneratorV8.pm:
+ * bindings/scripts/test/JS/JSTestObj.cpp:
+ (WebCore::jsTestObjPrototypeFunctionOverloadedMethod5):
+ (WebCore::jsTestObjPrototypeFunctionOverloadedMethod):
+ * bindings/scripts/test/TestObj.idl:
+ * bindings/scripts/test/V8/V8TestObj.cpp:
+ (WebCore::TestObjInternal::overloadedMethod5Callback):
+ (WebCore::TestObjInternal::overloadedMethodCallback):
+
+2010-09-03 Kenneth Russell <kbr@google.com>
+
+ Unreviewed, Chromium build fix. Fix breakage on Windows after
+ r66787 / https://bugs.webkit.org/show_bug.cgi?id=45223 .
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::Font::drawGlyphs):
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Text sometimes fails to display in accelerated 2d canvases
+ https://bugs.webkit.org/show_bug.cgi?id=45223
+
+ Calls PlatformContextSkia::prepareForSoftwareDraw() before drawing glyphs
+ using skia to ensure that the backing store state is consistent.
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::Font::drawGlyphs):
+
+2010-09-03 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Add thirdparty directory and incorporate GLU tessellator
+ https://bugs.webkit.org/show_bug.cgi?id=44707
+
+ This directory is intended to contain copies of third-party libraries used
+ by WebCore, in particular those which may require some modification in
+ order to incorporate.
+
+ No tests at this time; these sources are being added in preparation for
+ incorporating other code which uses them, at which point the code will be
+ exercised and testable.
+
+ * thirdparty: Added.
+ * thirdparty/README.txt: Added.
+ * thirdparty/glu: Added.
+ * thirdparty/glu/LICENSE.txt: Added.
+ * thirdparty/glu/README.webkit: Added.
+ * thirdparty/glu/gluos.h: Added.
+ * thirdparty/glu/internal_glu.h: Added.
+ * thirdparty/glu/libtess: Added.
+ * thirdparty/glu/libtess/GNUmakefile: Added.
+ * thirdparty/glu/libtess/Imakefile: Added.
+ * thirdparty/glu/libtess/README: Added.
+ * thirdparty/glu/libtess/alg-outline: Added.
+ * thirdparty/glu/libtess/dict-list.h: Added.
+ * thirdparty/glu/libtess/dict.c: Added.
+ * thirdparty/glu/libtess/dict.h: Added.
+ * thirdparty/glu/libtess/geom.c: Added.
+ * thirdparty/glu/libtess/geom.h: Added.
+ * thirdparty/glu/libtess/memalloc.c: Added.
+ * thirdparty/glu/libtess/memalloc.h: Added.
+ * thirdparty/glu/libtess/mesh.c: Added.
+ * thirdparty/glu/libtess/mesh.h: Added.
+ * thirdparty/glu/libtess/normal.c: Added.
+ * thirdparty/glu/libtess/normal.h: Added.
+ * thirdparty/glu/libtess/priorityq-heap.c: Added.
+ * thirdparty/glu/libtess/priorityq-heap.h: Added.
+ * thirdparty/glu/libtess/priorityq-sort.h: Added.
+ * thirdparty/glu/libtess/priorityq.c: Added.
+ * thirdparty/glu/libtess/priorityq.h: Added.
+ * thirdparty/glu/libtess/render.c: Added.
+ * thirdparty/glu/libtess/render.h: Added.
+ * thirdparty/glu/libtess/sweep.c: Added.
+ * thirdparty/glu/libtess/sweep.h: Added.
+ * thirdparty/glu/libtess/tess.c: Added.
+ * thirdparty/glu/libtess/tess.h: Added.
+ * thirdparty/glu/libtess/tessmono.c: Added.
+ * thirdparty/glu/libtess/tessmono.h: Added.
+
+2010-09-03 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66781.
+ http://trac.webkit.org/changeset/66781
+ https://bugs.webkit.org/show_bug.cgi?id=45220
+
+ Breaks the build. Adds a mac-specific file to
+ platform/graphics without #if PLATFORM() guards and changes
+ the GraphicsContext3D interface without updating all
+ implementations (Requested by jamesr on #webkit).
+
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/canvas/WebGLObject.cpp:
+ (WebCore::WebGLObject::deleteObject):
+ * platform/graphics/ANGLEWebKitBridge.h:
+ * platform/graphics/GraphicsContext3D.h:
+ * platform/graphics/GraphicsContext3DOpenGL.cpp: Removed.
+ * platform/graphics/mac/GraphicsContext3DMac.mm:
+ (WebCore::GraphicsContext3D::validateAttributes):
+ (WebCore::GraphicsContext3D::makeContextCurrent):
+ (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas):
+ (WebCore::GraphicsContext3D::reshape):
+ (WebCore::ensureContext):
+ (WebCore::GraphicsContext3D::prepareTexture):
+ (WebCore::GraphicsContext3D::activeTexture):
+ (WebCore::GraphicsContext3D::attachShader):
+ (WebCore::GraphicsContext3D::bindAttribLocation):
+ (WebCore::GraphicsContext3D::bindBuffer):
+ (WebCore::GraphicsContext3D::bindFramebuffer):
+ (WebCore::GraphicsContext3D::bindRenderbuffer):
+ (WebCore::GraphicsContext3D::bindTexture):
+ (WebCore::GraphicsContext3D::blendColor):
+ (WebCore::GraphicsContext3D::blendEquation):
+ (WebCore::GraphicsContext3D::blendEquationSeparate):
+ (WebCore::GraphicsContext3D::blendFunc):
+ (WebCore::GraphicsContext3D::blendFuncSeparate):
+ (WebCore::GraphicsContext3D::bufferData):
+ (WebCore::GraphicsContext3D::bufferSubData):
+ (WebCore::GraphicsContext3D::checkFramebufferStatus):
+ (WebCore::GraphicsContext3D::clearColor):
+ (WebCore::GraphicsContext3D::clear):
+ (WebCore::GraphicsContext3D::clearDepth):
+ (WebCore::GraphicsContext3D::clearStencil):
+ (WebCore::GraphicsContext3D::colorMask):
+ (WebCore::GraphicsContext3D::compileShader):
+ (WebCore::GraphicsContext3D::copyTexImage2D):
+ (WebCore::GraphicsContext3D::copyTexSubImage2D):
+ (WebCore::GraphicsContext3D::cullFace):
+ (WebCore::GraphicsContext3D::depthFunc):
+ (WebCore::GraphicsContext3D::depthMask):
+ (WebCore::GraphicsContext3D::depthRange):
+ (WebCore::GraphicsContext3D::detachShader):
+ (WebCore::GraphicsContext3D::disable):
+ (WebCore::GraphicsContext3D::disableVertexAttribArray):
+ (WebCore::GraphicsContext3D::drawArrays):
+ (WebCore::GraphicsContext3D::drawElements):
+ (WebCore::GraphicsContext3D::enable):
+ (WebCore::GraphicsContext3D::enableVertexAttribArray):
+ (WebCore::GraphicsContext3D::finish):
+ (WebCore::GraphicsContext3D::flush):
+ (WebCore::GraphicsContext3D::framebufferRenderbuffer):
+ (WebCore::GraphicsContext3D::framebufferTexture2D):
+ (WebCore::GraphicsContext3D::frontFace):
+ (WebCore::GraphicsContext3D::generateMipmap):
+ (WebCore::GraphicsContext3D::getActiveAttrib):
+ (WebCore::GraphicsContext3D::getActiveUniform):
+ (WebCore::GraphicsContext3D::getAttachedShaders):
+ (WebCore::GraphicsContext3D::getAttribLocation):
+ (WebCore::GraphicsContext3D::getContextAttributes):
+ (WebCore::GraphicsContext3D::getError):
+ (WebCore::GraphicsContext3D::getString):
+ (WebCore::GraphicsContext3D::hint):
+ (WebCore::GraphicsContext3D::isBuffer):
+ (WebCore::GraphicsContext3D::isEnabled):
+ (WebCore::GraphicsContext3D::isFramebuffer):
+ (WebCore::GraphicsContext3D::isProgram):
+ (WebCore::GraphicsContext3D::isRenderbuffer):
+ (WebCore::GraphicsContext3D::isShader):
+ (WebCore::GraphicsContext3D::isTexture):
+ (WebCore::GraphicsContext3D::lineWidth):
+ (WebCore::GraphicsContext3D::linkProgram):
+ (WebCore::GraphicsContext3D::pixelStorei):
+ (WebCore::GraphicsContext3D::polygonOffset):
+ (WebCore::GraphicsContext3D::readPixels):
+ (WebCore::GraphicsContext3D::releaseShaderCompiler):
+ (WebCore::GraphicsContext3D::renderbufferStorage):
+ (WebCore::GraphicsContext3D::sampleCoverage):
+ (WebCore::GraphicsContext3D::scissor):
+ (WebCore::GraphicsContext3D::shaderSource):
+ (WebCore::GraphicsContext3D::stencilFunc):
+ (WebCore::GraphicsContext3D::stencilFuncSeparate):
+ (WebCore::GraphicsContext3D::stencilMask):
+ (WebCore::GraphicsContext3D::stencilMaskSeparate):
+ (WebCore::GraphicsContext3D::stencilOp):
+ (WebCore::GraphicsContext3D::stencilOpSeparate):
+ (WebCore::GraphicsContext3D::texParameterf):
+ (WebCore::GraphicsContext3D::texParameteri):
+ (WebCore::GraphicsContext3D::uniform1f):
+ (WebCore::GraphicsContext3D::uniform1fv):
+ (WebCore::GraphicsContext3D::uniform2f):
+ (WebCore::GraphicsContext3D::uniform2fv):
+ (WebCore::GraphicsContext3D::uniform3f):
+ (WebCore::GraphicsContext3D::uniform3fv):
+ (WebCore::GraphicsContext3D::uniform4f):
+ (WebCore::GraphicsContext3D::uniform4fv):
+ (WebCore::GraphicsContext3D::uniform1i):
+ (WebCore::GraphicsContext3D::uniform1iv):
+ (WebCore::GraphicsContext3D::uniform2i):
+ (WebCore::GraphicsContext3D::uniform2iv):
+ (WebCore::GraphicsContext3D::uniform3i):
+ (WebCore::GraphicsContext3D::uniform3iv):
+ (WebCore::GraphicsContext3D::uniform4i):
+ (WebCore::GraphicsContext3D::uniform4iv):
+ (WebCore::GraphicsContext3D::uniformMatrix2fv):
+ (WebCore::GraphicsContext3D::uniformMatrix3fv):
+ (WebCore::GraphicsContext3D::uniformMatrix4fv):
+ (WebCore::GraphicsContext3D::useProgram):
+ (WebCore::GraphicsContext3D::validateProgram):
+ (WebCore::GraphicsContext3D::vertexAttrib1f):
+ (WebCore::GraphicsContext3D::vertexAttrib1fv):
+ (WebCore::GraphicsContext3D::vertexAttrib2f):
+ (WebCore::GraphicsContext3D::vertexAttrib2fv):
+ (WebCore::GraphicsContext3D::vertexAttrib3f):
+ (WebCore::GraphicsContext3D::vertexAttrib3fv):
+ (WebCore::GraphicsContext3D::vertexAttrib4f):
+ (WebCore::GraphicsContext3D::vertexAttrib4fv):
+ (WebCore::GraphicsContext3D::vertexAttribPointer):
+ (WebCore::GraphicsContext3D::viewport):
+ (WebCore::GraphicsContext3D::getBooleanv):
+ (WebCore::GraphicsContext3D::getBufferParameteriv):
+ (WebCore::GraphicsContext3D::getFloatv):
+ (WebCore::GraphicsContext3D::getFramebufferAttachmentParameteriv):
+ (WebCore::GraphicsContext3D::getIntegerv):
+ (WebCore::GraphicsContext3D::getProgramiv):
+ (WebCore::GraphicsContext3D::getProgramInfoLog):
+ (WebCore::GraphicsContext3D::getRenderbufferParameteriv):
+ (WebCore::GraphicsContext3D::getShaderiv):
+ (WebCore::GraphicsContext3D::getShaderInfoLog):
+ (WebCore::GraphicsContext3D::getShaderSource):
+ (WebCore::GraphicsContext3D::getTexParameterfv):
+ (WebCore::GraphicsContext3D::getTexParameteriv):
+ (WebCore::GraphicsContext3D::getUniformfv):
+ (WebCore::GraphicsContext3D::getUniformiv):
+ (WebCore::GraphicsContext3D::getUniformLocation):
+ (WebCore::GraphicsContext3D::getVertexAttribfv):
+ (WebCore::GraphicsContext3D::getVertexAttribiv):
+ (WebCore::GraphicsContext3D::getVertexAttribOffset):
+ (WebCore::GraphicsContext3D::texImage2D):
+ (WebCore::GraphicsContext3D::texSubImage2D):
+ (WebCore::GraphicsContext3D::createBuffer):
+ (WebCore::GraphicsContext3D::createFramebuffer):
+ (WebCore::GraphicsContext3D::createProgram):
+ (WebCore::GraphicsContext3D::createRenderbuffer):
+ (WebCore::GraphicsContext3D::createShader):
+ (WebCore::GraphicsContext3D::createTexture):
+ (WebCore::GraphicsContext3D::deleteBuffer):
+ (WebCore::GraphicsContext3D::deleteFramebuffer):
+ (WebCore::GraphicsContext3D::deleteProgram):
+ (WebCore::GraphicsContext3D::deleteRenderbuffer):
+ (WebCore::GraphicsContext3D::deleteShader):
+ (WebCore::GraphicsContext3D::deleteTexture):
+ (WebCore::GraphicsContext3D::sizeInBytes):
+ (WebCore::GraphicsContext3D::synthesizeGLError):
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ Force 2d canvases to be rendered in software when the composite operation isn't source-over
+ https://bugs.webkit.org/show_bug.cgi?id=45216
+
+ The current accelerated 2d canvas implementation is very slow for composite operations other
+ than the default. This patch forces a canvas to be rendered in software if any other operation
+ is set until we accelerate the rest.
+
+ Tested by any of the fast/canvas tests that use a non-default globalCompositeOperation.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::setGlobalCompositeOperation):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::setSharedGraphicsContext3D):
+
+2010-09-03 Paul Sawaya <psawaya@apple.com>
+
+ Reviewed by Chris Marrin.
+
+ Refactored out Mac specific code for platform/graphics/mac/GraphicsContext3D.mm file.
+ Left general OpenGL code in platform/graphics/GraphicsContext3DOpenGL.cpp.
+ https://bugs.webkit.org/show_bug.cgi?id=30625
+
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/canvas/WebGLObject.cpp:
+ (WebCore::WebGLObject::deleteObject):
+ * platform/graphics/ANGLEWebKitBridge.h:
+ * platform/graphics/GraphicsContext3D.h:
+ * platform/graphics/GraphicsContext3DOpenGL.cpp: Copied from platform/graphics/mac/GraphicsContext3DMac.mm.
+ (WebCore::GraphicsContext3D::prepareTexture):
+ (WebCore::GraphicsContext3D::activeTexture):
+ (WebCore::GraphicsContext3D::attachShader):
+ (WebCore::GraphicsContext3D::bindAttribLocation):
+ (WebCore::GraphicsContext3D::bindBuffer):
+ (WebCore::GraphicsContext3D::bindFramebuffer):
+ (WebCore::GraphicsContext3D::bindRenderbuffer):
+ (WebCore::GraphicsContext3D::bindTexture):
+ (WebCore::GraphicsContext3D::blendColor):
+ (WebCore::GraphicsContext3D::blendEquation):
+ (WebCore::GraphicsContext3D::blendEquationSeparate):
+ (WebCore::GraphicsContext3D::blendFunc):
+ (WebCore::GraphicsContext3D::blendFuncSeparate):
+ (WebCore::GraphicsContext3D::bufferData):
+ (WebCore::GraphicsContext3D::bufferSubData):
+ (WebCore::GraphicsContext3D::checkFramebufferStatus):
+ (WebCore::GraphicsContext3D::clearColor):
+ (WebCore::GraphicsContext3D::clear):
+ (WebCore::GraphicsContext3D::clearDepth):
+ (WebCore::GraphicsContext3D::clearStencil):
+ (WebCore::GraphicsContext3D::colorMask):
+ (WebCore::GraphicsContext3D::compileShader):
+ (WebCore::GraphicsContext3D::copyTexImage2D):
+ (WebCore::GraphicsContext3D::copyTexSubImage2D):
+ (WebCore::GraphicsContext3D::cullFace):
+ (WebCore::GraphicsContext3D::depthFunc):
+ (WebCore::GraphicsContext3D::depthMask):
+ (WebCore::GraphicsContext3D::depthRange):
+ (WebCore::GraphicsContext3D::detachShader):
+ (WebCore::GraphicsContext3D::disable):
+ (WebCore::GraphicsContext3D::disableVertexAttribArray):
+ (WebCore::GraphicsContext3D::drawArrays):
+ (WebCore::GraphicsContext3D::drawElements):
+ (WebCore::GraphicsContext3D::enable):
+ (WebCore::GraphicsContext3D::enableVertexAttribArray):
+ (WebCore::GraphicsContext3D::finish):
+ (WebCore::GraphicsContext3D::flush):
+ (WebCore::GraphicsContext3D::framebufferRenderbuffer):
+ (WebCore::GraphicsContext3D::framebufferTexture2D):
+ (WebCore::GraphicsContext3D::frontFace):
+ (WebCore::GraphicsContext3D::generateMipmap):
+ (WebCore::GraphicsContext3D::getActiveAttrib):
+ (WebCore::GraphicsContext3D::getActiveUniform):
+ (WebCore::GraphicsContext3D::getAttachedShaders):
+ (WebCore::GraphicsContext3D::getAttribLocation):
+ (WebCore::GraphicsContext3D::getError):
+ (WebCore::GraphicsContext3D::getString):
+ (WebCore::GraphicsContext3D::hint):
+ (WebCore::GraphicsContext3D::isBuffer):
+ (WebCore::GraphicsContext3D::isEnabled):
+ (WebCore::GraphicsContext3D::isFramebuffer):
+ (WebCore::GraphicsContext3D::isProgram):
+ (WebCore::GraphicsContext3D::isRenderbuffer):
+ (WebCore::GraphicsContext3D::isShader):
+ (WebCore::GraphicsContext3D::isTexture):
+ (WebCore::GraphicsContext3D::lineWidth):
+ (WebCore::GraphicsContext3D::linkProgram):
+ (WebCore::GraphicsContext3D::pixelStorei):
+ (WebCore::GraphicsContext3D::polygonOffset):
+ (WebCore::GraphicsContext3D::readPixels):
+ (WebCore::GraphicsContext3D::releaseShaderCompiler):
+ (WebCore::GraphicsContext3D::renderbufferStorage):
+ (WebCore::GraphicsContext3D::sampleCoverage):
+ (WebCore::GraphicsContext3D::scissor):
+ (WebCore::GraphicsContext3D::shaderSource):
+ (WebCore::GraphicsContext3D::stencilFunc):
+ (WebCore::GraphicsContext3D::stencilFuncSeparate):
+ (WebCore::GraphicsContext3D::stencilMask):
+ (WebCore::GraphicsContext3D::stencilMaskSeparate):
+ (WebCore::GraphicsContext3D::stencilOp):
+ (WebCore::GraphicsContext3D::stencilOpSeparate):
+ (WebCore::GraphicsContext3D::texParameterf):
+ (WebCore::GraphicsContext3D::texParameteri):
+ (WebCore::GraphicsContext3D::uniform1f):
+ (WebCore::GraphicsContext3D::uniform1fv):
+ (WebCore::GraphicsContext3D::uniform2f):
+ (WebCore::GraphicsContext3D::uniform2fv):
+ (WebCore::GraphicsContext3D::uniform3f):
+ (WebCore::GraphicsContext3D::uniform3fv):
+ (WebCore::GraphicsContext3D::uniform4f):
+ (WebCore::GraphicsContext3D::uniform4fv):
+ (WebCore::GraphicsContext3D::uniform1i):
+ (WebCore::GraphicsContext3D::uniform1iv):
+ (WebCore::GraphicsContext3D::uniform2i):
+ (WebCore::GraphicsContext3D::uniform2iv):
+ (WebCore::GraphicsContext3D::uniform3i):
+ (WebCore::GraphicsContext3D::uniform3iv):
+ (WebCore::GraphicsContext3D::uniform4i):
+ (WebCore::GraphicsContext3D::uniform4iv):
+ (WebCore::GraphicsContext3D::uniformMatrix2fv):
+ (WebCore::GraphicsContext3D::uniformMatrix3fv):
+ (WebCore::GraphicsContext3D::uniformMatrix4fv):
+ (WebCore::GraphicsContext3D::useProgram):
+ (WebCore::GraphicsContext3D::validateProgram):
+ (WebCore::GraphicsContext3D::vertexAttrib1f):
+ (WebCore::GraphicsContext3D::vertexAttrib1fv):
+ (WebCore::GraphicsContext3D::vertexAttrib2f):
+ (WebCore::GraphicsContext3D::vertexAttrib2fv):
+ (WebCore::GraphicsContext3D::vertexAttrib3f):
+ (WebCore::GraphicsContext3D::vertexAttrib3fv):
+ (WebCore::GraphicsContext3D::vertexAttrib4f):
+ (WebCore::GraphicsContext3D::vertexAttrib4fv):
+ (WebCore::GraphicsContext3D::vertexAttribPointer):
+ (WebCore::GraphicsContext3D::viewport):
+ (WebCore::GraphicsContext3D::getBooleanv):
+ (WebCore::GraphicsContext3D::getBufferParameteriv):
+ (WebCore::GraphicsContext3D::getFloatv):
+ (WebCore::GraphicsContext3D::getFramebufferAttachmentParameteriv):
+ (WebCore::GraphicsContext3D::getIntegerv):
+ (WebCore::GraphicsContext3D::getProgramiv):
+ (WebCore::GraphicsContext3D::getProgramInfoLog):
+ (WebCore::GraphicsContext3D::getRenderbufferParameteriv):
+ (WebCore::GraphicsContext3D::getShaderiv):
+ (WebCore::GraphicsContext3D::getShaderInfoLog):
+ (WebCore::GraphicsContext3D::getShaderSource):
+ (WebCore::GraphicsContext3D::getTexParameterfv):
+ (WebCore::GraphicsContext3D::getTexParameteriv):
+ (WebCore::GraphicsContext3D::getUniformfv):
+ (WebCore::GraphicsContext3D::getUniformiv):
+ (WebCore::GraphicsContext3D::getUniformLocation):
+ (WebCore::GraphicsContext3D::getVertexAttribfv):
+ (WebCore::GraphicsContext3D::getVertexAttribiv):
+ (WebCore::GraphicsContext3D::getVertexAttribOffset):
+ (WebCore::GraphicsContext3D::texImage2D):
+ (WebCore::GraphicsContext3D::texSubImage2D):
+ (WebCore::GraphicsContext3D::createBuffer):
+ (WebCore::GraphicsContext3D::createFramebuffer):
+ (WebCore::GraphicsContext3D::createProgram):
+ (WebCore::GraphicsContext3D::createRenderbuffer):
+ (WebCore::GraphicsContext3D::createShader):
+ (WebCore::GraphicsContext3D::createTexture):
+ (WebCore::GraphicsContext3D::deleteBuffer):
+ (WebCore::GraphicsContext3D::deleteFramebuffer):
+ (WebCore::GraphicsContext3D::deleteProgram):
+ (WebCore::GraphicsContext3D::deleteRenderbuffer):
+ (WebCore::GraphicsContext3D::deleteShader):
+ (WebCore::GraphicsContext3D::deleteTexture):
+ * platform/graphics/mac/GraphicsContext3DMac.mm:
+ (WebCore::GraphicsContext3D::ensureContext):
+ (WebCore::GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses):
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Implement ImageBufferSkia::draw on the GPU when possible
+ https://bugs.webkit.org/show_bug.cgi?id=45207
+
+ When drawing from an ImageBuffer into a GraphicsContext, attempt to do the
+ draw in hardware when possible. This is how canvas 2d's drawImage(canvas, ...)
+ is implemented. Adds new API to DrawingBuffer to request a texture containing
+ the DrawingBuffer's current rendering results.
+
+ Test: covered fast/canvas/drawImage.html and all other tests that draw from one
+ 2d canvas into another.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::drawImage):
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBuffer::getRenderingResultsAsTexture):
+ * platform/graphics/gpu/DrawingBuffer.h:
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::draw):
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Kenneth Russell.
+
+ [chromium] Null out Canvas2DLayerChromium's back reference to DrawingBuffer on destruction
+ https://bugs.webkit.org/show_bug.cgi?id=45187
+
+ Canvas2DLayerChromium keeps a back reference to a DrawingBuffer. This has to be a raw pointer
+ because the DrawingBuffer holds a RefPtr to the Canvas2DLayerChromium. Since the layer can
+ outlive the buffer, this back reference has to be explicitly cleared when the DrawingBuffer
+ is destroyed.
+
+ * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+ (WebCore::Canvas2DLayerChromium::setDrawingBuffer):
+ * platform/graphics/chromium/Canvas2DLayerChromium.h:
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBuffer::~DrawingBuffer):
+
+2010-09-03 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Add interval tree capable of holding plain old data (POD)
+ https://bugs.webkit.org/show_bug.cgi?id=45160
+
+ Adding an interval tree currently capable of holding types which
+ do not require their destructors to be called. POD is a slight
+ misnomer which will be corrected soon, hopefully by removing this
+ restriction.
+
+ This class is based on the augmentable property of the red/black
+ tree integrated under bug 45059.
+
+ Unit tests for the PODIntervalTree will be integrated separately
+ under bug 45161.
+
+ * WebCore.gypi:
+ * platform/graphics/gpu/PODInterval.h: Added.
+ (WebCore::PODInterval::PODInterval):
+ (WebCore::PODInterval::low):
+ (WebCore::PODInterval::high):
+ (WebCore::PODInterval::data):
+ (WebCore::PODInterval::overlaps):
+ (WebCore::PODInterval::operator<):
+ (WebCore::PODInterval::operator==):
+ (WebCore::PODInterval::maxHigh):
+ (WebCore::PODInterval::setMaxHigh):
+ (WebCore::PODInterval::toString):
+ * platform/graphics/gpu/PODIntervalTree.h: Added.
+ (WebCore::PODIntervalTree::PODIntervalTree):
+ (WebCore::PODIntervalTree::allOverlaps):
+ (WebCore::PODIntervalTree::createInterval):
+ (WebCore::PODIntervalTree::checkInvariants):
+ (WebCore::PODIntervalTree::init):
+ (WebCore::PODIntervalTree::searchForOverlapsFrom):
+ (WebCore::PODIntervalTree::updateNode):
+ (WebCore::PODIntervalTree::checkInvariantsFromNode):
+ (WebCore::valueToString):
+
+2010-09-02 Vangelis Kokkevis <vangelis@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Gracefully switch over to software compositing if the accelerated
+ compositor fails to initialize. LayerRendererChromium::create() will now return 0
+ if the GLES2Context passed to it is NULL or the LayerRendererChromium failed to initialize
+ hardware rendering.
+ https://bugs.webkit.org/show_bug.cgi?id=45124
+
+ Tested by forcing the creation of the gles2 context to fail and loading pages that normally trigger
+ the compositor.
+
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::create):
+ (WebCore::LayerRendererChromium::LayerRendererChromium):
+ (WebCore::LayerRendererChromium::makeContextCurrent):
+
+2010-09-03 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Simon Fraser.
+
+ Report correct (unzoomed) image sizes for zoomed images.
+ https://bugs.webkit.org/show_bug.cgi?id=42089
+
+ Test: fast/images/zoomed-img-size.html
+
+ * css/CSSPrimitiveValue.cpp: Factor rounding code out to a templatized function so it can be shared.
+ (WebCore::CSSPrimitiveValue::computeLengthInt):
+ (WebCore::CSSPrimitiveValue::computeLengthIntForLength):
+ (WebCore::CSSPrimitiveValue::computeLengthShort):
+ * css/CSSPrimitiveValue.h: Factor rounding code out to a templatized function so it can be shared.
+ (WebCore::roundForImpreciseConversion):
+ * html/HTMLImageElement.cpp: Report unzoomed size to script that queries an image's width or height.
+ (WebCore::HTMLImageElement::width):
+ (WebCore::HTMLImageElement::height):
+ * loader/ImageDocument.cpp: Report unzoomed size in the page title when viewing a standalone image.
+ (WebCore::ImageDocumentParser::finish):
+ * rendering/RenderObject.h: Use shared rounding code from CSSPrimitiveValue to compensate for inexactness in zoomed sizes.
+ (WebCore::adjustForAbsoluteZoom):
+
+2010-09-03 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66770.
+ http://trac.webkit.org/changeset/66770
+ https://bugs.webkit.org/show_bug.cgi?id=45200
+
+ Broke Windows in a way I can't figure out now to fix
+ (Requested by abarth on #webkit).
+
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/generic/BindingDOMWindow.h:
+ (WebCore::::completeURL):
+ * bindings/generic/BindingFrame.h: Removed.
+ * bindings/generic/BindingLocation.h: Removed.
+ * bindings/generic/GenericBinding.h:
+ * bindings/js/JSBinding.h: Removed.
+ * bindings/js/JSBindingsAllInOne.cpp:
+ * bindings/js/JSDOMBinding.cpp:
+ (WebCore::shouldAllowNavigation):
+ (WebCore::toLexicalFrame):
+ (WebCore::toDynamicFrame):
+ (WebCore::processingUserGesture):
+ (WebCore::completeURL):
+ * bindings/js/JSLocationCustom.cpp:
+ (WebCore::navigateIfAllowed):
+ (WebCore::JSLocation::replace):
+ * bindings/js/specialization/JSBindingState.cpp: Removed.
+ * bindings/js/specialization/JSBindingState.h: Removed.
+ * bindings/v8/V8Binding.h:
+ * bindings/v8/V8Utilities.cpp:
+ (WebCore::completeURL):
+ (WebCore::navigateIfAllowed):
+ * bindings/v8/custom/V8LocationCustom.cpp:
+ (WebCore::V8Location::replaceCallback):
+ * bindings/v8/specialization/V8BindingState.cpp:
+ * bindings/v8/specialization/V8BindingState.h:
+
+2010-09-03 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ REGRESSION (r66452): Sending of multipart forms with files is broken.
+ https://bugs.webkit.org/show_bug.cgi?id=45159
+
+ * platform/network/FormData.cpp:
+ (WebCore::FormData::appendKeyValuePairItems):
+
+2010-09-03 Dominic Cooney <dominicc@google.com>
+
+ Reviewed by Adam Barth.
+
+ Moves location.replace bindings logic into bindings/generic and
+ instantiates it for JSC and V8.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44891
+
+ Covered by existing location.replace tests.
+
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/generic/BindingDOMWindow.h:
+ (WebCore::::createWindow):
+ (WebCore::::open):
+ * bindings/generic/BindingFrame.h: Added.
+ (WebCore::::navigateIfAllowed):
+ * bindings/generic/BindingLocation.h: Added.
+ (WebCore::::replace):
+ * bindings/generic/GenericBinding.h:
+ (WebCore::completeURL):
+ * bindings/js/JSBinding.h: Added.
+ * bindings/js/JSBindingsAllInOne.cpp:
+ * bindings/js/JSDOMBinding.cpp:
+ (WebCore::shouldAllowNavigation):
+ (WebCore::toLexicalFrame):
+ (WebCore::toDynamicFrame):
+ (WebCore::processingUserGesture):
+ (WebCore::completeURL):
+ * bindings/js/JSLocationCustom.cpp:
+ (WebCore::navigateIfAllowed):
+ (WebCore::JSLocation::replace):
+ * bindings/js/specialization/JSBindingState.cpp: Added.
+ (WebCore::::getActiveFrame):
+ (WebCore::::getFirstFrame):
+ (WebCore::::processingUserGesture):
+ (WebCore::::allowsAccessFromFrame):
+ * bindings/js/specialization/JSBindingState.h: Added.
+ * bindings/v8/V8Binding.h:
+ * bindings/v8/V8Utilities.cpp:
+ (WebCore::completeURL):
+ (WebCore::navigateIfAllowed):
+ * bindings/v8/custom/V8LocationCustom.cpp:
+ (WebCore::V8Location::replaceCallback):
+ * bindings/v8/specialization/V8BindingState.cpp:
+ (WebCore::::allowsAccessFromFrame):
+ * bindings/v8/specialization/V8BindingState.h:
+
+2010-09-03 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ [Chromium] Make sure that the width of the menu list is always constant under layout tests.
+ https://bugs.webkit.org/show_bug.cgi?id=45196
+
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::menuListButtonWidth): Added.
+ (WebCore::RenderThemeChromiumWin::paintMenuList): Use menuListButtonWidth instead of always
+ querying system metrics.
+
+2010-09-03 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66732.
+ http://trac.webkit.org/changeset/66732
+ https://bugs.webkit.org/show_bug.cgi?id=45195
+
+ the patch is not matched with general publish/subscribe scheme
+ implemented in the Inspector API (Requested by loislo on
+ #webkit).
+
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/Inspector.idl:
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::pushChildNodesToFrontend):
+ (WebCore::InspectorDOMAgent::getChildNodes):
+ * inspector/InspectorDOMAgent.h:
+ * inspector/front-end/DOMAgent.js:
+ (WebInspector.DOMAgent.prototype.getChildNodesAsync.mycallback):
+ (WebInspector.DOMAgent.prototype.getChildNodesAsync):
+ * inspector/front-end/WorkersSidebarPane.js:
+ (WebInspector.WorkersSidebarPane.prototype.reset):
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ [chromium] Compile fixes for 66746
+
+ * platform/graphics/gpu/SharedGraphicsContext3D.cpp:
+ (WebCore::SharedGraphicsContext3D::texImage2D):
+ (WebCore::SharedGraphicsContext3D::texSubImage2D):
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add AudioParam files
+ https://bugs.webkit.org/show_bug.cgi?id=44995
+
+ No new tests since audio API is not yet implemented.
+
+ * webaudio: Added.
+ * webaudio/AudioParam.h: Added.
+ (WebCore::AudioParam::create):
+ (WebCore::AudioParam::AudioParam):
+ (WebCore::AudioParam::value):
+ (WebCore::AudioParam::setValue):
+ (WebCore::AudioParam::name):
+ (WebCore::AudioParam::minValue):
+ (WebCore::AudioParam::maxValue):
+ (WebCore::AudioParam::defaultValue):
+ (WebCore::AudioParam::units):
+ (WebCore::AudioParam::smoothedValue):
+ (WebCore::AudioParam::smooth):
+ (WebCore::AudioParam::resetSmoothedValue):
+ (WebCore::AudioParam::setSmoothingConstant):
+ * webaudio/AudioParam.idl: Added.
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ audio engine: add AudioChannel files
+ https://bugs.webkit.org/show_bug.cgi?id=44921
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/AudioChannel.cpp: Added.
+ (WebCore::AudioChannel::scale):
+ (WebCore::AudioChannel::copyFrom):
+ (WebCore::AudioChannel::copyFromRange):
+ (WebCore::AudioChannel::sumFrom):
+ (WebCore::AudioChannel::maxAbsValue):
+ * platform/audio/AudioChannel.h: Added.
+ (WebCore::AudioChannel::AudioChannel):
+ (WebCore::AudioChannel::set):
+ (WebCore::AudioChannel::length):
+ (WebCore::AudioChannel::data):
+ (WebCore::AudioChannel::zero):
+
+2010-09-03 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ [WINCE] Remove usage of ce_textcodecs.h
+ https://bugs.webkit.org/show_bug.cgi?id=45169
+
+ ce_textcodecs.h was a non public header for (not required)
+ additonal codecs in the original Torch Mobile port.
+
+ * platform/text/wince/TextCodecWinCE.cpp:
+ (WebCore::LanguageManager::LanguageManager):
+ (WebCore::decode):
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Initial patch for audio engine: AudioBus and helper classes
+ https://bugs.webkit.org/show_bug.cgi?id=34452
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/AudioBus.cpp: Added.
+ (WebCore::AudioBus::AudioBus):
+ (WebCore::AudioBus::setChannelMemory):
+ (WebCore::AudioBus::zero):
+ (WebCore::AudioBus::channelByType):
+ (WebCore::AudioBus::topologyMatches):
+ (WebCore::AudioBus::createBufferFromRange):
+ (WebCore::AudioBus::maxAbsValue):
+ (WebCore::AudioBus::normalize):
+ (WebCore::AudioBus::scale):
+ (WebCore::AudioBus::copyFrom):
+ (WebCore::AudioBus::sumFrom):
+ (WebCore::AudioBus::processWithGainFromMonoStereo):
+ (WebCore::AudioBus::processWithGainFrom):
+ (WebCore::AudioBus::copyWithGainFrom):
+ (WebCore::AudioBus::sumWithGainFrom):
+ * platform/audio/AudioBus.h: Added.
+ (WebCore::AudioBus::numberOfChannels):
+ (WebCore::AudioBus::channel):
+ (WebCore::AudioBus::length):
+ (WebCore::AudioBus::sampleRate):
+ (WebCore::AudioBus::setSampleRate):
+ (WebCore::AudioBus::setGain):
+ (WebCore::AudioBus::gain):
+ (WebCore::AudioBus::reset):
+ (WebCore::AudioBus::AudioBus):
+ * platform/audio/AudioSourceProvider.h: Added.
+ (WebCore::AudioSourceProvider::~AudioSourceProvider):
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add Panner files
+ https://bugs.webkit.org/show_bug.cgi?id=45076
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/Panner.cpp: Added.
+ (WebCore::Panner::create):
+ * platform/audio/Panner.h: Added.
+ (WebCore::Panner::~Panner):
+ (WebCore::Panner::panningModel):
+ (WebCore::Panner::Panner):
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add AudioListener files
+ https://bugs.webkit.org/show_bug.cgi?id=45006
+
+ No new tests since audio API is not yet implemented.
+
+ * webaudio: Added.
+ * webaudio/AudioListener.cpp: Added.
+ (WebCore::AudioListener::AudioListener):
+ * webaudio/AudioListener.h: Added.
+ (WebCore::AudioListener::create):
+ (WebCore::AudioListener::setPosition):
+ (WebCore::AudioListener::position):
+ (WebCore::AudioListener::setOrientation):
+ (WebCore::AudioListener::orientation):
+ (WebCore::AudioListener::setUpVector):
+ (WebCore::AudioListener::upVector):
+ (WebCore::AudioListener::setVelocity):
+ (WebCore::AudioListener::velocity):
+ (WebCore::AudioListener::setDopplerFactor):
+ (WebCore::AudioListener::dopplerFactor):
+ (WebCore::AudioListener::setSpeedOfSound):
+ (WebCore::AudioListener::speedOfSound):
+ * webaudio/AudioListener.idl: Added.
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Unreviewed
+
+ Add WebCore/webaudio and WebCore/platform/audio/mac directories in preparation for landing reviewed patches
+ https://bugs.webkit.org/show_bug.cgi?id=45185
+
+ * platform/audio/mac: Added.
+ * webaudio: Added.
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Chris Marrin.
+
+ Multiple accelerated 2D canvases should be able to use the same GraphicsContext3D
+ https://bugs.webkit.org/show_bug.cgi?id=44926
+
+ This allows many accelerated 2d canvases to render using a single underlying GraphicsContext3D.
+ It introduces a new class SharedGraphicsContext3D that manages several callers. This class could
+ also cache the current state to avoid issuing redundant calls, although in this first cut it doesn't.
+ The SharedGraphicsContext3D is provided through the ChromeClient so that its lifetime can be tied to that
+ of the platform-specific compositor infrastructure.
+
+ Accelerated 2d canvases maintain a reference to a SharedGraphicsContext3D and have ownership of a CanvasFramebuffer,
+ which represents the canvas's rendering target. The compositing layer for an accelerated 2d canvas is
+ aware only of the canvas's CanvasFramebuffer. This means that WebGL and 2d canvases are no longer treated
+ as the same time of layer by the compositor.
+
+ Covered by existing canvas tests.
+
+ * WebCore.gypi:
+ * html/canvas/CanvasRenderingContext.cpp:
+ * html/canvas/CanvasRenderingContext.h:
+ (WebCore::CanvasRenderingContext::paintsIntoCanvasBuffer):
+ (WebCore::CanvasRenderingContext::platformLayer):
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::CanvasRenderingContext2D):
+ (WebCore::CanvasRenderingContext2D::paintsIntoCanvasBuffer):
+ (WebCore::CanvasRenderingContext2D::reset):
+ (WebCore::CanvasRenderingContext2D::didDraw):
+ (WebCore::CanvasRenderingContext2D::platformLayer):
+ * html/canvas/CanvasRenderingContext2D.h:
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::paintsIntoCanvasBuffer):
+ * html/canvas/WebGLRenderingContext.h:
+ (WebCore::WebGLRenderingContext::graphicsContext3D):
+ (WebCore::WebGLRenderingContext::platformLayer):
+ * loader/EmptyClients.h:
+ (WebCore::EmptyChromeClient::attachRootGraphicsLayer):
+ (WebCore::EmptyChromeClient::setNeedsOneShotDrawingSynchronization):
+ (WebCore::EmptyChromeClient::scheduleCompositingLayerSync):
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::getSharedGraphicsContext3D):
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::setSharedGraphicsContext3D):
+ (WebCore::GraphicsContext::syncSoftwareCanvas):
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/chromium/Canvas2DLayerChromium.cpp: Added.
+ (WebCore::Canvas2DLayerChromium::create):
+ (WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
+ (WebCore::Canvas2DLayerChromium::~Canvas2DLayerChromium):
+ (WebCore::Canvas2DLayerChromium::updateContents):
+ (WebCore::Canvas2DLayerChromium::setTextureChanged):
+ (WebCore::Canvas2DLayerChromium::textureId):
+ * platform/graphics/chromium/Canvas2DLayerChromium.h: Added.
+ (WebCore::Canvas2DLayerChromium::drawsContent):
+ * platform/graphics/chromium/CanvasLayerChromium.cpp:
+ (WebCore::CanvasLayerChromium::CanvasLayerChromium):
+ (WebCore::CanvasLayerChromium::~CanvasLayerChromium):
+ (WebCore::CanvasLayerChromium::draw):
+ * platform/graphics/chromium/CanvasLayerChromium.h:
+ * platform/graphics/chromium/DrawingBufferChromium.cpp: Added.
+ (WebCore::generateColorTexture):
+ (WebCore::DrawingBuffer::DrawingBuffer):
+ (WebCore::DrawingBuffer::~DrawingBuffer):
+ (WebCore::DrawingBuffer::publishToPlatformLayer):
+ (WebCore::DrawingBuffer::reset):
+ (WebCore::DrawingBuffer::platformLayer):
+ * platform/graphics/chromium/GLES2Canvas.cpp:
+ (WebCore::GLES2Canvas::GLES2Canvas):
+ (WebCore::GLES2Canvas::~GLES2Canvas):
+ (WebCore::GLES2Canvas::bindFramebuffer):
+ (WebCore::GLES2Canvas::clearRect):
+ (WebCore::GLES2Canvas::fillRect):
+ (WebCore::GLES2Canvas::drawTexturedRect):
+ (WebCore::GLES2Canvas::drawTexturedRectTile):
+ (WebCore::GLES2Canvas::drawQuad):
+ (WebCore::GLES2Canvas::createTexture):
+ (WebCore::GLES2Canvas::getTexture):
+ * platform/graphics/chromium/GLES2Canvas.h:
+ (WebCore::GLES2Canvas::context):
+ (WebCore::GLES2Canvas::drawingBuffer):
+ * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+ (WebCore::GraphicsLayerChromium::setContentsToCanvas):
+ * platform/graphics/chromium/GraphicsLayerChromium.h:
+ * platform/graphics/chromium/WebGLLayerChromium.cpp: Added.
+ (WebCore::WebGLLayerChromium::create):
+ (WebCore::WebGLLayerChromium::WebGLLayerChromium):
+ (WebCore::WebGLLayerChromium::updateContents):
+ (WebCore::WebGLLayerChromium::setContext):
+ * platform/graphics/chromium/WebGLLayerChromium.h: Added.
+ (WebCore::WebGLLayerChromium::drawsContent):
+ * platform/graphics/gpu/DrawingBuffer.cpp: Added.
+ (WebCore::DrawingBuffer::create):
+ (WebCore::DrawingBuffer::bind):
+ (WebCore::DrawingBuffer::setWillPublishCallback):
+ * platform/graphics/gpu/DrawingBuffer.h: Added.
+ (WebCore::DrawingBuffer::size):
+ * platform/graphics/gpu/SharedGraphicsContext3D.cpp: Added.
+ (WebCore::SharedGraphicsContext3D::create):
+ (WebCore::SharedGraphicsContext3D::SharedGraphicsContext3D):
+ (WebCore::SharedGraphicsContext3D::~SharedGraphicsContext3D):
+ (WebCore::SharedGraphicsContext3D::makeContextCurrent):
+ (WebCore::SharedGraphicsContext3D::scissor):
+ (WebCore::SharedGraphicsContext3D::enable):
+ (WebCore::SharedGraphicsContext3D::disable):
+ (WebCore::SharedGraphicsContext3D::clearColor):
+ (WebCore::SharedGraphicsContext3D::clear):
+ (WebCore::SharedGraphicsContext3D::drawArrays):
+ (WebCore::SharedGraphicsContext3D::getError):
+ (WebCore::SharedGraphicsContext3D::getIntegerv):
+ (WebCore::SharedGraphicsContext3D::createFramebuffer):
+ (WebCore::SharedGraphicsContext3D::createTexture):
+ (WebCore::SharedGraphicsContext3D::deleteFramebuffer):
+ (WebCore::SharedGraphicsContext3D::deleteTexture):
+ (WebCore::SharedGraphicsContext3D::framebufferTexture2D):
+ (WebCore::SharedGraphicsContext3D::texParameteri):
+ (WebCore::SharedGraphicsContext3D::texImage2D):
+ (WebCore::SharedGraphicsContext3D::texSubImage2D):
+ (WebCore::SharedGraphicsContext3D::readPixels):
+ (WebCore::SharedGraphicsContext3D::supportsBGRA):
+ (WebCore::SharedGraphicsContext3D::getTexture):
+ (WebCore::SharedGraphicsContext3D::applyCompositeOperator):
+ (WebCore::SharedGraphicsContext3D::useQuadVertices):
+ (WebCore::SharedGraphicsContext3D::setActiveTexture):
+ (WebCore::SharedGraphicsContext3D::bindTexture):
+ (WebCore::SharedGraphicsContext3D::useFillSolidProgram):
+ (WebCore::SharedGraphicsContext3D::useTextureProgram):
+ (WebCore::SharedGraphicsContext3D::bindFramebuffer):
+ (WebCore::SharedGraphicsContext3D::setViewport):
+ (WebCore::SharedGraphicsContext3D::paintsIntoCanvasBuffer):
+ * platform/graphics/gpu/SharedGraphicsContext3D.h: Added.
+ * platform/graphics/gpu/Texture.cpp:
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::syncSoftwareCanvas):
+ (WebCore::GraphicsContext::setSharedGraphicsContext3D):
+ * platform/graphics/skia/ImageSkia.cpp:
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (WebCore::PlatformContextSkia::~PlatformContextSkia):
+ (WebCore::WillPublishCallbackImpl::create):
+ (WebCore::WillPublishCallbackImpl::willPublish):
+ (WebCore::WillPublishCallbackImpl::WillPublishCallbackImpl):
+ (WebCore::PlatformContextSkia::setSharedGraphicsContext3D):
+ (WebCore::PlatformContextSkia::uploadSoftwareToHardware):
+ (WebCore::PlatformContextSkia::readbackHardwareToSoftware):
+ * platform/graphics/skia/PlatformContextSkia.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration):
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Add audio distance effect files
+ https://bugs.webkit.org/show_bug.cgi?id=44705
+
+ No new tests since audio API is not yet implemented.
+
+ * platform/audio/Distance.cpp: Added.
+ (WebCore::DistanceEffect::DistanceEffect):
+ (WebCore::DistanceEffect::gain):
+ (WebCore::DistanceEffect::linearGain):
+ (WebCore::DistanceEffect::inverseGain):
+ (WebCore::DistanceEffect::exponentialGain):
+ * platform/audio/Distance.h: Added.
+ (WebCore::DistanceEffect::model):
+ (WebCore::DistanceEffect::setModel):
+ (WebCore::DistanceEffect::setRefDistance):
+ (WebCore::DistanceEffect::setMaxDistance):
+ (WebCore::DistanceEffect::setRolloffFactor):
+ (WebCore::DistanceEffect::refDistance):
+ (WebCore::DistanceEffect::maxDistance):
+ (WebCore::DistanceEffect::rolloffFactor):
+
+2010-09-03 Johnny Ding <jnd@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Save the gesture state to track the user gesture state across async form submission.
+ https://bugs.webkit.org/show_bug.cgi?id=44969
+
+ fast/events/popup-blocked-to-post-blank.html can cover the test in WebKit.
+ A UI test will be added in chromium to address chromium's bug.
+
+ * loader/RedirectScheduler.cpp:
+ (WebCore::ScheduledFormSubmission::ScheduledFormSubmission):
+ (WebCore::ScheduledFormSubmission::fire):
+ (WebCore::RedirectScheduler::scheduleFormSubmission):
+
+2010-09-03 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ <rdar://problem/8392655> REGRESSION (r57215): Decomposed diacritics render incorrectly when preceded by stacked diacritics
+ https://bugs.webkit.org/show_bug.cgi?id=45182
+
+ Test: fast/text/decomposed-after-stacked-diacritics.html
+
+ * platform/graphics/Font.cpp:
+ (WebCore::Font::codePath): Do not bail out if the run contains stacked diacritics, since
+ it may also contain characters that require the complex text code path.
+
+2010-09-03 Mikhail Naganov <mnaganov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: Cleanup after r66117 - extract heap snapshot
+ view styles into a dedicated .css
+
+ https://bugs.webkit.org/show_bug.cgi?id=45178
+
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/heapProfiler.css: Added.
+ (.heap-snapshot-sidebar-tree-item .icon):
+ (.heap-snapshot-sidebar-tree-item.small .icon):
+ (.heap-snapshot-view):
+ (.heap-snapshot-view.visible):
+ (.heap-snapshot-view .data-grid):
+ (.heap-snapshot-view .data-grid th.count-column):
+ (.heap-snapshot-view .data-grid td.count-column):
+ (.heap-snapshot-view .data-grid th.size-column):
+ (.heap-snapshot-view .data-grid td.size-column):
+ (.heap-snapshot-view .data-grid th.countDelta-column):
+ (.heap-snapshot-view .data-grid td.countDelta-column):
+ (.heap-snapshot-view .data-grid th.sizeDelta-column):
+ (.heap-snapshot-view .data-grid td.sizeDelta-column):
+ (#heap-snapshot-summary-container):
+ (.heap-snapshot-summary):
+ (.heap-snapshot-summary canvas.summary-graph):
+ (.heap-snapshot-summary-label):
+ * inspector/front-end/inspector.css:
+ * inspector/front-end/inspector.html:
+
+2010-09-03 Zaheer Ahmad <zaheer.mot@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ [GTK] compilation issue with JSTimeRanges when video turned off
+ https://bugs.webkit.org/show_bug.cgi?id=44249
+
+ Move the JSTimeRanges outside ENABLE_VIDEO in GNUMakefile.am
+ * WebCore/GNUMakefile.am
+
+2010-09-03 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: cleanup inspector api. getChildNodes should return array of child nodes as an output value.
+
+ The current implementation of the inspector api has some unnecessary complexity.
+ As example WebInspector is requesting child nodes of a node by getChildNodes
+ but DOM agent is actually pushing the child nodes via setChildNodes event call and
+ send back an empty response message.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45172
+
+ * inspector/CodeGeneratorInspector.pm:
+ * inspector/Inspector.idl:
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::getChildNodesArray):
+ (WebCore::InspectorDOMAgent::pushChildNodesToFrontend):
+ (WebCore::InspectorDOMAgent::getChildNodes):
+ * inspector/InspectorDOMAgent.h:
+ * inspector/front-end/DOMAgent.js:
+ (WebInspector.DOMAgent.prototype.getChildNodesAsync.mycallback):
+ (WebInspector.DOMAgent.prototype.getChildNodesAsync):
+ * inspector/front-end/WorkersSidebarPane.js:
+ (WebInspector.WorkersSidebarPane.prototype.reset):
+
+2010-09-03 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ SVG atlas map slider doesn't work properly
+ https://bugs.webkit.org/show_bug.cgi?id=45107
+
+ SVG 1.1 2nd edition relaxes hit testing rules. The outermost <svg> should react
+ to mouse events, in standalone and compound documents, if the mouse location is
+ within the intrinsic boundaries of the <svg> element.
+
+ Tests: svg/custom/mouse-move-on-svg-container-standalone.svg
+ svg/custom/mouse-move-on-svg-container.xhtml
+ svg/custom/mouse-move-on-svg-root-standalone.svg
+ svg/custom/mouse-move-on-svg-root.xhtml
+
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::nodeAtPoint):
+
+2010-09-03 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: provide more information to front-end when breaking on DOM event
+ https://bugs.webkit.org/show_bug.cgi?id=44679
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::insertBefore):
+ (WebCore::ContainerNode::parserInsertBefore):
+ (WebCore::ContainerNode::replaceChild):
+ (WebCore::ContainerNode::appendChild):
+ (WebCore::ContainerNode::parserAddChild):
+ (WebCore::notifyChildInserted):
+ (WebCore::dispatchChildRemovalEvents):
+ * dom/Element.cpp:
+ (WebCore::Element::setAttribute):
+ (WebCore::Element::removeAttribute):
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::willInsertDOMNodeImpl):
+ (WebCore::InspectorController::didInsertDOMNodeImpl):
+ (WebCore::InspectorController::willRemoveDOMNodeImpl):
+ (WebCore::InspectorController::didRemoveDOMNodeImpl):
+ (WebCore::InspectorController::willModifyDOMAttrImpl):
+ (WebCore::InspectorController::didModifyDOMAttrImpl):
+ * inspector/InspectorController.h:
+ (WebCore::InspectorController::willInsertDOMNode):
+ (WebCore::InspectorController::didInsertDOMNode):
+ (WebCore::InspectorController::willRemoveDOMNode):
+ (WebCore::InspectorController::willModifyDOMAttr):
+ (WebCore::InspectorController::didModifyDOMAttr):
+ (WebCore::InspectorController::inspectorControllerForNode):
+ * inspector/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::~InspectorDOMAgent):
+ (WebCore::InspectorDOMAgent::shouldBreakOnNodeInsertion):
+ (WebCore::InspectorDOMAgent::shouldBreakOnNodeRemoval):
+ (WebCore::InspectorDOMAgent::shouldBreakOnAttributeModification):
+ (WebCore::InspectorDOMAgent::didInsertDOMNode):
+ (WebCore::InspectorDOMAgent::didRemoveDOMNode):
+ (WebCore::InspectorDOMAgent::didModifyDOMAttr):
+ (WebCore::InspectorDOMAgent::createBreakpoint):
+ * inspector/InspectorDOMAgent.h:
+ * inspector/InspectorDebuggerAgent.cpp:
+ (WebCore::InspectorDebuggerAgent::InspectorDebuggerAgent):
+ (WebCore::InspectorDebuggerAgent::~InspectorDebuggerAgent):
+ (WebCore::InspectorDebuggerAgent::didPause):
+ (WebCore::InspectorDebuggerAgent::breakProgram):
+ * inspector/InspectorDebuggerAgent.h:
+ * inspector/InspectorValues.h:
+ (WebCore::InspectorValue::isNull):
+ * inspector/front-end/BreakpointsSidebarPane.js:
+ (WebInspector.BreakpointItem):
+ (WebInspector.BreakpointItem.prototype._enableChanged):
+ * inspector/front-end/Script.js:
+ (WebInspector.Script.prototype.get linesCount):
+ * inspector/front-end/inspector.js:
+ (WebInspector.pausedScript):
+
+2010-08-31 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ IDBCursor.continue() should reuse the .openCursor's IDBRequest object
+ https://bugs.webkit.org/show_bug.cgi?id=44953
+
+ This is to match the spec. This requires a modification to IDBRequest so
+ that multiple events can be queued up.
+
+ Note that the initial state for IDBRequest was removed from the spec.
+
+ Test: modified existing test to verify new behavior.
+
+ * storage/IDBAny.cpp:
+ (WebCore::IDBAny::createInvalid):
+ (WebCore::IDBAny::createNull):
+ (WebCore::IDBAny::setNull):
+ * storage/IDBAny.h:
+ (WebCore::IDBAny::create):
+ * storage/IDBCursor.cpp:
+ (WebCore::IDBCursor::IDBCursor):
+ (WebCore::IDBCursor::continueFunction):
+ * storage/IDBCursor.h:
+ (WebCore::IDBCursor::create):
+ * storage/IDBCursor.idl:
+ * storage/IDBRequest.cpp:
+ (WebCore::IDBRequest::IDBRequest):
+ (WebCore::IDBRequest::~IDBRequest):
+ (WebCore::IDBRequest::resetReadyState):
+ (WebCore::IDBRequest::onError):
+ (WebCore::IDBRequest::onSuccess):
+ (WebCore::IDBRequest::abort):
+ (WebCore::IDBRequest::timerFired):
+ (WebCore::IDBRequest::scheduleEvent):
+ * storage/IDBRequest.h:
+ * storage/IDBRequest.idl:
+
+2010-09-03 Bharathwaaj Srinivasan <bharathwaaj.s@gmail.com>
+
+ Reviewed by Xan Lopez.
+
+ Initialize keyboard events before passing plugins.
+ https://bugs.webkit.org/show_bug.cgi?id=44771
+
+ No new tests needed since this is a trivial fix.
+
+ * plugins/gtk/PluginViewGtk.cpp:
+ (WebCore::PluginView::handleKeyboardEvent):
+
+2010-09-03 Yury Semikhatsky <yurys@chromium.org>
+
+ Unreviewed. Fix Qt compilation.
+
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::parametersForPlugin):
+
+2010-09-03 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ Adds textInputController.hasSpellingMarker() to avoid using pixel tests for spellchecking tests
+ and implements it for Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=41832
+
+ Tests: editing/spelling/spelling-contenteditable.html
+ editing/spelling/spelling-textarea.html
+
+ * WebCore.exp.in: Exported symbols used by [WebFrame hasSpellingMarker:length:].
+
+2010-09-02 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ REGRESSION: Crash occurs at objc_msgSend when closing a window that is displaying the web inspector
+ https://bugs.webkit.org/show_bug.cgi?id=44230
+
+ * inspector/Inspector.idl:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::inspectedPageDestroyed):
+ (WebCore::InspectorController::close):
+ * inspector/InspectorFrontendClient.h:
+ * inspector/InspectorFrontendHost.cpp:
+ (WebCore::InspectorFrontendHost::disconnectFromBackend): don't try to notify InspectorController
+ that frontend closes if InspectorController triggered the action.
+ * inspector/InspectorFrontendHost.h:
+ * inspector/InspectorFrontendHost.idl:
+ * inspector/front-end/InspectorFrontendHostStub.js:
+ (.WebInspector.InspectorFrontendHostStub.prototype.disconnectFromBackend):
+ * inspector/front-end/inspector.js:
+ (WebInspector.disconnectFromBackend):
+
+2010-09-03 Girish Ramakrishnan <girish@forwardbias.in>
+
+ Reviewed-by Simon Hausmann.
+
+ Passing a 32-bit depth X pixmap to NPAPI windowless plugins is too inefficient.
+ Instead, pass a X Pixmap that has same depth as the screen depth since graphics
+ operations are optimized for this depth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45167
+
+ * plugins/PluginPackage.cpp:
+ (WebCore::PluginPackage::determineQuirks):
+
+2010-09-02 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kent Tamura.
+
+ Add ENABLE(DATABASE) guard to DatabaseAuthorizer.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=45152
+
+ DatabaseAuthorizer is used only with ENABLE(DATABASE).
+
+ * storage/DatabaseAuthorizer.cpp:
+
+2010-09-02 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: persist DOM breakpoints between page reloads
+ https://bugs.webkit.org/show_bug.cgi?id=44837
+
+ * inspector/front-end/BreakpointsSidebarPane.js:
+ (WebInspector.DOMBreakpointItem):
+ * inspector/front-end/DOMAgent.js:
+ (WebInspector.DOMNode.prototype.path):
+ (WebInspector.DOMNode.prototype.setBreakpoint):
+ (WebInspector.DOMNode.prototype.hasBreakpoint):
+ (WebInspector.DOMNode.prototype.removeBreakpoint):
+ (WebInspector.DOMNode.prototype.removeBreakpoints):
+ (WebInspector.DOMAgent.prototype._setDocument):
+ (WebInspector.DOMAgent.prototype._childNodeRemoved):
+ (WebInspector.DOMAgent.prototype._removeBreakpoints):
+ (WebInspector.DOMBreakpointManager):
+ (WebInspector.DOMBreakpointManager.prototype.setBreakpoint):
+ (WebInspector.DOMBreakpointManager.prototype.removeBreakpointsForNode):
+ (WebInspector.DOMBreakpointManager.prototype._breakpointRemoved):
+ (WebInspector.DOMBreakpointManager.prototype.restoreBreakpoints.restoreBreakpointsForNode):
+ (WebInspector.DOMBreakpointManager.prototype.restoreBreakpoints):
+ (WebInspector.DOMBreakpoint):
+ (WebInspector.DOMBreakpoint.prototype.get nodeId):
+ (WebInspector.DOMBreakpoint.prototype.get type):
+ (WebInspector.DOMBreakpoint.prototype.set enabled):
+ (WebInspector.DOMBreakpoint.prototype.remove):
+ * inspector/front-end/ElementsPanel.js:
+ (WebInspector.ElementsPanel.prototype.reset):
+ (WebInspector.ElementsPanel.prototype.setDocument):
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype._populateTagContextMenu):
+ * inspector/front-end/SourceFrame.js:
+ (WebInspector.SourceFrame.prototype._showPopup.showObjectPopup):
+
+2010-09-02 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Move updateWidget into FrameView from RenderEmbeddedObject
+ https://bugs.webkit.org/show_bug.cgi?id=45065
+
+ I also made updateWidget() virtual on HTMLPlugInImageElement.
+ I'm not yet sure that updateWidget belongs on HTMLElement since
+ I'm not sure that HTMLMediaElement's use of the updateWidget
+ infrastructure is correct.
+
+ I also got rid of the strange !m_replacementText.isEmpty() checks
+ by making a pluginCrashedOrWasMissing() call which seems to embody
+ the idea behind that check and hides the screwy details.
+
+ I noticed a couple methods on HTMLPlugInImageElement were public
+ which did not need to be. Fixed.
+
+ No functional change, thus no tests.
+
+ * html/HTMLEmbedElement.h:
+ * html/HTMLObjectElement.h:
+ * html/HTMLPlugInImageElement.cpp:
+ (WebCore::HTMLPlugInImageElement::updateWidgetIfNecessary):
+ * html/HTMLPlugInImageElement.h:
+ (WebCore::HTMLPlugInImageElement::serviceType):
+ (WebCore::HTMLPlugInImageElement::url):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateWidget):
+ (WebCore::FrameView::updateWidgets):
+ * page/FrameView.h:
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::RenderEmbeddedObject::pluginCrashedOrWasMissing):
+ (WebCore::RenderEmbeddedObject::paint):
+ (WebCore::RenderEmbeddedObject::paintReplaced):
+ * rendering/RenderEmbeddedObject.h:
+
+2010-09-02 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Move updateWidget implementations into the DOM
+ https://bugs.webkit.org/show_bug.cgi?id=45058
+
+ Unfortunately it's not yet possible to share an updateWidget
+ implementation between <embed> and <object>. That would amount to
+ (positive) functional changes for <embed> which I'd will separate
+ into a later patch. I will also have to untangle <object>'s <param>
+ walk from its url/serviceType calculations.
+
+ However after this patch it's slap-you-across-the-face obvious that
+ RenderEmbeddedObject::updateWidget was the wrong place for this code.
+ RenderEmbeddedObject::updateWidget still exists, but only as a
+ pseudo-virtual-method dispatcher. Unless we add updateWidget() to
+ HTMLElement, we won't be able to use real virtual dispatch.
+
+ I may need to consider making "having a widget" a has-a relationship
+ with some sort of WidgetContainer object which Media and Plugin can
+ share. Or its also possible that Media's use of the widget code here
+ is just wrong. Certainly now that updateWidget was moved into HTMLMediaElement
+ it becomes obvious that HTMLMediaElement has duplicate code for updating widgets.
+
+ No functional changes, thus no tests.
+
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::updateWidget):
+ * html/HTMLEmbedElement.h:
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::updateWidget):
+ * html/HTMLMediaElement.h:
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::updateWidget):
+ * html/HTMLObjectElement.h:
+ (WebCore::HTMLObjectElement::useFallbackContent):
+ * html/HTMLPlugInImageElement.h:
+ (WebCore::HTMLPlugInImageElement::needsWidgetUpdate):
+ (WebCore::HTMLPlugInImageElement::setNeedsWidgetUpdate):
+ * loader/FrameLoader.cpp:
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::RenderEmbeddedObject::updateWidget):
+
+2010-09-02 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Move more code from RenderEmbeddedObject into the DOM
+ https://bugs.webkit.org/show_bug.cgi?id=45055
+
+ No logic changes here, just taking the code which
+ I ripped out of RenderEmbeddedObject::updateWidget
+ into static methods before and moving it into
+ the applicable DOM classes.
+
+ HTMLObjectElement::parametersForPlugin does too much
+ but in order to fix it I may need to add a PluginParameters
+ class so we can ask things about the parameters. <object>
+ needs to get multiple bits of information out of its parameters
+ array. Right now it does it all in one walk. In order to share
+ code with HTMLEmbedElement, we need the "generate the params array"
+ code to be separate from the "make advanced <object> specific decision
+ from the params array". But that will need to be in a later patch.
+
+ No functional changes, thus no tests.
+
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::parametersForPlugin):
+ * html/HTMLEmbedElement.h:
+ * html/HTMLObjectElement.cpp:
+ (WebCore::createClassIdToTypeMap):
+ (WebCore::serviceTypeForClassId):
+ (WebCore::mapDataParamToSrc):
+ (WebCore::HTMLObjectElement::parametersForPlugin):
+ (WebCore::HTMLObjectElement::hasFallbackContent):
+ * html/HTMLObjectElement.h:
+ * html/HTMLPlugInImageElement.cpp:
+ (WebCore::HTMLPlugInImageElement::allowedToLoadFrameURL):
+ (WebCore::HTMLPlugInImageElement::wouldLoadAsNetscapePlugin):
+ (WebCore::HTMLPlugInImageElement::detach):
+ (WebCore::HTMLPlugInImageElement::updateWidgetIfNecessary):
+ (WebCore::HTMLPlugInImageElement::updateWidgetCallback):
+ * html/HTMLPlugInImageElement.h:
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::updateWidgetForObjectElement):
+ (WebCore::updateWidgetForEmbedElement):
+ (WebCore::RenderEmbeddedObject::updateWidget):
+
+2010-09-02 François Sausset <sausset@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ MathML mo element should render "hyphen-minus" as "minus sign" (Unicode glyph names).
+ https://bugs.webkit.org/show_bug.cgi?id=43629
+
+ Test: mathml/presentation/mo.xhtml
+
+ * mathml/RenderMathMLOperator.cpp:
+ (WebCore::RenderMathMLOperator::RenderMathMLOperator):
+ (WebCore::RenderMathMLOperator::updateFromElement):
+ * mathml/RenderMathMLOperator.h:
+ (WebCore::convertHyphenMinusToMinusSign):
+ * platform/text/CharacterNames.h:
+
+2010-09-02 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Add red-black tree capable of holding plain old data (POD)
+ https://bugs.webkit.org/show_bug.cgi?id=45059
+
+ Adding an augmentable red-black tree capable of holding Plain Old
+ Data (POD), or classes bottoming out into only POD, and an
+ associated PODArena. Note that the PODArena will be used by other
+ classes to allocate temporary structures, which is why it is not
+ just an implementation detail of the red-black tree.
+
+ These classes are being placed under WebCore/platform/graphics/gpu
+ for the time being. If they are generalized to hold even data
+ types which internally perform dynamic memory allocation, we may
+ consider moving them to WTF in the future.
+
+ Unit tests for the PODRedBlackTree will be integrated separately
+ under bug 45060.
+
+ * WebCore.gypi:
+ * platform/graphics/gpu/PODArena.h: Added.
+ (WebCore::PODArena::Allocator::~Allocator):
+ (WebCore::PODArena::FastMallocAllocator::create):
+ (WebCore::PODArena::FastMallocAllocator::allocate):
+ (WebCore::PODArena::FastMallocAllocator::free):
+ (WebCore::PODArena::FastMallocAllocator::FastMallocAllocator):
+ (WebCore::PODArena::create):
+ (WebCore::PODArena::allocateObject):
+ (WebCore::PODArena::~PODArena):
+ (WebCore::PODArena::PODArena):
+ (WebCore::PODArena::minAlignment):
+ (WebCore::PODArena::roundUp):
+ (WebCore::PODArena::Chunk::Chunk):
+ (WebCore::PODArena::Chunk::~Chunk):
+ (WebCore::PODArena::Chunk::allocate):
+ * platform/graphics/gpu/PODRedBlackTree.h: Added.
+ (WebCore::PODRedBlackTree::Visitor::~Visitor):
+ (WebCore::PODRedBlackTree::PODRedBlackTree):
+ (WebCore::PODRedBlackTree::~PODRedBlackTree):
+ (WebCore::PODRedBlackTree::add):
+ (WebCore::PODRedBlackTree::remove):
+ (WebCore::PODRedBlackTree::contains):
+ (WebCore::PODRedBlackTree::visitInorder):
+ (WebCore::PODRedBlackTree::size):
+ (WebCore::PODRedBlackTree::setNeedsFullOrderingComparisons):
+ (WebCore::PODRedBlackTree::checkInvariants):
+ (WebCore::PODRedBlackTree::dump):
+ (WebCore::PODRedBlackTree::setVerboseDebugging):
+ (WebCore::PODRedBlackTree::Node::Node):
+ (WebCore::PODRedBlackTree::Node::~Node):
+ (WebCore::PODRedBlackTree::Node::color):
+ (WebCore::PODRedBlackTree::Node::setColor):
+ (WebCore::PODRedBlackTree::Node::data):
+ (WebCore::PODRedBlackTree::Node::copyFrom):
+ (WebCore::PODRedBlackTree::Node::left):
+ (WebCore::PODRedBlackTree::Node::setLeft):
+ (WebCore::PODRedBlackTree::Node::right):
+ (WebCore::PODRedBlackTree::Node::setRight):
+ (WebCore::PODRedBlackTree::Node::parent):
+ (WebCore::PODRedBlackTree::Node::setParent):
+ (WebCore::PODRedBlackTree::root):
+ (WebCore::PODRedBlackTree::updateNode):
+ (WebCore::PODRedBlackTree::treeSearch):
+ (WebCore::PODRedBlackTree::treeSearchNormal):
+ (WebCore::PODRedBlackTree::treeSearchFullComparisons):
+ (WebCore::PODRedBlackTree::treeInsert):
+ (WebCore::PODRedBlackTree::treeSuccessor):
+ (WebCore::PODRedBlackTree::treeMinimum):
+ (WebCore::PODRedBlackTree::propagateUpdates):
+ (WebCore::PODRedBlackTree::leftRotate):
+ (WebCore::PODRedBlackTree::rightRotate):
+ (WebCore::PODRedBlackTree::insertNode):
+ (WebCore::PODRedBlackTree::deleteFixup):
+ (WebCore::PODRedBlackTree::deleteNode):
+ (WebCore::PODRedBlackTree::visitInorderImpl):
+ (WebCore::PODRedBlackTree::Counter::Counter):
+ (WebCore::PODRedBlackTree::Counter::visit):
+ (WebCore::PODRedBlackTree::Counter::count):
+ (WebCore::PODRedBlackTree::checkInvariantsFromNode):
+ (WebCore::PODRedBlackTree::logIfVerbose):
+ (WebCore::PODRedBlackTree::dumpFromNode):
+
+2010-09-02 Rafael Antognolli <antognolli@profusion.mobi>
+
+ Reviewed by Martin Robinson.
+
+ [Cairo] Remove glib dependency (caused by use of GOwnPtr)
+ https://bugs.webkit.org/show_bug.cgi?id=45053
+
+ Use OwnPtr instead of GOwnPtr to keep track of Fc* references
+ in FontCacheCairo.cpp.
+
+ No features added, so no new tests.
+
+ * CMakeListsEfl.txt: Updating build system to look for GOwnPtrCairo.*
+ * GNUmakefile.am: Ditto.
+ * platform/graphics/cairo/FontCacheCairo.cpp: Using OwnPtr instead of GOwnPtr.
+ (WebCore::FontCache::createFontPlatformData):
+ * platform/graphics/cairo/GOwnPtrCairo.cpp: Removed.
+ * platform/graphics/cairo/GOwnPtrCairo.h: Removed.
+ * platform/graphics/cairo/OwnPtrCairo.cpp: Added.
+ (WTF::FcPattern):
+ (WTF::FcObjectSet):
+ (WTF::FcFontSet):
+ * platform/graphics/cairo/OwnPtrCairo.h: Added.
+
+2010-09-02 Kinuko Yasuda <kinuko@chromium.org>
+
+ Unreviewed, updating binding-tests expectations (for changeset 66521).
+
+ * bindings/scripts/test/V8/V8TestObj.cpp:
+ (WebCore::TestObjInternal::stringAttrAttrSetter):
+ (WebCore::TestObjInternal::reflectedStringAttrAttrSetter):
+ (WebCore::TestObjInternal::reflectedURLAttrAttrSetter):
+ (WebCore::TestObjInternal::reflectedNonEmptyURLAttrAttrSetter):
+ (WebCore::TestObjInternal::reflectedCustomURLAttrAttrSetter):
+ (WebCore::TestObjInternal::reflectedCustomNonEmptyURLAttrAttrSetter):
+ (WebCore::TestObjInternal::stringAttrWithGetterExceptionAttrSetter):
+ (WebCore::TestObjInternal::stringAttrWithSetterExceptionAttrSetter):
+
+2010-09-02 Adam Langley <agl@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [chromium] fix memory corruption in Khmer rendering.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44960
+
+ Test: fast/text/khmer-crash.html
+
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::TextRunWalker::shapeGlyphs):
+ The Khmer shaper has a bug where it would request larger output
+ buffers, but request a zero increase in size. Because of this we add
+ one to the requested size.
+ (WebCore::TextRunWalker::setGlyphXPositions):
+ The Khmer shaper is outputing cluster logs which suggest that some
+ output glyphs appear from nowhere (i.e. have no input codepoints). I
+ don't know Khmer, so maybe that's correct, but it broke the
+ assumptions of this code, causing a read out-of-bounds.
+ * platform/graphics/chromium/HarfbuzzSkia.cpp:
+ (WebCore::stringToGlyphs):
+ The Harfbuzz interfaces aren't documented, but it appears that the
+ output array to stringToGlyphs isn't sized and that Harfbuzz expects
+ us to detect when the input is too long.
+
+2010-09-02 Adam Roben <aroben@apple.com>
+
+ Fill the scroll corner with white when shouldPaintCustomScrollbars is
+ false
+
+ Previously we were only filling with white when
+ shouldPaintCustomScrollbars was true but the ChromeClient didn't paint
+ any custom scrollbars.
+
+ Reviewed by Sam Weinig.
+
+ * platform/ScrollbarThemeComposite.cpp:
+ (WebCore::ScrollbarThemeComposite::paintScrollCorner):
+
+2010-09-02 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66671.
+ http://trac.webkit.org/changeset/66671
+ https://bugs.webkit.org/show_bug.cgi?id=45115
+
+ http/tests/misc/redirect-to-about-blank.html is failing on
+ several platforms (Requested by japhet on #webkit).
+
+ * WebCore.exp.in:
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::updateURLForPushOrReplaceState):
+ * loader/DocumentWriter.cpp:
+ (WebCore::DocumentWriter::begin):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::iconURL):
+ (WebCore::FrameLoader::didOpenURL):
+ (WebCore::FrameLoader::didExplicitOpen):
+ (WebCore::FrameLoader::receivedFirstData):
+ (WebCore::FrameLoader::setURL):
+ (WebCore::FrameLoader::startIconLoader):
+ (WebCore::FrameLoader::commitIconURLToIconDatabase):
+ (WebCore::FrameLoader::finishedParsing):
+ (WebCore::FrameLoader::checkIfDisplayInsecureContent):
+ (WebCore::FrameLoader::checkIfRunInsecureContent):
+ (WebCore::FrameLoader::updateFirstPartyForCookies):
+ (WebCore::FrameLoader::loadInSameDocument):
+ (WebCore::FrameLoader::commitProvisionalLoad):
+ (WebCore::FrameLoader::open):
+ (WebCore::FrameLoader::shouldScrollToAnchor):
+ * loader/FrameLoader.h:
+ (WebCore::FrameLoader::url):
+
+2010-09-01 Zhenyao Mo <zmo@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Roll ANGLE under webkit to r402
+ https://bugs.webkit.org/show_bug.cgi?id=45004
+
+ * platform/graphics/mac/GraphicsContext3DMac.mm: Update the code to use newer ANGLE interface.
+ (WebCore::GraphicsContext3D::GraphicsContext3D):
+
+2010-09-02 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ WebInspector: Timeline instrumentation code can crash browser.
+
+ Steps:
+ 1) load the site
+ 2) open inspector
+ 3) start timeline recording
+ 4) reload inspected page
+ got NPE
+
+ https://bugs.webkit.org/show_bug.cgi?id=45098
+
+ * loader/ResourceLoader.cpp:
+ (WebCore::ResourceLoader::didReceiveResponse):
+ (WebCore::ResourceLoader::didReceiveData):
+
+2010-09-02 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Remove m_URL from FrameLoader and instead depend on Document's url.
+ FrameLoader::url() will be removed in a later patch.
+
+ http://bugs.webkit.org/show_bug.cgi?id=41165
+
+ No new tests, since this predominantly a refactor. Updating
+ fast/dom/early-frame-url.html.
+
+ * WebCore.exp.in:
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::updateURLForPushOrReplaceState):
+ * loader/DocumentWriter.cpp:
+ (WebCore::DocumentWriter::begin):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::iconURL):
+ (WebCore::FrameLoader::didOpenURL):
+ (WebCore::FrameLoader::didExplicitOpen):
+ (WebCore::FrameLoader::receivedFirstData):
+ (WebCore::FrameLoader::url):
+ (WebCore::FrameLoader::setOutgoingReferrer):
+ (WebCore::FrameLoader::startIconLoader):
+ (WebCore::FrameLoader::commitIconURLToIconDatabase):
+ (WebCore::FrameLoader::finishedParsing):
+ (WebCore::FrameLoader::checkIfDisplayInsecureContent):
+ (WebCore::FrameLoader::checkIfRunInsecureContent):
+ (WebCore::FrameLoader::updateFirstPartyForCookies):
+ (WebCore::FrameLoader::loadInSameDocument):
+ (WebCore::FrameLoader::commitProvisionalLoad):
+ (WebCore::FrameLoader::open):
+ (WebCore::FrameLoader::shouldScrollToAnchor):
+ * loader/FrameLoader.h:
+
+2010-09-01 Tony Gentilcore <tonyg@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Support <script defer> as specified by HTML5
+ https://bugs.webkit.org/show_bug.cgi?id=40934
+
+ Tests: fast/dom/HTMLScriptElement/defer-double-defer-write.html
+ fast/dom/HTMLScriptElement/defer-double-write.html
+ fast/dom/HTMLScriptElement/defer-inline-script.html
+ fast/dom/HTMLScriptElement/defer-onbeforeload.html
+ fast/dom/HTMLScriptElement/defer-script-invalid-url.html
+ fast/dom/HTMLScriptElement/defer-write.html
+ fast/dom/HTMLScriptElement/two-defer-writes.html
+ http/tests/misc/script-defer-after-slow-stylesheet.html
+ http/tests/misc/script-defer.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::open): Allow implicit open for writes() while executing deferred scripts.
+ * dom/DocumentParser.cpp:
+ (WebCore::DocumentParser::DocumentParser):
+ (WebCore::DocumentParser::startParsing):
+ (WebCore::DocumentParser::prepareToStopParsing): If called when stopped or detached, it shouldn't reset to stopping.
+ (WebCore::DocumentParser::stopParsing):
+ (WebCore::DocumentParser::detach):
+ * dom/DocumentParser.h:
+ (WebCore::DocumentParser::isParsing):
+ (WebCore::DocumentParser::isActive):
+ (WebCore::DocumentParser::isStopping):
+ (WebCore::DocumentParser::isDetached):
+ * dom/RawDataDocumentParser.h:
+ (WebCore::RawDataDocumentParser::finish):
+ * dom/XMLDocumentParser.cpp:
+ (WebCore::XMLDocumentParser::append):
+ (WebCore::XMLDocumentParser::exitText):
+ * dom/XMLDocumentParserLibxml2.cpp:
+ (WebCore::XMLDocumentParser::doWrite):
+ (WebCore::XMLDocumentParser::startElementNs):
+ (WebCore::XMLDocumentParser::endElementNs):
+ (WebCore::XMLDocumentParser::characters):
+ (WebCore::XMLDocumentParser::error):
+ (WebCore::XMLDocumentParser::processingInstruction):
+ (WebCore::XMLDocumentParser::cdataBlock):
+ (WebCore::XMLDocumentParser::comment):
+ (WebCore::XMLDocumentParser::internalSubset):
+ (WebCore::XMLDocumentParser::initializeParserContext):
+ (WebCore::XMLDocumentParser::doEnd):
+ * html/parser/HTMLDocumentParser.cpp:
+ (WebCore::HTMLDocumentParser::prepareToStopParsing):
+ (WebCore::HTMLDocumentParser::pumpTokenizerIfPossible):
+ (WebCore::HTMLDocumentParser::pumpTokenizer):
+ (WebCore::HTMLDocumentParser::insert):
+ (WebCore::HTMLDocumentParser::append):
+ (WebCore::HTMLDocumentParser::end):
+ (WebCore::HTMLDocumentParser::attemptToEnd):
+ (WebCore::HTMLDocumentParser::endIfDelayed):
+ (WebCore::HTMLDocumentParser::notifyFinished):
+ * html/parser/HTMLDocumentParser.h:
+ * html/parser/HTMLScriptRunner.cpp:
+ (WebCore::HTMLScriptRunner::~HTMLScriptRunner):
+ (WebCore::HTMLScriptRunner::executeParsingBlockingScript):
+ (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent):
+ (WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing):
+ (WebCore::HTMLScriptRunner::requestDeferredScript):
+ (WebCore::HTMLScriptRunner::runScript):
+ * html/parser/HTMLScriptRunner.h:
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageDocumentParser::finish):
+
+2010-09-02 Andrey Kosyakov <caseq@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: HAR converter fails on POST requests with non-form content type
+ https://bugs.webkit.org/show_bug.cgi?id=45109
+
+ * inspector/front-end/HAREntry.js:
+ (WebInspector.HAREntry.prototype._buildPostData):
+
+2010-09-02 Andreas Kling <andreas.kling@nokia.com>
+
+ Rubber-stamped by Simon Hausmann.
+
+ [Qt] REGRESSION(r62898): tst_QWebFrame crashing
+ https://bugs.webkit.org/show_bug.cgi?id=43039
+
+ Rolling out the offending change <http://trac.webkit.org/changeset/62898>
+
+ * bridge/qt/qt_instance.cpp:
+ (JSC::Bindings::QtInstance::markAggregate):
+
2010-09-02 Anton Muhin <antonm@chromium.org>
Reviewed by Tony Chang.
diff --git a/WebCore/Configurations/Base.xcconfig b/WebCore/Configurations/Base.xcconfig
index be19c22..94beb03 100644
--- a/WebCore/Configurations/Base.xcconfig
+++ b/WebCore/Configurations/Base.xcconfig
@@ -54,14 +54,14 @@ VALID_ARCHS_macosx = i386 ppc x86_64 ppc64;
WARNING_CFLAGS_BASE = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings;
WARNING_CFLAGS = $(WARNING_CFLAGS_$(REAL_PLATFORM_NAME));
WARNING_CFLAGS_iphoneos = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
-WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
+WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
WARNING_CFLAGS_macosx = $(WARNING_CFLAGS_macosx_$(CURRENT_ARCH));
-WARNING_CFLAGS_macosx_ = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
-WARNING_CFLAGS_macosx_i386 = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
-WARNING_CFLAGS_macosx_ppc = $(WARNING_CFLAGS_BASE) -Wcast-align -Wshorten-64-to-32;
+WARNING_CFLAGS_macosx_ = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
+WARNING_CFLAGS_macosx_i386 = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
+WARNING_CFLAGS_macosx_ppc = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
// FIXME: WebCore 64-bit builds should build with -Wshorten-64-to-32
-WARNING_CFLAGS_macosx_ppc64 = $(WARNING_CFLAGS_BASE) -Wcast-align;
-WARNING_CFLAGS_macosx_x86_64 = $(WARNING_CFLAGS_BASE) -Wcast-align;
+WARNING_CFLAGS_macosx_ppc64 = $(WARNING_CFLAGS_BASE);
+WARNING_CFLAGS_macosx_x86_64 = $(WARNING_CFLAGS_BASE);
REAL_PLATFORM_NAME = $(REAL_PLATFORM_NAME_$(PLATFORM_NAME));
diff --git a/WebCore/Configurations/Version.xcconfig b/WebCore/Configurations/Version.xcconfig
index 69bde0f..bc7cdb8 100644
--- a/WebCore/Configurations/Version.xcconfig
+++ b/WebCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 534;
-MINOR_VERSION = 7;
+MINOR_VERSION = 8;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/WebCore/DerivedSources.cpp b/WebCore/DerivedSources.cpp
index 81f4070..7a0c2fd 100644
--- a/WebCore/DerivedSources.cpp
+++ b/WebCore/DerivedSources.cpp
@@ -105,6 +105,7 @@
#include "JSEventException.cpp"
#include "JSEventSource.cpp"
#include "JSFile.cpp"
+#include "JSFileCallback.cpp"
#include "JSFileEntry.cpp"
#include "JSFileError.cpp"
#include "JSFileException.cpp"
@@ -113,6 +114,7 @@
#include "JSFileReaderSync.cpp"
#include "JSFileSystemCallback.cpp"
#include "JSFileWriter.cpp"
+#include "JSFileWriterCallback.cpp"
#include "JSFlags.cpp"
#include "JSGeolocation.cpp"
#include "JSGeoposition.cpp"
diff --git a/WebCore/DerivedSources.make b/WebCore/DerivedSources.make
index 6fd1cde..c37efb3 100644
--- a/WebCore/DerivedSources.make
+++ b/WebCore/DerivedSources.make
@@ -151,6 +151,7 @@ DOM_CLASSES = \
EventSource \
EventTarget \
File \
+ FileCallback \
FileEntry \
FileException \
FileError \
@@ -158,6 +159,7 @@ DOM_CLASSES = \
FileReader \
FileReaderSync \
FileWriter \
+ FileWriterCallback \
FileSystemCallback \
Flags \
Geolocation \
diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js
index c26c15f..28cdf1a 100644
--- a/WebCore/English.lproj/localizedStrings.js
+++ b/WebCore/English.lproj/localizedStrings.js
Binary files differ
diff --git a/WebCore/ForwardingHeaders/runtime/RegExp.h b/WebCore/ForwardingHeaders/runtime/RegExp.h
new file mode 100644
index 0000000..b6e8894
--- /dev/null
+++ b/WebCore/ForwardingHeaders/runtime/RegExp.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_RegExp_h
+#define WebCore_FWD_RegExp_h
+#include <JavaScriptCore/RegExp.h>
+#endif
diff --git a/WebCore/ForwardingHeaders/runtime/RegExpObject.h b/WebCore/ForwardingHeaders/runtime/RegExpObject.h
new file mode 100644
index 0000000..b3f2516
--- /dev/null
+++ b/WebCore/ForwardingHeaders/runtime/RegExpObject.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_RegExpObject_h
+#define WebCore_FWD_RegExpObject_h
+#include <JavaScriptCore/RegExpObject.h>
+#endif
diff --git a/WebCore/ForwardingHeaders/wtf/NonCopyingSort.h b/WebCore/ForwardingHeaders/wtf/NonCopyingSort.h
new file mode 100644
index 0000000..d30e61f
--- /dev/null
+++ b/WebCore/ForwardingHeaders/wtf/NonCopyingSort.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_NonCopyingSort_h
+#define WebCore_FWD_NonCopyingSort_h
+#include <JavaScriptCore/NonCopyingSort.h>
+#endif
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 76f8be2..01d11cf 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -9,6 +9,7 @@ webcore_cppflags += \
-I$(srcdir)/WebCore/accessibility \
-I$(srcdir)/WebCore/bindings/generic \
-I$(srcdir)/WebCore/bindings/js \
+ -I$(srcdir)/WebCore/bindings/js/specialization \
-I$(srcdir)/WebCore/bindings/gobject \
-I$(srcdir)/WebCore/bridge \
-I$(srcdir)/WebCore/bridge/c \
@@ -391,6 +392,8 @@ webcore_built_sources += \
DerivedSources/WebCore/JSHTMLUListElement.h \
DerivedSources/WebCore/JSHTMLVideoElement.cpp \
DerivedSources/WebCore/JSHTMLVideoElement.h \
+ DerivedSources/WebCore/JSTimeRanges.cpp \
+ DerivedSources/WebCore/JSTimeRanges.h \
DerivedSources/WebCore/JSImageData.cpp \
DerivedSources/WebCore/JSImageData.h \
DerivedSources/WebCore/JSInjectedScriptHost.cpp \
@@ -621,6 +624,12 @@ webcore_sources += \
WebCore/accessibility/AccessibilityTableRow.h \
WebCore/bindings/generic/ActiveDOMCallback.cpp \
WebCore/bindings/generic/ActiveDOMCallback.h \
+ WebCore/bindings/generic/BindingFrame.h \
+ WebCore/bindings/generic/BindingLocation.h \
+ WebCore/bindings/generic/BindingSecurity.h \
+ WebCore/bindings/generic/BindingSecurityBase.cpp \
+ WebCore/bindings/generic/BindingSecurityBase.h \
+ WebCore/bindings/generic/GenericBinding.h \
WebCore/bindings/generic/RuntimeEnabledFeatures.cpp \
WebCore/bindings/generic/RuntimeEnabledFeatures.h \
WebCore/bindings/js/CachedScriptSourceProvider.h \
@@ -794,6 +803,8 @@ webcore_sources += \
WebCore/bindings/js/SerializedScriptValue.h \
WebCore/bindings/js/StringSourceProvider.h \
WebCore/bindings/js/WebCoreJSClientData.h \
+ WebCore/bindings/js/specialization/JSBindingState.cpp \
+ WebCore/bindings/js/specialization/JSBindingState.h \
WebCore/bindings/ScriptControllerBase.cpp \
WebCore/bindings/ScriptControllerBase.h \
WebCore/bridge/Bridge.h \
@@ -1349,6 +1360,8 @@ webcore_sources += \
WebCore/html/DataGridDataSource.h \
WebCore/html/DateComponents.cpp \
WebCore/html/DateComponents.h \
+ WebCore/html/FTPDirectoryDocument.cpp \
+ WebCore/html/FTPDirectoryDocument.h \
WebCore/html/FormDataList.cpp \
WebCore/html/FormDataList.h \
WebCore/html/HTMLAllCollection.cpp \
@@ -1431,7 +1444,6 @@ webcore_sources += \
WebCore/html/HTMLImageLoader.h \
WebCore/html/HTMLInputElement.cpp \
WebCore/html/HTMLInputElement.h \
- WebCore/html/HTMLInputStream.h \
WebCore/html/HTMLIsIndexElement.cpp \
WebCore/html/HTMLIsIndexElement.h \
WebCore/html/HTMLKeygenElement.cpp \
@@ -1517,13 +1529,21 @@ webcore_sources += \
WebCore/html/HTMLViewSourceDocument.h \
WebCore/html/ImageData.cpp \
WebCore/html/ImageData.h \
+ WebCore/html/ImageDocument.cpp \
+ WebCore/html/ImageDocument.h \
WebCore/html/ImageResizerThread.cpp \
WebCore/html/ImageResizerThread.h \
WebCore/html/LabelsNodeList.cpp \
WebCore/html/LabelsNodeList.h \
+ WebCore/html/MediaDocument.cpp \
+ WebCore/html/MediaDocument.h \
WebCore/html/MediaError.h \
+ WebCore/html/PluginDocument.cpp \
+ WebCore/html/PluginDocument.h \
WebCore/html/StepRange.cpp \
WebCore/html/StepRange.h \
+ WebCore/html/TextDocument.cpp \
+ WebCore/html/TextDocument.h \
WebCore/html/TextMetrics.h \
WebCore/html/canvas/CanvasContextAttributes.h \
WebCore/html/canvas/CanvasGradient.cpp \
@@ -1553,6 +1573,7 @@ webcore_sources += \
WebCore/html/parser/HTMLEntityTable.h \
WebCore/html/parser/HTMLFormattingElementList.cpp \
WebCore/html/parser/HTMLFormattingElementList.h \
+ WebCore/html/parser/HTMLInputStream.h \
WebCore/html/parser/HTMLParserScheduler.cpp \
WebCore/html/parser/HTMLParserScheduler.h \
WebCore/html/parser/HTMLPreloadScanner.cpp \
@@ -1567,6 +1588,10 @@ webcore_sources += \
WebCore/html/parser/HTMLTreeBuilder.h \
WebCore/html/parser/HTMLViewSourceParser.cpp \
WebCore/html/parser/HTMLViewSourceParser.h \
+ WebCore/html/parser/TextDocumentParser.cpp \
+ WebCore/html/parser/TextDocumentParser.h \
+ WebCore/html/parser/TextViewSourceParser.cpp \
+ WebCore/html/parser/TextViewSourceParser.h \
WebCore/html/ValidityState.cpp \
WebCore/html/ValidityState.h \
WebCore/html/VoidCallback.h \
@@ -1667,8 +1692,8 @@ webcore_sources += \
WebCore/loader/CrossOriginAccessControl.h \
WebCore/loader/CrossOriginPreflightResultCache.cpp \
WebCore/loader/CrossOriginPreflightResultCache.h \
- WebCore/loader/DocLoader.cpp \
- WebCore/loader/DocLoader.h \
+ WebCore/loader/CachedResourceLoader.cpp \
+ WebCore/loader/CachedResourceLoader.h \
WebCore/loader/DocumentLoadTiming.h \
WebCore/loader/DocumentLoader.cpp \
WebCore/loader/DocumentLoader.h \
@@ -1677,8 +1702,6 @@ webcore_sources += \
WebCore/loader/DocumentWriter.cpp \
WebCore/loader/DocumentWriter.h \
WebCore/loader/EmptyClients.h \
- WebCore/loader/FTPDirectoryDocument.cpp \
- WebCore/loader/FTPDirectoryDocument.h \
WebCore/loader/FTPDirectoryParser.cpp \
WebCore/loader/FTPDirectoryParser.h \
WebCore/loader/FormState.cpp \
@@ -1694,14 +1717,10 @@ webcore_sources += \
WebCore/loader/FrameNetworkingContext.h \
WebCore/loader/HistoryController.cpp \
WebCore/loader/HistoryController.h \
- WebCore/loader/ImageDocument.cpp \
- WebCore/loader/ImageDocument.h \
WebCore/loader/ImageLoader.cpp \
WebCore/loader/ImageLoader.h \
WebCore/loader/MainResourceLoader.cpp \
WebCore/loader/MainResourceLoader.h \
- WebCore/loader/MediaDocument.cpp \
- WebCore/loader/MediaDocument.h \
WebCore/loader/NavigationAction.cpp \
WebCore/loader/NavigationAction.h \
WebCore/loader/NetscapePlugInStreamLoader.cpp \
@@ -1710,8 +1729,6 @@ webcore_sources += \
WebCore/loader/PingLoader.h \
WebCore/loader/PlaceholderDocument.cpp \
WebCore/loader/PlaceholderDocument.h \
- WebCore/loader/PluginDocument.cpp \
- WebCore/loader/PluginDocument.h \
WebCore/loader/PolicyCallback.cpp \
WebCore/loader/PolicyCallback.h \
WebCore/loader/PolicyChecker.cpp \
@@ -1735,8 +1752,6 @@ webcore_sources += \
WebCore/loader/SubresourceLoaderClient.h \
WebCore/loader/SubstituteData.h \
WebCore/loader/SubstituteResource.h \
- WebCore/loader/TextDocument.cpp \
- WebCore/loader/TextDocument.h \
WebCore/loader/TextResourceDecoder.cpp \
WebCore/loader/TextResourceDecoder.h \
WebCore/loader/ThreadableLoader.cpp \
@@ -1947,6 +1962,8 @@ webcore_sources += \
WebCore/platform/PopupMenuStyle.h \
WebCore/platform/PurgeableBuffer.h \
WebCore/platform/SSLKeyGenerator.h \
+ WebCore/platform/ScrollAnimator.cpp \
+ WebCore/platform/ScrollAnimator.h \
WebCore/platform/ScrollTypes.h \
WebCore/platform/ScrollView.cpp \
WebCore/platform/ScrollView.h \
@@ -1954,6 +1971,7 @@ webcore_sources += \
WebCore/platform/SchemeRegistry.h \
WebCore/platform/Scrollbar.cpp \
WebCore/platform/Scrollbar.h \
+ WebCore/platform/ScrollbarClient.cpp \
WebCore/platform/ScrollbarClient.h \
WebCore/platform/ScrollbarTheme.h \
WebCore/platform/ScrollbarThemeComposite.cpp \
@@ -2204,6 +2222,7 @@ webcore_sources += \
WebCore/rendering/AutoTableLayout.h \
WebCore/rendering/BidiRun.cpp \
WebCore/rendering/BidiRun.h \
+ WebCore/rendering/ColumnInfo.h \
WebCore/rendering/CounterNode.cpp \
WebCore/rendering/CounterNode.h \
WebCore/rendering/EllipsisBox.cpp \
@@ -2449,8 +2468,8 @@ webcoregtk_sources += \
WebCore/platform/graphics/cairo/FontCairo.cpp \
WebCore/platform/graphics/cairo/FontCustomPlatformData.h \
WebCore/platform/graphics/cairo/FontPlatformData.h \
- WebCore/platform/graphics/cairo/GOwnPtrCairo.cpp \
- WebCore/platform/graphics/cairo/GOwnPtrCairo.h \
+ WebCore/platform/graphics/cairo/OwnPtrCairo.cpp \
+ WebCore/platform/graphics/cairo/OwnPtrCairo.h \
WebCore/platform/graphics/cairo/GradientCairo.cpp \
WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp \
WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h \
@@ -2501,6 +2520,8 @@ webcoregtk_sources += \
WebCore/platform/gtk/Language.cpp \
WebCore/platform/gtk/LocalizedStringsGtk.cpp \
WebCore/platform/gtk/LoggingGtk.cpp \
+ WebCore/platform/gtk/MainFrameScrollbarGtk.cpp \
+ WebCore/platform/gtk/MainFrameScrollbarGtk.h \
WebCore/platform/gtk/MIMETypeRegistryGtk.cpp \
WebCore/platform/gtk/MouseEventGtk.cpp \
WebCore/platform/gtk/PasteboardGtk.cpp \
@@ -2511,8 +2532,6 @@ webcoregtk_sources += \
WebCore/platform/gtk/PopupMenuGtk.h \
WebCore/platform/gtk/RenderThemeGtk.cpp \
WebCore/platform/gtk/RenderThemeGtk.h \
- WebCore/platform/gtk/ScrollbarGtk.cpp \
- WebCore/platform/gtk/ScrollbarGtk.h \
WebCore/platform/gtk/ScrollbarThemeGtk.cpp \
WebCore/platform/gtk/ScrollbarThemeGtk.h \
WebCore/platform/gtk/ScrollViewGtk.cpp \
@@ -2566,6 +2585,8 @@ endif
if TARGET_WIN32
webcore_sources += \
+ WebCore/platform/ScrollAnimatorWin.cpp \
+ WebCore/platform/ScrollAnimatorWin.h \
WebCore/plugins/win/PluginDatabaseWin.cpp \
WebCore/plugins/win/PluginMessageThrottlerWin.cpp \
WebCore/plugins/win/PluginMessageThrottlerWin.h
@@ -3014,6 +3035,8 @@ webcore_built_sources += \
DerivedSources/WebCore/JSEntryCallback.h \
DerivedSources/WebCore/JSErrorCallback.cpp \
DerivedSources/WebCore/JSErrorCallback.h \
+ DerivedSources/WebCore/JSFileCallback.cpp \
+ DerivedSources/WebCore/JSFileCallback.h \
DerivedSources/WebCore/JSFileEntry.cpp \
DerivedSources/WebCore/JSFileEntry.h \
DerivedSources/WebCore/JSFileSystemCallback.cpp \
@@ -3041,6 +3064,7 @@ webcore_sources += \
WebCore/fileapi/EntryArray.h \
WebCore/fileapi/EntryCallback.h \
WebCore/fileapi/ErrorCallback.h \
+ WebCore/fileapi/FileCallback.h \
WebCore/fileapi/FileEntry.cpp \
WebCore/fileapi/FileEntry.h \
WebCore/fileapi/FileSystemCallback.h \
@@ -3134,10 +3158,6 @@ if ENABLE_DEBUG
webcore_cppflags += -DGST_DISABLE_DEPRECATED
endif # END ENABLE_DEBUG
-webcore_built_sources += \
- DerivedSources/WebCore/JSTimeRanges.cpp \
- DerivedSources/WebCore/JSTimeRanges.h
-
webcore_sources += \
WebCore/bindings/js/JSAudioConstructor.cpp \
WebCore/bindings/js/JSAudioConstructor.h \
@@ -3905,6 +3925,8 @@ webcore_sources += \
WebCore/rendering/RenderSVGResourceClipper.h \
WebCore/rendering/RenderSVGResourceFilter.cpp \
WebCore/rendering/RenderSVGResourceFilter.h \
+ WebCore/rendering/RenderSVGResourceFilterPrimitive.cpp \
+ WebCore/rendering/RenderSVGResourceFilterPrimitive.h \
WebCore/rendering/RenderSVGResourceGradient.cpp \
WebCore/rendering/RenderSVGResourceGradient.h \
WebCore/rendering/RenderSVGResourceLinearGradient.cpp \
@@ -4447,12 +4469,15 @@ webcore_cppflags += -DENABLE_FILE_WRITER=1
webcore_built_sources += \
DerivedSources/WebCore/JSFileWriter.cpp \
DerivedSources/WebCore/JSFileWriter.h
+ DerivedSources/WebCore/JSFileWriterCallback.cpp \
+ DerivedSources/WebCore/JSFileWriterCallback.h
webcore_sources += \
WebCore/fileapi/AsyncFileWriter.h \
WebCore/fileapi/FileWriterClient.h \
WebCore/fileapi/FileWriter.cpp \
- WebCore/fileapi/FileWriter.h
+ WebCore/fileapi/FileWriter.h \
+ WebCore/fileapi/FileWriterCallback.h
endif # END ENABLE_FILE_WRITER
@@ -4674,8 +4699,3 @@ dist_webresources_DATA = \
$(WebCore)/Resources/panIcon.png \
$(WebCore)/Resources/deleteButton.png \
$(WebCore)/Resources/inputSpeech.png
-
-# Clean rules for WebCore
-
-CLEANFILES += \
- libWebCoreJS.la
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index e8b4fe7..a2d5a39 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -314,6 +314,7 @@ __ZN7WebCore14SVGSMILElement13isSMILElementEPNS_4NodeE
__ZN7WebCore14SchemeRegistry24registerURLSchemeAsLocalERKN3WTF6StringE
__ZN7WebCore14SchemeRegistry25registerURLSchemeAsSecureERKN3WTF6StringE
__ZN7WebCore14SchemeRegistry32registerURLSchemeAsEmptyDocumentERKN3WTF6StringE
+__ZN7WebCore14SecurityOrigin10canDisplayERKNS_4KURLERKN3WTF6StringEPNS_8DocumentE
__ZN7WebCore14SecurityOrigin16createFromStringERKN3WTF6StringE
__ZN7WebCore14SecurityOrigin18setLocalLoadPolicyENS0_15LocalLoadPolicyE
__ZN7WebCore14SecurityOrigin18shouldHideReferrerERKNS_4KURLERKN3WTF6StringE
@@ -322,7 +323,6 @@ __ZN7WebCore14SecurityOrigin29addOriginAccessWhitelistEntryERKS0_RKN3WTF6StringE
__ZN7WebCore14SecurityOrigin32removeOriginAccessWhitelistEntryERKS0_RKN3WTF6StringES6_b
__ZN7WebCore14SecurityOrigin40setDomainRelaxationForbiddenForURLSchemeEbRKN3WTF6StringE
__ZN7WebCore14SecurityOrigin6createERKNS_4KURLEi
-__ZN7WebCore14SecurityOrigin7canLoadERKNS_4KURLERKN3WTF6StringEPNS_8DocumentE
__ZN7WebCore15ArchiveResource6createEN3WTF10PassRefPtrINS_12SharedBufferEEERKNS_4KURLERKNS1_6StringESA_SA_RKNS_16ResourceResponseE
__ZN7WebCore15DOMWrapperWorld15unregisterWorldEv
__ZN7WebCore15DOMWrapperWorldD1Ev
@@ -341,7 +341,7 @@ __ZN7WebCore15DatabaseTracker9setClientEPNS_21DatabaseTrackerClientE
__ZN7WebCore15FocusController10setFocusedEb
__ZN7WebCore15FocusController15setFocusedFrameEN3WTF10PassRefPtrINS_5FrameEEE
__ZN7WebCore15FocusController15setInitialFocusENS_14FocusDirectionEPNS_13KeyboardEventE
-__ZN7WebCore15FocusController18focusedOrMainFrameEv
+__ZNK7WebCore15FocusController18focusedOrMainFrameEv
__ZN7WebCore15FocusController9setActiveEb
__ZN7WebCore15GraphicsContext12setFillColorERKNS_5ColorENS_10ColorSpaceE
__ZN7WebCore15GraphicsContext4clipERKNS_9FloatRectE
@@ -443,6 +443,7 @@ __ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
__ZN7WebCore21SVGDocumentExtensions21sampleAnimationAtTimeERKN3WTF6StringEPNS_14SVGSMILElementEd
__ZN7WebCore21SerializedScriptValue11deserializeEPK15OpaqueJSContextPPK13OpaqueJSValue
__ZN7WebCore21SerializedScriptValue6createEPK15OpaqueJSContextPK13OpaqueJSValuePS6_
+__ZN7WebCore21SerializedScriptValueC1ERN3WTF6VectorIhLm0EEE
__ZN7WebCore21SerializedScriptValueD1Ev
__ZN7WebCore21UserContentURLPattern5parseERKN3WTF6StringE
__ZN7WebCore21WindowsLatin1EncodingEv
@@ -462,6 +463,7 @@ __ZN7WebCore23ReplaceSelectionCommandC1EPNS_8DocumentEN3WTF10PassRefPtrINS_16Doc
__ZN7WebCore23createFragmentFromNodesEPNS_8DocumentERKN3WTF6VectorIPNS_4NodeELm0EEE
__ZN7WebCore24BinaryPropertyListWriter17writePropertyListEv
__ZN7WebCore24DocumentMarkerController13removeMarkersENS_14DocumentMarker10MarkerTypeE
+__ZN7WebCore24DocumentMarkerController14markersForNodeEPNS_4NodeE
__ZN7WebCore24DocumentMarkerController23renderedRectsForMarkersENS_14DocumentMarker10MarkerTypeE
__ZN7WebCore24contextMenuItemTagItalicEv
__ZN7WebCore24contextMenuItemTagStylesEv
@@ -577,16 +579,12 @@ __ZN7WebCore5Cache11setDisabledEb
__ZN7WebCore5Cache13getStatisticsEv
__ZN7WebCore5Cache13setCapacitiesEjjj
__ZN7WebCore5Frame10createViewERKNS_7IntSizeERKNS_5ColorEbS3_bNS_13ScrollbarModeEbS7_b
-__ZN7WebCore5Frame10findStringERKN3WTF6StringEbbbb
__ZN7WebCore5Frame14frameForWidgetEPKNS_6WidgetE
__ZN7WebCore5Frame15revealSelectionERKNS_15ScrollAlignmentEb
-__ZN7WebCore5Frame19countMatchesForTextERKN3WTF6StringEbjb
__ZN7WebCore5Frame20setSelectionFromNoneEv
__ZN7WebCore5Frame23visiblePositionForPointERKNS_8IntPointE
-__ZN7WebCore5Frame24computeAndSetTypingStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
__ZN7WebCore5Frame25matchLabelsAgainstElementEP7NSArrayPNS_7ElementE
__ZN7WebCore5Frame28searchForLabelsBeforeElementEP7NSArrayPNS_7ElementEPmPb
-__ZN7WebCore5Frame34setMarkedTextMatchesAreHighlightedEb
__ZN7WebCore5Frame6createEPNS_4PageEPNS_21HTMLFrameOwnerElementEPNS_17FrameLoaderClientE
__ZN7WebCore5Frame7setViewEN3WTF10PassRefPtrINS_9FrameViewEEE
__ZN7WebCore5Frame9nodeImageEPNS_4NodeE
@@ -603,6 +601,7 @@ __ZN7WebCore6Cursor8fromTypeENS0_4TypeE
__ZN7WebCore6CursorD1Ev
__ZN7WebCore6CursoraSERKS0_
__ZN7WebCore6Editor10applyStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
+__ZN7WebCore6Editor10findStringERKN3WTF6StringEbbbb
__ZN7WebCore6Editor10insertTextERKN3WTF6StringEPNS_5EventE
__ZN7WebCore6Editor13canDHTMLPasteEv
__ZN7WebCore6Editor13performDeleteEv
@@ -614,12 +613,14 @@ __ZN7WebCore6Editor16pasteAsPlainTextEv
__ZN7WebCore6Editor17insertOrderedListEv
__ZN7WebCore6Editor18confirmCompositionERKN3WTF6StringE
__ZN7WebCore6Editor18confirmCompositionEv
+__ZN7WebCore6Editor19countMatchesForTextERKN3WTF6StringEbjb
__ZN7WebCore6Editor19deleteWithDirectionENS_19SelectionController10EDirectionENS_15TextGranularityEbb
__ZN7WebCore6Editor19insertUnorderedListEv
__ZN7WebCore6Editor21applyStyleToSelectionEPNS_19CSSStyleDeclarationENS_10EditActionE
__ZN7WebCore6Editor21isSelectionMisspelledEv
__ZN7WebCore6Editor23setBaseWritingDirectionENS_16WritingDirectionE
__ZN7WebCore6Editor24advanceToNextMisspellingEb
+__ZN7WebCore6Editor24computeAndSetTypingStyleEPNS_19CSSStyleDeclarationENS_10EditActionE
__ZN7WebCore6Editor24handleRejectedCorrectionEv
__ZN7WebCore6Editor24isSelectionUngrammaticalEv
__ZN7WebCore6Editor26decreaseSelectionListLevelEv
@@ -631,6 +632,7 @@ __ZN7WebCore6Editor30deleteSelectionWithSmartDeleteEb
__ZN7WebCore6Editor30pasteAsPlainTextBypassingDHTMLEv
__ZN7WebCore6Editor32guessesForUngrammaticalSelectionEv
__ZN7WebCore6Editor33increaseSelectionListLevelOrderedEv
+__ZN7WebCore6Editor34setMarkedTextMatchesAreHighlightedEb
__ZN7WebCore6Editor35increaseSelectionListLevelUnorderedEv
__ZN7WebCore6Editor35setIgnoreCompositionSelectionChangeEb
__ZN7WebCore6Editor3cutEv
@@ -670,14 +672,14 @@ __ZN7WebCore8Document16isPageBoxVisibleEi
__ZN7WebCore8Document17getFocusableNodesERN3WTF6VectorINS1_6RefPtrINS_4NodeEEELm0EEE
__ZN7WebCore8Document18createWrapperCacheEPNS_15DOMWrapperWorldE
__ZN7WebCore8Document19accessSVGExtensionsEv
+__ZN7WebCore8Document20styleSelectorChangedENS_23StyleSelectorUpdateFlagE
__ZN7WebCore8Document22createDocumentFragmentEv
__ZN7WebCore8Document24addMediaCanStartListenerEPNS_21MediaCanStartListenerE
__ZN7WebCore8Document24setShouldCreateRenderersEb
+__ZN7WebCore8Document25scheduleForcedStyleRecalcEv
__ZN7WebCore8Document26pageSizeAndMarginsInPixelsEiRNS_7IntSizeERiS3_S3_S3_
__ZN7WebCore8Document27removeMediaCanStartListenerEPNS_21MediaCanStartListenerE
__ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv
-__ZN7WebCore8Document25scheduleForcedStyleRecalcEv
-__ZN7WebCore8Document20styleSelectorChangedENS_23StyleSelectorUpdateFlagE
__ZN7WebCore8Document4headEv
__ZN7WebCore8FormData6createEPKvm
__ZN7WebCore8FormDataD1Ev
@@ -735,9 +737,9 @@ __ZN7WebCore8Settings31setShrinksStandaloneImagesToFitEb
__ZN7WebCore8Settings32setAcceleratedCompositingEnabledEb
__ZN7WebCore8Settings32setNeedsAdobeFrameReloadingQuirkEb
__ZN7WebCore8Settings33setDownloadableBinaryFontsEnabledEb
-__ZN7WebCore8Settings35setEnforceCSSMIMETypeInNoQuirksModeEb
__ZN7WebCore8Settings34setLocalFileContentSniffingEnabledEb
__ZN7WebCore8Settings35setAllowUniversalAccessFromFileURLsEb
+__ZN7WebCore8Settings35setEnforceCSSMIMETypeInNoQuirksModeEb
__ZN7WebCore8Settings35setExperimentalNotificationsEnabledEb
__ZN7WebCore8Settings35setTreatsAnyTextCSSLinkAsStylesheetEb
__ZN7WebCore8Settings36setOfflineWebApplicationCacheEnabledEb
@@ -772,10 +774,10 @@ __ZN7WebCore9FrameView20enterCompositingModeEv
__ZN7WebCore9FrameView21flushDeferredRepaintsEv
__ZN7WebCore9FrameView22setBaseBackgroundColorENS_5ColorE
__ZN7WebCore9FrameView23updateCanHaveScrollbarsEv
-__ZN7WebCore9FrameView37updateLayoutAndStyleIfNeededRecursiveEv
__ZN7WebCore9FrameView24forceLayoutForPaginationERKNS_9FloatSizeEfNS_5Frame19AdjustViewSizeOrNotE
__ZN7WebCore9FrameView29setShouldUpdateWhileOffscreenEb
__ZN7WebCore9FrameView29syncCompositingStateRecursiveEv
+__ZN7WebCore9FrameView37updateLayoutAndStyleIfNeededRecursiveEv
__ZN7WebCore9FrameView38scrollPositionChangedViaPlatformWidgetEv
__ZN7WebCore9FrameView6createEPNS_5FrameE
__ZN7WebCore9FrameView6createEPNS_5FrameERKNS_7IntSizeE
@@ -855,6 +857,7 @@ __ZNK7WebCore10ScrollView16contentsToWindowERKNS_8IntPointE
__ZNK7WebCore10ScrollView18visibleContentRectEb
__ZNK7WebCore11CachedImage5imageEv
__ZNK7WebCore11FrameLoader10isCompleteEv
+__ZNK7WebCore11FrameLoader12blockedErrorERKNS_15ResourceRequestE
__ZNK7WebCore11FrameLoader14cancelledErrorERKNS_15ResourceRequestE
__ZNK7WebCore11FrameLoader14frameHasLoadedEv
__ZNK7WebCore11FrameLoader16outgoingReferrerEv
@@ -888,6 +891,7 @@ __ZNK7WebCore12IconDatabase24shouldStopThreadActivityEv
__ZNK7WebCore12IconDatabase9isEnabledEv
__ZNK7WebCore12RenderObject14enclosingLayerEv
__ZNK7WebCore12RenderObject15localToAbsoluteENS_10FloatPointEbb
+__ZNK7WebCore12RenderObject7childAtEj
__ZNK7WebCore12RenderWidget14windowClipRectEv
__ZNK7WebCore12SharedBuffer4dataEv
__ZNK7WebCore12SharedBuffer4sizeEv
@@ -985,19 +989,14 @@ __ZNK7WebCore4Page15backForwardListEv
__ZNK7WebCore4Page34inLowQualityImageInterpolationModeEv
__ZNK7WebCore4Page9groupNameEv
__ZNK7WebCore5Frame11currentFormEv
-__ZNK7WebCore5Frame12selectedTextEv
__ZNK7WebCore5Frame13ownerRendererEv
__ZNK7WebCore5Frame14selectionImageEb
__ZNK7WebCore5Frame15contentRendererEv
__ZNK7WebCore5Frame15layerTreeAsTextEv
__ZNK7WebCore5Frame15selectionBoundsEb
-__ZNK7WebCore5Frame17firstRectForRangeEPNS_5RangeE
__ZNK7WebCore5Frame18documentTypeStringEv
__ZNK7WebCore5Frame18selectionTextRectsERN3WTF6VectorINS_9FloatRectELm0EEENS0_30SelectionRectRespectTransformsEb
__ZNK7WebCore5Frame20selectionGranularityEv
-__ZNK7WebCore5Frame30applyEditingStyleToBodyElementEv
-__ZNK7WebCore5Frame31fontAttributesForSelectionStartEv
-__ZNK7WebCore5Frame37baseWritingDirectionForSelectionStartEv
__ZNK7WebCore5Frame8settingsEv
__ZNK7WebCore5Frame9domWindowEv
__ZNK7WebCore5Range11startOffsetERi
@@ -1009,13 +1008,18 @@ __ZNK7WebCore5Range9endOffsetERi
__ZNK7WebCore5Range9firstNodeEv
__ZNK7WebCore6Chrome12createWindowEPNS_5FrameERKNS_16FrameLoadRequestERKNS_14WindowFeaturesE
__ZNK7WebCore6Cursor14platformCursorEv
+__ZNK7WebCore6Editor12selectedTextEv
__ZNK7WebCore6Editor13canEditRichlyEv
__ZNK7WebCore6Editor16compositionRangeEv
__ZNK7WebCore6Editor16fontForSelectionERb
+__ZNK7WebCore6Editor17firstRectForRangeEPNS_5RangeE
__ZNK7WebCore6Editor17selectionHasStyleEPNS_19CSSStyleDeclarationE
__ZNK7WebCore6Editor17shouldDeleteRangeEPNS_5RangeE
__ZNK7WebCore6Editor22selectionStartHasStyleEPNS_19CSSStyleDeclarationE
__ZNK7WebCore6Editor23getCompositionSelectionERjS1_
+__ZNK7WebCore6Editor30applyEditingStyleToBodyElementEv
+__ZNK7WebCore6Editor31fontAttributesForSelectionStartEv
+__ZNK7WebCore6Editor37baseWritingDirectionForSelectionStartEv
__ZNK7WebCore6Editor6canCutEv
__ZNK7WebCore6Editor7Command11isSupportedEv
__ZNK7WebCore6Editor7Command15isTextInsertionEv
diff --git a/WebCore/WebCore.gyp/WebCore.gyp b/WebCore/WebCore.gyp/WebCore.gyp
index 595034e..6282530 100644
--- a/WebCore/WebCore.gyp/WebCore.gyp
+++ b/WebCore/WebCore.gyp/WebCore.gyp
@@ -1212,6 +1212,9 @@
['include', 'platform/Theme\\.cpp$'],
['include', 'WebKit/mac/WebCoreSupport/WebSystemInterface\\.mm$'],
+
+ # Chromium Mac does not use skia.
+ ['exclude', 'platform/graphics/skia/[^/]*Skia\\.(cpp|h)$'],
],
'sources!': [
# The Mac uses platform/mac/KillRingMac.mm instead of the dummy
@@ -1220,7 +1223,7 @@
# The Mac currently uses FontCustomPlatformData.cpp from
# platform/graphics/mac, included by regex above, instead.
- '../platform/graphics/chromium/FontCustomPlatformData.cpp',
+ '../platform/graphics/skia/FontCustomPlatformData.cpp',
# The Mac currently uses ScrollbarThemeChromiumMac.mm, which is not
# related to ScrollbarThemeChromium.cpp.
@@ -1230,22 +1233,6 @@
# by regex above, instead.
'../platform/graphics/ImageSource.cpp',
- # These Skia files aren't currently built on the Mac, which uses
- # CoreGraphics directly for this portion of graphics handling.
- '../platform/graphics/skia/FloatPointSkia.cpp',
- '../platform/graphics/skia/FloatRectSkia.cpp',
- '../platform/graphics/skia/GradientSkia.cpp',
- '../platform/graphics/skia/GraphicsContext3DSkia.cpp',
- '../platform/graphics/skia/GraphicsContextSkia.cpp',
- '../platform/graphics/skia/ImageBufferSkia.cpp',
- '../platform/graphics/skia/ImageSkia.cpp',
- '../platform/graphics/skia/ImageSourceSkia.cpp',
- '../platform/graphics/skia/IntPointSkia.cpp',
- '../platform/graphics/skia/IntRectSkia.cpp',
- '../platform/graphics/skia/PathSkia.cpp',
- '../platform/graphics/skia/PatternSkia.cpp',
- '../platform/graphics/skia/TransformationMatrixSkia.cpp',
-
# RenderThemeChromiumSkia is not used on mac since RenderThemeChromiumMac
# does not reference the Skia code that is used by Windows and Linux.
'../rendering/RenderThemeChromiumSkia.cpp',
@@ -1279,6 +1266,8 @@
'sources/': [
['exclude', 'Posix\\.cpp$'],
['include', '/opentype/'],
+ ['include', '/ScrollAnimatorWin\\.cpp$'],
+ ['include', '/ScrollAnimatorWin\\.h$'],
['include', '/SkiaFontWin\\.cpp$'],
['include', '/TransparencyWin\\.cpp$'],
],
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 89f4202..88f0149 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -96,6 +96,7 @@
'fileapi/EntryCallback.idl',
'fileapi/ErrorCallback.idl',
'fileapi/File.idl',
+ 'fileapi/FileCallback.idl',
'fileapi/FileEntry.idl',
'fileapi/FileError.idl',
'fileapi/FileException.idl',
@@ -104,6 +105,7 @@
'fileapi/FileReaderSync.idl',
'fileapi/FileSystemCallback.idl',
'fileapi/FileWriter.idl',
+ 'fileapi/FileWriterCallback.idl',
'fileapi/Flags.idl',
'fileapi/Metadata.idl',
'fileapi/MetadataCallback.idl',
@@ -512,6 +514,8 @@
'bindings/generic/ActiveDOMCallback.cpp',
'bindings/generic/ActiveDOMCallback.h',
'bindings/generic/BindingDOMWindow.h',
+ 'bindings/generic/BindingFrame.h',
+ 'bindings/generic/BindingLocation.h',
'bindings/generic/BindingSecurity.h',
'bindings/generic/BindingSecurityBase.cpp',
'bindings/generic/BindingSecurityBase.h',
@@ -531,6 +535,7 @@
'bindings/js/JSAttrCustom.cpp',
'bindings/js/JSAudioConstructor.cpp',
'bindings/js/JSAudioConstructor.h',
+ 'bindings/js/JSBinding.h',
'bindings/js/JSCanvasRenderingContextCustom.cpp',
'bindings/js/JSCanvasRenderingContext2DCustom.cpp',
'bindings/js/JSCDATASectionCustom.cpp',
@@ -710,6 +715,8 @@
'bindings/js/WebCoreJSClientData.h',
'bindings/js/WorkerScriptController.cpp',
'bindings/js/WorkerScriptController.h',
+ 'bindings/js/specialization/JSBindingState.cpp',
+ 'bindings/js/specialization/JSBindingState.h',
'bindings/ScriptControllerBase.cpp',
'bindings/ScriptControllerBase.h',
'bindings/v8/ChildThreadDOMData.cpp',
@@ -1446,6 +1453,7 @@
'fileapi/ErrorCallback.h',
'fileapi/File.cpp',
'fileapi/File.h',
+ 'fileapi/FileCallback.h',
'fileapi/FileEntry.cpp',
'fileapi/FileEntry.h',
'fileapi/FileError.h',
@@ -1466,6 +1474,7 @@
'fileapi/FileThreadTask.h',
'fileapi/FileWriter.cpp',
'fileapi/FileWriter.h',
+ 'fileapi/FileWriterCallback.h',
'fileapi/FileWriterClient.h',
'fileapi/Flags.h',
'fileapi/LocalFileSystem.h',
@@ -1505,6 +1514,8 @@
'html/DataGridColumnList.h',
'html/DateComponents.cpp',
'html/DateComponents.h',
+ 'html/FTPDirectoryDocument.cpp',
+ 'html/FTPDirectoryDocument.h',
'html/FormDataList.cpp',
'html/FormDataList.h',
'html/HTMLAllCollection.cpp',
@@ -1589,7 +1600,6 @@
'html/HTMLImageLoader.h',
'html/HTMLInputElement.cpp',
'html/HTMLInputElement.h',
- 'html/HTMLInputStream.h',
'html/HTMLIsIndexElement.cpp',
'html/HTMLIsIndexElement.h',
'html/HTMLKeygenElement.cpp',
@@ -1680,13 +1690,21 @@
'html/HTMLViewSourceDocument.h',
'html/ImageData.cpp',
'html/ImageData.h',
+ 'html/ImageDocument.cpp',
+ 'html/ImageDocument.h',
'html/ImageResizerThread.cpp',
'html/ImageResizerThread.h',
'html/LabelsNodeList.cpp',
'html/LabelsNodeList.h',
+ 'html/MediaDocument.cpp',
+ 'html/MediaDocument.h',
'html/MediaError.h',
+ 'html/PluginDocument.cpp',
+ 'html/PluginDocument.h',
'html/StepRange.cpp',
'html/StepRange.h',
+ 'html/TextDocument.cpp',
+ 'html/TextDocument.h',
'html/TextMetrics.h',
'html/TimeRanges.cpp',
'html/TimeRanges.h',
@@ -1764,6 +1782,7 @@
'html/parser/HTMLEntitySearch.h',
'html/parser/HTMLFormattingElementList.cpp',
'html/parser/HTMLFormattingElementList.h',
+ 'html/parser/HTMLInputStream.h',
'html/parser/HTMLParserScheduler.cpp',
'html/parser/HTMLParserScheduler.h',
'html/parser/HTMLPreloadScanner.cpp',
@@ -1778,6 +1797,10 @@
'html/parser/HTMLTreeBuilder.h',
'html/parser/HTMLViewSourceParser.cpp',
'html/parser/HTMLViewSourceParser.h',
+ 'html/parser/TextDocumentParser.cpp',
+ 'html/parser/TextDocumentParser.h',
+ 'html/parser/TextViewSourceParser.cpp',
+ 'html/parser/TextViewSourceParser.h',
'inspector/InspectorClient.h',
'inspector/ConsoleMessage.cpp',
'inspector/ConsoleMessage.h',
@@ -1888,8 +1911,8 @@
'loader/CrossOriginAccessControl.h',
'loader/CrossOriginPreflightResultCache.cpp',
'loader/CrossOriginPreflightResultCache.h',
- 'loader/DocLoader.cpp',
- 'loader/DocLoader.h',
+ 'loader/CachedResourceLoader.cpp',
+ 'loader/CachedResourceLoader.h',
'loader/DocumentLoadTiming.h',
'loader/DocumentLoader.cpp',
'loader/DocumentLoader.h',
@@ -1898,8 +1921,6 @@
'loader/DocumentWriter.cpp',
'loader/DocumentWriter.h',
'loader/EmptyClients.h',
- 'loader/FTPDirectoryDocument.cpp',
- 'loader/FTPDirectoryDocument.h',
'loader/FTPDirectoryParser.cpp',
'loader/FTPDirectoryParser.h',
'loader/FormState.cpp',
@@ -1915,14 +1936,10 @@
'loader/FrameNetworkingContext.h',
'loader/HistoryController.cpp',
'loader/HistoryController.h',
- 'loader/ImageDocument.cpp',
- 'loader/ImageDocument.h',
'loader/ImageLoader.cpp',
'loader/ImageLoader.h',
'loader/MainResourceLoader.cpp',
'loader/MainResourceLoader.h',
- 'loader/MediaDocument.cpp',
- 'loader/MediaDocument.h',
'loader/NavigationAction.cpp',
'loader/NavigationAction.h',
'loader/NetscapePlugInStreamLoader.cpp',
@@ -1931,8 +1948,6 @@
'loader/PingLoader.h',
'loader/PlaceholderDocument.cpp',
'loader/PlaceholderDocument.h',
- 'loader/PluginDocument.cpp',
- 'loader/PluginDocument.h',
'loader/PolicyCallback.cpp',
'loader/PolicyCallback.h',
'loader/PolicyChecker.cpp',
@@ -1956,8 +1971,6 @@
'loader/SubresourceLoaderClient.h',
'loader/SubstituteData.h',
'loader/SubstituteResource.h',
- 'loader/TextDocument.cpp',
- 'loader/TextDocument.h',
'loader/TextResourceDecoder.cpp',
'loader/TextResourceDecoder.h',
'loader/ThreadableLoader.cpp',
@@ -2272,8 +2285,11 @@
'platform/graphics/cg/PathCG.cpp',
'platform/graphics/cg/PatternCG.cpp',
'platform/graphics/cg/TransformationMatrixCG.cpp',
+ 'platform/graphics/chromium/Canvas2DLayerChromium.cpp',
+ 'platform/graphics/chromium/Canvas2DLayerChromium.h',
'platform/graphics/chromium/CanvasLayerChromium.cpp',
'platform/graphics/chromium/CanvasLayerChromium.h',
+ 'platform/graphics/chromium/DrawingBufferChromium.cpp',
'platform/graphics/chromium/ContentLayerChromium.cpp',
'platform/graphics/chromium/ContentLayerChromium.h',
'platform/graphics/chromium/CrossProcessFontLoading.h',
@@ -2281,8 +2297,6 @@
'platform/graphics/chromium/FontCacheChromiumWin.cpp',
'platform/graphics/chromium/FontCacheLinux.cpp',
'platform/graphics/chromium/FontChromiumWin.cpp',
- 'platform/graphics/chromium/FontCustomPlatformData.cpp',
- 'platform/graphics/chromium/FontCustomPlatformData.h',
'platform/graphics/chromium/FontLinux.cpp',
'platform/graphics/chromium/FontPlatformData.h',
'platform/graphics/chromium/FontPlatformDataChromiumWin.cpp',
@@ -2320,6 +2334,8 @@
'platform/graphics/chromium/UniscribeHelperTextRun.h',
'platform/graphics/chromium/VideoLayerChromium.cpp',
'platform/graphics/chromium/VideoLayerChromium.h',
+ 'platform/graphics/chromium/WebGLLayerChromium.cpp',
+ 'platform/graphics/chromium/WebGLLayerChromium.h',
'platform/graphics/cocoa/FontPlatformData.h',
'platform/graphics/cocoa/FontPlatformDataCocoa.mm',
'platform/graphics/filters/FEBlend.cpp',
@@ -2341,6 +2357,14 @@
'platform/graphics/filters/SourceAlpha.h',
'platform/graphics/filters/SourceGraphic.cpp',
'platform/graphics/filters/SourceGraphic.h',
+ 'platform/graphics/gpu/DrawingBuffer.cpp',
+ 'platform/graphics/gpu/DrawingBuffer.h',
+ 'platform/graphics/gpu/PODArena.h',
+ 'platform/graphics/gpu/PODInterval.h',
+ 'platform/graphics/gpu/PODIntervalTree.h',
+ 'platform/graphics/gpu/PODRedBlackTree.h',
+ 'platform/graphics/gpu/SharedGraphicsContext3D.cpp',
+ 'platform/graphics/gpu/SharedGraphicsContext3D.h',
'platform/graphics/gpu/Shader.cpp',
'platform/graphics/gpu/Shader.h',
'platform/graphics/gpu/SolidFillShader.cpp',
@@ -2445,6 +2469,8 @@
'platform/graphics/skia/BitmapImageSingleFrameSkia.h',
'platform/graphics/skia/FloatPointSkia.cpp',
'platform/graphics/skia/FloatRectSkia.cpp',
+ 'platform/graphics/skia/FontCustomPlatformData.cpp',
+ 'platform/graphics/skia/FontCustomPlatformData.h',
'platform/graphics/skia/GradientSkia.cpp',
'platform/graphics/skia/GraphicsContextPlatformPrivate.h',
'platform/graphics/skia/GraphicsContextSkia.cpp',
@@ -2599,8 +2625,8 @@
'platform/graphics/ImageBuffer.cpp',
'platform/graphics/ImageBuffer.h',
'platform/graphics/ImageObserver.h',
- 'platform/graphics/ImageSource.h',
'platform/graphics/ImageSource.cpp',
+ 'platform/graphics/ImageSource.h',
'platform/graphics/IntPoint.h',
'platform/graphics/IntRect.cpp',
'platform/graphics/IntRect.h',
@@ -3158,6 +3184,10 @@
'platform/PopupMenuStyle.h',
'platform/PurgeableBuffer.h',
'platform/SSLKeyGenerator.h',
+ 'platform/ScrollAnimator.cpp',
+ 'platform/ScrollAnimator.h',
+ 'platform/ScrollAnimatorWin.cpp',
+ 'platform/ScrollAnimatorWin.h',
'platform/ScrollTypes.h',
'platform/ScrollView.cpp',
'platform/ScrollView.h',
@@ -3165,6 +3195,7 @@
'platform/SchemeRegistry.h',
'platform/Scrollbar.cpp',
'platform/Scrollbar.h',
+ 'platform/ScrollbarClient.cpp',
'platform/ScrollbarClient.h',
'platform/ScrollbarTheme.h',
'platform/ScrollbarThemeComposite.cpp',
@@ -3449,6 +3480,8 @@
'rendering/RenderSVGResourceContainer.h',
'rendering/RenderSVGResourceFilter.cpp',
'rendering/RenderSVGResourceFilter.h',
+ 'rendering/RenderSVGResourceFilterPrimitive.cpp',
+ 'rendering/RenderSVGResourceFilterPrimitive.h',
'rendering/RenderSVGResourceGradient.cpp',
'rendering/RenderSVGResourceGradient.h',
'rendering/RenderSVGResourceLinearGradient.cpp',
@@ -4277,6 +4310,7 @@
'inspector/front-end/WelcomeView.js',
'inspector/front-end/WorkersSidebarPane.js',
'inspector/front-end/audits.css',
+ 'inspector/front-end/heapProfiler.css',
'inspector/front-end/helpScreen.css',
'inspector/front-end/inspector.css',
'inspector/front-end/inspectorSyntaxHighlight.css',
diff --git a/WebCore/WebCore.pri b/WebCore/WebCore.pri
index a4c69b1..48bd9ee 100644
--- a/WebCore/WebCore.pri
+++ b/WebCore/WebCore.pri
@@ -158,12 +158,14 @@ IDL_BINDINGS += \
fileapi/EntryCallback.idl \
fileapi/ErrorCallback.idl \
fileapi/File.idl \
- fileapi/FileList.idl \
- fileapi/FileReader.idl \
- fileapi/FileWriter.idl \
+ fileapi/FileCallback.idl \
fileapi/FileEntry.idl \
fileapi/FileError.idl \
+ fileapi/FileList.idl \
+ fileapi/FileReader.idl \
fileapi/FileSystemCallback.idl \
+ fileapi/FileWriter.idl \
+ fileapi/FileWriterCallback.idl \
fileapi/Flags.idl \
fileapi/Metadata.idl \
fileapi/MetadataCallback.idl \
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 3f23cdd..01bdc75 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -184,6 +184,7 @@ WEBCORE_INCLUDEPATH = \
$$PWD/bindings \
$$PWD/bindings/generic \
$$PWD/bindings/js \
+ $$PWD/bindings/js/specialization \
$$PWD/bridge \
$$PWD/bridge/c \
$$PWD/bridge/jsc \
@@ -392,6 +393,7 @@ SOURCES += \
bindings/js/ScriptValue.cpp \
bindings/js/ScheduledAction.cpp \
bindings/js/SerializedScriptValue.cpp \
+ bindings/js/specialization/JSBindingState.cpp \
bindings/ScriptControllerBase.cpp \
bridge/IdentifierRep.cpp \
bridge/NP_jsobject.cpp \
@@ -629,7 +631,6 @@ SOURCES += \
fileapi/FileReaderSync.cpp \
fileapi/FileStreamProxy.cpp \
fileapi/FileThread.cpp \
- fileapi/FileWriter.cpp \
fileapi/ThreadableBlobRegistry.cpp \
history/BackForwardController.cpp \
history/BackForwardListImpl.cpp \
@@ -645,6 +646,7 @@ SOURCES += \
html/DataGridColumn.cpp \
html/DataGridColumnList.cpp \
html/DateComponents.cpp \
+ html/FTPDirectoryDocument.cpp \
html/FormDataList.cpp \
html/HTMLAllCollection.cpp \
html/HTMLAnchorElement.cpp \
@@ -728,9 +730,13 @@ SOURCES += \
html/HTMLUListElement.cpp \
html/HTMLViewSourceDocument.cpp \
html/ImageData.cpp \
+ html/ImageDocument.cpp \
html/ImageResizerThread.cpp \
html/LabelsNodeList.cpp \
+ html/MediaDocument.cpp \
+ html/PluginDocument.cpp \
html/StepRange.cpp \
+ html/TextDocument.cpp \
html/ValidityState.cpp \
html/canvas/CanvasGradient.cpp \
html/canvas/CanvasPattern.cpp \
@@ -751,6 +757,8 @@ SOURCES += \
html/parser/HTMLTokenizer.cpp \
html/parser/HTMLTreeBuilder.cpp \
html/parser/HTMLViewSourceParser.cpp \
+ html/parser/TextDocumentParser.cpp \
+ html/parser/TextViewSourceParser.cpp \
inspector/ConsoleMessage.cpp \
inspector/InjectedScript.cpp \
inspector/InjectedScriptHost.cpp \
@@ -785,7 +793,7 @@ SOURCES += \
loader/CachedXSLStyleSheet.cpp \
loader/CrossOriginAccessControl.cpp \
loader/CrossOriginPreflightResultCache.cpp \
- loader/DocLoader.cpp \
+ loader/CachedResourceLoader.cpp \
loader/DocumentLoader.cpp \
loader/DocumentThreadableLoader.cpp \
loader/DocumentWriter.cpp \
@@ -794,19 +802,15 @@ SOURCES += \
loader/FrameLoader.cpp \
loader/FrameLoaderStateMachine.cpp \
loader/HistoryController.cpp \
- loader/FTPDirectoryDocument.cpp \
loader/FTPDirectoryParser.cpp \
loader/icon/IconLoader.cpp \
- loader/ImageDocument.cpp \
loader/ImageLoader.cpp \
loader/loader.cpp \
loader/MainResourceLoader.cpp \
- loader/MediaDocument.cpp \
loader/NavigationAction.cpp \
loader/NetscapePlugInStreamLoader.cpp \
loader/PingLoader.cpp \
loader/PlaceholderDocument.cpp \
- loader/PluginDocument.cpp \
loader/PolicyCallback.cpp \
loader/PolicyChecker.cpp \
loader/ProgressTracker.cpp \
@@ -817,7 +821,6 @@ SOURCES += \
loader/SinkDocument.cpp \
loader/SubframeLoader.cpp \
loader/SubresourceLoader.cpp \
- loader/TextDocument.cpp \
loader/TextResourceDecoder.cpp \
loader/ThreadableLoader.cpp \
notifications/Notification.cpp \
@@ -957,7 +960,9 @@ SOURCES += \
platform/network/ResourceResponseBase.cpp \
platform/text/RegularExpression.cpp \
platform/SchemeRegistry.cpp \
+ platform/ScrollAnimator.cpp \
platform/Scrollbar.cpp \
+ platform/ScrollbarClient.cpp \
platform/ScrollbarThemeComposite.cpp \
platform/ScrollView.cpp \
platform/text/SegmentedString.cpp \
@@ -1399,7 +1404,6 @@ HEADERS += \
editing/VisibleSelection.h \
editing/visible_units.h \
editing/WrapContentsInDummySpanCommand.h \
- fileapi/AsyncFileWriter.h \
fileapi/Blob.h \
fileapi/BlobBuilder.h \
fileapi/BlobURL.h \
@@ -1412,8 +1416,6 @@ HEADERS += \
fileapi/FileStreamProxy.h \
fileapi/FileThread.h \
fileapi/FileThreadTask.h \
- fileapi/FileWriter.h \
- fileapi/FileWriterClient.h \
history/BackForwardController.h \
history/BackForwardControllerClient.h \
history/BackForwardListImpl.h \
@@ -1525,6 +1527,7 @@ HEADERS += \
html/ImageResizerThread.h \
html/LabelsNodeList.h \
html/StepRange.h \
+ html/TextDocument.h \
html/TimeRanges.h \
html/ValidityState.h \
html/parser/CSSPreloadScanner.h \
@@ -1582,7 +1585,7 @@ HEADERS += \
loader/Cache.h \
loader/CrossOriginAccessControl.h \
loader/CrossOriginPreflightResultCache.h \
- loader/DocLoader.h \
+ loader/CachedResourceLoader.h \
loader/DocumentLoader.h \
loader/DocumentThreadableLoader.h \
loader/FormState.h \
@@ -1607,7 +1610,6 @@ HEADERS += \
loader/Request.h \
loader/ResourceLoader.h \
loader/SubresourceLoader.h \
- loader/TextDocument.h \
loader/TextResourceDecoder.h \
loader/ThreadableLoader.h \
loader/WorkerThreadableLoader.h \
@@ -1787,7 +1789,9 @@ HEADERS += \
platform/qt/QtStyleOptionWebComboBox.h \
platform/qt/RenderThemeQt.h \
platform/qt/ScrollbarThemeQt.h \
+ platform/ScrollAnimator.h \
platform/Scrollbar.h \
+ platform/ScrollbarClient.h \
platform/ScrollbarThemeComposite.h \
platform/ScrollView.h \
platform/SearchPopupMenu.h \
@@ -1906,6 +1910,7 @@ HEADERS += \
rendering/RenderSVGResourceClipper.h \
rendering/RenderSVGResourceContainer.h \
rendering/RenderSVGResourceFilter.h \
+ rendering/RenderSVGResourceFilterPrimitive.h \
rendering/RenderSVGResourceGradient.h \
rendering/RenderSVGResourceLinearGradient.h \
rendering/RenderSVGResourceMarker.h \
@@ -2347,8 +2352,12 @@ maemo5 {
}
- win32-*|wince*: SOURCES += platform/win/SystemTimeWin.cpp \
- platform/graphics/win/TransformationMatrixWin.cpp
+ win32-*|wince* {
+ HEADERS += platform/ScrollAnimatorWin.h
+ SOURCES += platform/ScrollAnimatorWin.cpp \
+ platform/win/SystemTimeWin.cpp \
+ platform/graphics/win/TransformationMatrixWin.cpp
+ }
mac {
SOURCES += \
@@ -2418,7 +2427,8 @@ contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=1) {
win32-* {
INCLUDEPATH += $$PWD/plugins/win \
- $$PWD/platform/win
+ $$PWD/platform/win \
+ $$PWD/platform/graphics/win
SOURCES += plugins/win/PluginDatabaseWin.cpp \
plugins/win/PluginPackageWin.cpp \
@@ -2463,6 +2473,8 @@ contains(DEFINES, ENABLE_SQLITE=1) {
}
}
+ wince*:DEFINES += HAVE_LOCALTIME_S=0
+
SOURCES += \
platform/sql/SQLiteAuthorizer.cpp \
platform/sql/SQLiteDatabase.cpp \
@@ -2616,10 +2628,10 @@ contains(DEFINES, ENABLE_FILE_SYSTEM=1) {
fileapi/EntryArray.h \
fileapi/EntryCallback.h \
fileapi/ErrorCallback.h \
+ fileapi/FileCallback.h \
fileapi/FileEntry.h \
fileapi/FileSystemCallback.h \
fileapi/FileSystemCallbacks.h \
- fileapi/FileWriterCallback.h \
fileapi/Flags.h \
fileapi/LocalFileSystem.h \
fileapi/Metadata.h \
@@ -2640,6 +2652,17 @@ contains(DEFINES, ENABLE_FILE_SYSTEM=1) {
platform/AsyncFileSystem.cpp
}
+contains(DEFINES, ENABLE_FILE_WRITER=1) {
+ HEADERS += \
+ fileapi/AsyncFileWriter.h \
+ fileapi/FileWriter.h \
+ fileapi/FileWriterCallback.h \
+ fileapi/FileWriterClient.h
+
+ SOURCES += \
+ fileapi/FileWriter.cpp
+}
+
contains(DEFINES, ENABLE_ICONDATABASE=1) {
SOURCES += \
loader/icon/IconDatabase.cpp \
@@ -3052,6 +3075,7 @@ contains(DEFINES, ENABLE_SVG=1) {
rendering/RenderSVGResourceClipper.cpp \
rendering/RenderSVGResourceContainer.cpp \
rendering/RenderSVGResourceFilter.cpp \
+ rendering/RenderSVGResourceFilterPrimitive.cpp \
rendering/RenderSVGResourceGradient.cpp \
rendering/RenderSVGResourceLinearGradient.cpp \
rendering/RenderSVGResourceMarker.cpp \
@@ -3216,7 +3240,7 @@ HEADERS += $$WEBKIT_API_HEADERS
exists($$OUTPUT_DIR/include/QtWebKit/classheaders.pri): include($$OUTPUT_DIR/include/QtWebKit/classheaders.pri)
WEBKIT_INSTALL_HEADERS = $$WEBKIT_API_HEADERS $$WEBKIT_CLASS_HEADERS
- !symbian {
+ !symbian-abld:!symbian-sbsv2 {
headers.files = $$WEBKIT_INSTALL_HEADERS
!isEmpty(INSTALL_HEADERS): headers.path = $$INSTALL_HEADERS/QtWebKit
@@ -3230,7 +3254,7 @@ HEADERS += $$WEBKIT_API_HEADERS
INSTALLS += target headers modfile
} else {
- # INSTALLS is not implemented in qmake's s60 generators, copy headers manually
+ # INSTALLS is not implemented in qmake's mmp generators, copy headers manually
inst_headers.commands = $$QMAKE_COPY ${QMAKE_FILE_NAME} ${QMAKE_FILE_OUT}
inst_headers.input = WEBKIT_INSTALL_HEADERS
inst_headers.CONFIG = no_clean
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index ceb4fe8..92e9ee3 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -4821,6 +4821,14 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileCallback.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileCallback.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileError.cpp"
>
<FileConfiguration
@@ -5117,6 +5125,14 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileWriterCallback.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFileWriterCallback.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFlags.cpp"
>
<FileConfiguration
@@ -23481,6 +23497,14 @@
>
</File>
<File
+ RelativePath="..\loader\CachedResourceLoader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\CachedResourceLoader.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\CachedScript.cpp"
>
</File>
@@ -23517,14 +23541,6 @@
>
</File>
<File
- RelativePath="..\loader\DocLoader.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\DocLoader.h"
- >
- </File>
- <File
RelativePath="..\loader\DocumentLoader.cpp"
>
</File>
@@ -23601,14 +23617,6 @@
>
</File>
<File
- RelativePath="..\loader\FTPDirectoryDocument.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\FTPDirectoryDocument.h"
- >
- </File>
- <File
RelativePath="..\loader\FTPDirectoryParser.cpp"
>
</File>
@@ -23625,14 +23633,6 @@
>
</File>
<File
- RelativePath="..\loader\ImageDocument.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\ImageDocument.h"
- >
- </File>
- <File
RelativePath="..\loader\ImageLoader.cpp"
>
</File>
@@ -23657,14 +23657,6 @@
>
</File>
<File
- RelativePath="..\loader\MediaDocument.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\MediaDocument.h"
- >
- </File>
- <File
RelativePath="..\loader\NavigationAction.cpp"
>
</File>
@@ -23697,14 +23689,6 @@
>
</File>
<File
- RelativePath="..\loader\PluginDocument.cpp"
- >
- </File>
- <File
- RelativePath="..\loader\PluginDocument.h"
- >
- </File>
- <File
RelativePath="..\loader\PolicyCallback.cpp"
>
</File>
@@ -23817,10 +23801,6 @@
>
</File>
<File
- RelativePath="..\loader\TextDocument.cpp"
- >
- </File>
- <File
RelativePath="..\loader\TextDocument.h"
>
</File>
@@ -24289,6 +24269,22 @@
>
</File>
<File
+ RelativePath="..\platform\ScrollAnimator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\ScrollAnimator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\ScrollAnimatorWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\ScrollAnimatorWin.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\Scrollbar.cpp"
>
</File>
@@ -24297,6 +24293,10 @@
>
</File>
<File
+ RelativePath="..\platform\ScrollbarClient.cpp"
+ >
+ </File>
+ <File
RelativePath="..\platform\ScrollbarClient.h"
>
</File>
@@ -25647,6 +25647,10 @@
>
</File>
<File
+ RelativePath="..\platform\graphics\win\LocalWindowsContext.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\graphics\win\MediaPlayerPrivateFullscreenWindow.cpp"
>
</File>
@@ -30977,6 +30981,62 @@
>
</File>
<File
+ RelativePath="..\rendering\RenderSVGResourceFilterPrimitive.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\rendering\RenderSVGResourceFilterPrimitive.h"
+ >
+ </File>
+ <File
RelativePath="..\rendering\RenderSVGResourceGradient.cpp"
>
<FileConfiguration
@@ -37109,335 +37169,331 @@
>
</File>
<File
- RelativePath="..\fileapi\Blob.cpp"
+ RelativePath="..\html\AsyncImageResizer.cpp"
>
</File>
<File
- RelativePath="..\fileapi\Blob.h"
+ RelativePath="..\html\AsyncImageResizer.h"
>
</File>
<File
- RelativePath="..\fileapi\BlobBuilder.cpp"
+ RelativePath="..\fileapi\Blob.cpp"
>
</File>
<File
- RelativePath="..\fileapi\BlobBuilder.h"
+ RelativePath="..\fileapi\Blob.h"
>
</File>
<File
- RelativePath="..\fileapi\BlobURL.cpp"
+ RelativePath="..\fileapi\BlobBuilder.cpp"
>
</File>
<File
- RelativePath="..\fileapi\BlobURL.h"
+ RelativePath="..\fileapi\BlobBuilder.h"
>
</File>
<File
- RelativePath="..\fileapi\DirectoryEntry.cpp"
+ RelativePath="..\fileapi\BlobURL.cpp"
>
</File>
<File
- RelativePath="..\fileapi\DirectoryEntry.h"
+ RelativePath="..\fileapi\BlobURL.h"
>
</File>
<File
- RelativePath="..\fileapi\DirectoryReader.cpp"
+ RelativePath="..\html\canvas\CanvasGradient.cpp"
>
</File>
<File
- RelativePath="..\fileapi\DirectoryReader.h"
+ RelativePath="..\html\canvas\CanvasGradient.h"
>
</File>
<File
- RelativePath="..\fileapi\DOMFilePath.cpp"
+ RelativePath="..\html\canvas\CanvasPattern.cpp"
>
</File>
<File
- RelativePath="..\fileapi\DOMFilePath.h"
+ RelativePath="..\html\canvas\CanvasPattern.h"
>
</File>
<File
- RelativePath="..\fileapi\DOMFileSystem.cpp"
+ RelativePath="..\html\canvas\CanvasPixelArray.cpp"
>
</File>
<File
- RelativePath="..\fileapi\DOMFileSystem.h"
+ RelativePath="..\html\canvas\CanvasPixelArray.h"
>
</File>
<File
- RelativePath="..\fileapi\EntriesCallback.h"
+ RelativePath="..\html\canvas\CanvasRenderingContext.cpp"
>
</File>
<File
- RelativePath="..\fileapi\Entry.cpp"
+ RelativePath="..\html\canvas\CanvasRenderingContext.h"
>
</File>
<File
- RelativePath="..\fileapi\Entry.h"
+ RelativePath="..\html\canvas\CanvasRenderingContext2D.cpp"
>
</File>
<File
- RelativePath="..\fileapi\EntryArray.cpp"
+ RelativePath="..\html\canvas\CanvasRenderingContext2D.h"
>
</File>
<File
- RelativePath="..\fileapi\EntryArray.h"
+ RelativePath="..\html\canvas\CanvasStyle.cpp"
>
</File>
<File
- RelativePath="..\fileapi\EntryCallback.h"
+ RelativePath="..\html\canvas\CanvasStyle.h"
>
</File>
<File
- RelativePath="..\fileapi\ErrorCallback.h"
+ RelativePath="..\html\CollectionCache.cpp"
>
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
</File>
<File
- RelativePath="..\fileapi\File.cpp"
+ RelativePath="..\html\CollectionCache.h"
>
</File>
<File
- RelativePath="..\fileapi\File.h"
+ RelativePath="..\html\CollectionType.h"
>
</File>
<File
- RelativePath="..\fileapi\FileEntry.cpp"
+ RelativePath="..\html\DataGridColumn.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileEntry.h"
+ RelativePath="..\html\DataGridColumn.h"
>
</File>
<File
- RelativePath="..\fileapi\FileError.h"
+ RelativePath="..\html\DataGridColumnList.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileException.h"
+ RelativePath="..\html\DataGridColumnList.h"
>
</File>
<File
- RelativePath="..\fileapi\FileList.cpp"
+ RelativePath="..\html\DataGridDataSource.h"
>
</File>
<File
- RelativePath="..\fileapi\FileList.h"
+ RelativePath="..\html\DateComponents.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileReader.cpp"
+ RelativePath="..\html\DateComponents.h"
>
</File>
<File
- RelativePath="..\fileapi\FileReader.h"
+ RelativePath="..\fileapi\DirectoryEntry.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileReaderSync.cpp"
+ RelativePath="..\fileapi\DirectoryEntry.h"
>
</File>
<File
- RelativePath="..\fileapi\FileReaderSync.h"
+ RelativePath="..\fileapi\DirectoryReader.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileStreamProxy.cpp"
+ RelativePath="..\fileapi\DirectoryReader.h"
>
</File>
<File
- RelativePath="..\fileapi\FileStreamProxy.h"
+ RelativePath="..\html\DOMDataGridDataSource.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileSystemCallback.h"
+ RelativePath="..\html\DOMDataGridDataSource.h"
>
</File>
<File
- RelativePath="..\fileapi\FileSystemCallbacks.cpp"
+ RelativePath="..\fileapi\DOMFilePath.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileSystemCallbacks.h"
+ RelativePath="..\fileapi\DOMFilePath.h"
>
</File>
<File
- RelativePath="..\fileapi\FileThread.cpp"
+ RelativePath="..\fileapi\DOMFileSystem.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileThread.h"
+ RelativePath="..\fileapi\DOMFileSystem.h"
>
</File>
<File
- RelativePath="..\fileapi\FileThreadTask.h"
+ RelativePath="..\html\DOMFormData.cpp"
>
</File>
<File
- RelativePath="..\fileapi\FileWriter.cpp"
+ RelativePath="..\html\DOMFormData.h"
>
</File>
<File
- RelativePath="..\fileapi\FileWriter.h"
+ RelativePath="..\fileapi\EntriesCallback.h"
>
</File>
<File
- RelativePath="..\fileapi\FileWriterClient.h"
+ RelativePath="..\fileapi\Entry.cpp"
>
</File>
<File
- RelativePath="..\fileapi\Flags.h"
+ RelativePath="..\fileapi\Entry.h"
>
</File>
<File
- RelativePath="..\fileapi\LocalFileSystem.cpp"
+ RelativePath="..\fileapi\EntryArray.cpp"
>
</File>
<File
- RelativePath="..\fileapi\LocalFileSystem.h"
+ RelativePath="..\fileapi\EntryArray.h"
>
</File>
<File
- RelativePath="..\fileapi\Metadata.h"
+ RelativePath="..\fileapi\EntryCallback.h"
>
</File>
<File
- RelativePath="..\fileapi\MetadataCallback.h"
+ RelativePath="..\fileapi\ErrorCallback.h"
>
</File>
<File
- RelativePath="..\fileapi\ThreadableBlobRegistry.cpp"
+ RelativePath="..\fileapi\File.cpp"
>
</File>
<File
- RelativePath="..\fileapi\ThreadableBlobRegistry.h"
+ RelativePath="..\fileapi\File.h"
>
</File>
<File
- RelativePath="..\html\AsyncImageResizer.cpp"
+ RelativePath="..\fileapi\FileCallback.h"
>
</File>
<File
- RelativePath="..\html\AsyncImageResizer.h"
+ RelativePath="..\fileapi\FileEntry.cpp"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasGradient.cpp"
+ RelativePath="..\fileapi\FileEntry.cpp"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasGradient.h"
+ RelativePath="..\fileapi\FileEntry.h"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasPattern.cpp"
+ RelativePath="..\fileapi\FileError.h"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasPattern.h"
+ RelativePath="..\fileapi\FileException.h"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasPixelArray.cpp"
+ RelativePath="..\fileapi\FileList.cpp"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasPixelArray.h"
+ RelativePath="..\fileapi\FileList.h"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasRenderingContext.cpp"
+ RelativePath="..\fileapi\FileReader.cpp"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasRenderingContext.h"
+ RelativePath="..\fileapi\FileReader.h"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasRenderingContext2D.cpp"
+ RelativePath="..\fileapi\FileReaderSync.cpp"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasRenderingContext2D.h"
+ RelativePath="..\fileapi\FileReaderSync.h"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasStyle.cpp"
+ RelativePath="..\fileapi\FileStreamProxy.cpp"
>
</File>
<File
- RelativePath="..\html\canvas\CanvasStyle.h"
+ RelativePath="..\fileapi\FileStreamProxy.h"
>
</File>
<File
- RelativePath="..\html\CollectionCache.cpp"
- >
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="true"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\html\CollectionCache.h"
+ RelativePath="..\fileapi\FileSystemCallback.h"
>
</File>
<File
- RelativePath="..\html\CollectionType.h"
+ RelativePath="..\fileapi\FileSystemCallbacks.cpp"
>
</File>
<File
- RelativePath="..\html\DataGridColumn.cpp"
+ RelativePath="..\fileapi\FileSystemCallbacks.h"
>
</File>
<File
- RelativePath="..\html\DataGridColumn.h"
+ RelativePath="..\fileapi\FileThread.cpp"
>
</File>
<File
- RelativePath="..\html\DataGridColumnList.cpp"
+ RelativePath="..\fileapi\FileThread.h"
>
</File>
<File
- RelativePath="..\html\DataGridColumnList.h"
+ RelativePath="..\fileapi\FileThreadTask.h"
>
</File>
<File
- RelativePath="..\html\DataGridDataSource.h"
+ RelativePath="..\fileapi\FileWriter.cpp"
>
</File>
<File
- RelativePath="..\html\DateComponents.cpp"
+ RelativePath="..\fileapi\FileWriter.h"
>
</File>
<File
- RelativePath="..\html\DateComponents.h"
+ RelativePath="..\fileapi\FileWriterCallback.h"
>
</File>
<File
- RelativePath="..\html\DOMDataGridDataSource.cpp"
+ RelativePath="..\fileapi\FileWriterClient.h"
>
</File>
<File
- RelativePath="..\html\DOMDataGridDataSource.h"
+ RelativePath="..\fileapi\Flags.h"
>
</File>
<File
- RelativePath="..\html\DOMFormData.cpp"
+ RelativePath="..\html\FormDataList.cpp"
>
</File>
<File
- RelativePath="..\html\DOMFormData.h"
+ RelativePath="..\html\FormDataList.h"
>
</File>
<File
- RelativePath="..\html\FormDataList.cpp"
+ RelativePath="..\html\FTPDirectoryDocument.cpp"
>
</File>
<File
- RelativePath="..\html\FormDataList.h"
+ RelativePath="..\html\FTPDirectoryDocument.h"
>
</File>
<File
@@ -39501,10 +39557,6 @@
>
</File>
<File
- RelativePath="..\html\HTMLInputStream.h"
- >
- </File>
- <File
RelativePath="..\html\HTMLIsIndexElement.cpp"
>
<FileConfiguration
@@ -41801,6 +41853,14 @@
>
</File>
<File
+ RelativePath="..\html\ImageDocument.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\ImageDocument.h"
+ >
+ </File>
+ <File
RelativePath="..\html\ImageResizerThread.cpp"
>
</File>
@@ -41817,125 +41877,41 @@
>
</File>
<File
+ RelativePath="..\fileapi\LocalFileSystem.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\fileapi\LocalFileSystem.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\MediaDocument.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\MediaDocument.h"
+ >
+ </File>
+ <File
RelativePath="..\html\MediaError.h"
>
</File>
- <Filter
- Name="parser"
+ <File
+ RelativePath="..\fileapi\Metadata.h"
>
- <File
- RelativePath="..\html\parser\CSSPreloadScanner.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\CSSPreloadScanner.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLConstructionSite.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLConstructionSite.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLDocumentParser.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLDocumentParser.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLEntityParser.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLEntityParser.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLElementStack.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLElementStack.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLEntitySearch.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLEntitySearch.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLFormattingElementList.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLFormattingElementList.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLParserScheduler.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLParserScheduler.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLPreloadScanner.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLPreloadScanner.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLScriptRunner.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLScriptRunner.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLScriptRunnerHost.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLToken.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLTokenizer.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLTokenizer.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLTreeBuilder.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLTreeBuilder.h"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLViewSourceParser.cpp"
- >
- </File>
- <File
- RelativePath="..\html\parser\HTMLViewSourceParser.h"
- >
- </File>
- </Filter>
+ </File>
+ <File
+ RelativePath="..\fileapi\MetadataCallback.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\PluginDocument.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\PluginDocument.h"
+ >
+ </File>
<File
RelativePath="..\html\StepRange.cpp"
>
@@ -41945,6 +41921,18 @@
>
</File>
<File
+ RelativePath="..\html\TextDocument.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\fileapi\ThreadableBlobRegistry.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\fileapi\ThreadableBlobRegistry.h"
+ >
+ </File>
+ <File
RelativePath="..\html\TimeRanges.cpp"
>
</File>
@@ -41964,6 +41952,142 @@
RelativePath="..\html\VoidCallback.h"
>
</File>
+ <Filter
+ Name="parser"
+ >
+ <File
+ RelativePath="..\html\parser\CSSPreloadScanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\CSSPreloadScanner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLConstructionSite.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLConstructionSite.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLDocumentParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLDocumentParser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLElementStack.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLElementStack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLEntityParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLEntityParser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLEntitySearch.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLEntitySearch.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLFormattingElementList.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLFormattingElementList.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLInputStream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLParserScheduler.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLParserScheduler.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLPreloadScanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLPreloadScanner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLScriptRunner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLScriptRunner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLScriptRunnerHost.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLToken.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLTokenizer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLTokenizer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLTreeBuilder.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLTreeBuilder.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLViewSourceParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\HTMLViewSourceParser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\TextDocumentParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\TextDocumentParser.h"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\TextViewSourceParser.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\html\parser\TextViewSourceParser.h"
+ >
+ </File>
+ </Filter>
</Filter>
<Filter
Name="bindings"
@@ -41987,10 +42111,30 @@
RelativePath="..\bindings\generic\ActiveDOMCallback.h"
>
</File>
- </Filter>
- <Filter
- Name="generic"
- >
+ <File
+ RelativePath="..\bindings\generic\BindingFrame.h"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\generic\BindingLocation.h"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\generic\BindingSecurity.h"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\generic\BindingSecurityBase.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\generic\BindingSecurityBase.h"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\generic\GenericBinding.h"
+ >
+ </File>
<File
RelativePath="..\bindings\generic\RuntimeEnabledFeatures.cpp"
>
@@ -42344,6 +42488,10 @@
>
</File>
<File
+ RelativePath="..\bindings\js\JSBinding.h"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\JSBindingsAllInOne.cpp"
>
</File>
@@ -49639,6 +49787,62 @@
RelativePath="..\bindings\js\WorkerScriptController.h"
>
</File>
+ <File
+ RelativePath="..\bindings\js\specialization\JSBindingState.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\bindings\js\specialization\JSBindingState.h"
+ >
+ </File>
</Filter>
</Filter>
<Filter
@@ -52236,6 +52440,14 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\heapProfiler.css"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\HeapSnapshotView.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\helpScreen.css"
>
</File>
@@ -52276,10 +52488,6 @@
>
</File>
<File
- RelativePath="..\inspector\front-end\HeapSnapshotView.js"
- >
- </File>
- <File
RelativePath="..\inspector\front-end\MetricsSidebarPane.js"
>
</File>
diff --git a/WebCore/WebCore.vcproj/WebCoreCommon.vsprops b/WebCore/WebCore.vcproj/WebCoreCommon.vsprops
index c98e13b..8677c0e 100644
--- a/WebCore/WebCore.vcproj/WebCoreCommon.vsprops
+++ b/WebCore/WebCore.vcproj/WebCoreCommon.vsprops
@@ -7,7 +7,7 @@
>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\accessibility&quot;;&quot;$(ProjectDir)..\accessibility\win&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\bridge\jsc&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\fileapi&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings&quot;;&quot;$(ProjectDir)..\bindings\generic&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\dom\default&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&quot;;&quot;$(ProjectDir)..\html\canvas&quot;;&quot;$(ProjectDir)..\html\parser&quot;;&quot;$(ProjectDir)..\inspector&quot;;&quot;$(ProjectDir)..\loader&quot;;&quot;$(ProjectDir)..\loader\appcache&quot;;&quot;$(ProjectDir)..\loader\archive&quot;;&quot;$(ProjectDir)..\loader\archive\cf&quot;;&quot;$(ProjectDir)..\loader\icon&quot;;&quot;$(ProjectDir)..\mathml&quot;;&quot;$(ProjectDir)..\notifications&quot;;&quot;$(ProjectDir)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&quot;;&quot;$(ProjectDir)..\platform\mock&quot;;&quot;$(ProjectDir)..\platform\sql&quot;;&quot;$(ProjectDir)..\platform\win&quot;;&quot;$(ProjectDir)..\platform\network&quot;;&quot;$(ProjectDir)..\platform\network\win&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\filters&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\text\transcoder&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\animation&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\websockets&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\private\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\zlib&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\accessibility&quot;;&quot;$(ProjectDir)..\accessibility\win&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\bridge\jsc&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\fileapi&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings&quot;;&quot;$(ProjectDir)..\bindings\generic&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\bindings\js\specialization&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\dom\default&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&quot;;&quot;$(ProjectDir)..\html\canvas&quot;;&quot;$(ProjectDir)..\html\parser&quot;;&quot;$(ProjectDir)..\inspector&quot;;&quot;$(ProjectDir)..\loader&quot;;&quot;$(ProjectDir)..\loader\appcache&quot;;&quot;$(ProjectDir)..\loader\archive&quot;;&quot;$(ProjectDir)..\loader\archive\cf&quot;;&quot;$(ProjectDir)..\loader\icon&quot;;&quot;$(ProjectDir)..\mathml&quot;;&quot;$(ProjectDir)..\notifications&quot;;&quot;$(ProjectDir)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&quot;;&quot;$(ProjectDir)..\platform\mock&quot;;&quot;$(ProjectDir)..\platform\sql&quot;;&quot;$(ProjectDir)..\platform\win&quot;;&quot;$(ProjectDir)..\platform\network&quot;;&quot;$(ProjectDir)..\platform\network\win&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\filters&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\text\transcoder&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\animation&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\websockets&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\private\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\zlib&quot;"
PreprocessorDefinitions="__WIN32__;DISABLE_3D_RENDERING;WEBCORE_CONTEXT_MENUS"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index c8b88ec..8893d0a 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -324,6 +324,8 @@
18F831B80FD48C7800D8C56B /* WorkerLoaderProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 18F831B70FD48C7800D8C56B /* WorkerLoaderProxy.h */; };
1921327411C0E6BB00456238 /* SVGFEConvolveMatrixElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1921327111C0E6BB00456238 /* SVGFEConvolveMatrixElement.cpp */; };
1921327511C0E6BB00456238 /* SVGFEConvolveMatrixElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1921327211C0E6BB00456238 /* SVGFEConvolveMatrixElement.h */; };
+ 19423B501234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19423B4E1234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.cpp */; };
+ 19423B511234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.h in Headers */ = {isa = PBXBuildFile; fileRef = 19423B4F1234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.h */; };
19BFF64B11C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 19BFF64611C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElement.h */; };
19BFF64C11C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 19BFF64711C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElement.mm */; };
19BFF64D11C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElementInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 19BFF64811C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElementInternal.h */; };
@@ -408,8 +410,6 @@
1A569D230D7E2B82007C3983 /* runtime_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CF40D7E2B82007C3983 /* runtime_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
1A569D240D7E2B82007C3983 /* runtime_root.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CF50D7E2B82007C3983 /* runtime_root.cpp */; };
1A569D250D7E2B82007C3983 /* runtime_root.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CF60D7E2B82007C3983 /* runtime_root.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 1A6938010A11100A00C127FE /* TextDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6937FF0A11100A00C127FE /* TextDocument.cpp */; };
- 1A6938020A11100A00C127FE /* TextDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6938000A11100A00C127FE /* TextDocument.h */; };
1A71D57B0F33819000F9CE4E /* IdentifierRep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A71D5790F33819000F9CE4E /* IdentifierRep.cpp */; };
1A71D57C0F33819000F9CE4E /* IdentifierRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71D57A0F33819000F9CE4E /* IdentifierRep.h */; settings = {ATTRIBUTES = (Private, ); }; };
1A750D5C0A90DEE1000FF215 /* JSTreeWalker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A750D5A0A90DEE1000FF215 /* JSTreeWalker.cpp */; };
@@ -436,8 +436,6 @@
1A7FA61B0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */; };
1A7FA6490DDA3CBA0028F8A5 /* NetworkStateNotifierMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7FA6470DDA3CBA0028F8A5 /* NetworkStateNotifierMac.cpp */; };
1A7FA7CC0DDA4B770028F8A5 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A7FA7CB0DDA4B770028F8A5 /* SystemConfiguration.framework */; };
- 1A820D910A13EBA600AF843C /* ImageDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A820D8F0A13EBA600AF843C /* ImageDocument.cpp */; };
- 1A820D920A13EBA600AF843C /* ImageDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A820D900A13EBA600AF843C /* ImageDocument.h */; };
1A85B18F0A1B18A200D8C87C /* JSHTMLHtmlElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A85B18D0A1B18A200D8C87C /* JSHTMLHtmlElement.cpp */; };
1A85B1900A1B18A200D8C87C /* JSHTMLHtmlElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A85B18E0A1B18A200D8C87C /* JSHTMLHtmlElement.h */; };
1A85B1E60A1B240500D8C87C /* JSHTMLDirectoryElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A85B1E00A1B240500D8C87C /* JSHTMLDirectoryElement.cpp */; };
@@ -497,8 +495,6 @@
1AC2260C0DB69F190089B669 /* JSDOMApplicationCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC2260A0DB69F190089B669 /* JSDOMApplicationCache.cpp */; };
1AC2260D0DB69F190089B669 /* JSDOMApplicationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC2260B0DB69F190089B669 /* JSDOMApplicationCache.h */; };
1AC226170DB69F740089B669 /* JSDOMApplicationCacheCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC226160DB69F740089B669 /* JSDOMApplicationCacheCustom.cpp */; };
- 1AC694C70A3B1676003F5049 /* PluginDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC694C50A3B1676003F5049 /* PluginDocument.cpp */; };
- 1AC694C80A3B1676003F5049 /* PluginDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC694C60A3B1676003F5049 /* PluginDocument.h */; };
1ACD1B630B029739007E5016 /* DOMCSSStyleDeclarationInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85E711440AC5D5340053270F /* DOMCSSStyleDeclarationInternal.h */; };
1ACE53DF0A8D18810022947D /* JSDOMParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACE53DD0A8D18810022947D /* JSDOMParser.cpp */; };
1ACE53E00A8D18810022947D /* JSDOMParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ACE53DE0A8D18810022947D /* JSDOMParser.h */; };
@@ -1217,8 +1213,6 @@
51E1ECC30C91C90400DC255B /* PageURLRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E1ECBD0C91C90400DC255B /* PageURLRecord.h */; };
51E3F9C70DA059DC00250911 /* Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E3F9C50DA059DC00250911 /* Storage.cpp */; };
51E3F9D60DA05E1D00250911 /* JSStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E3F9D40DA05E1D00250911 /* JSStorage.cpp */; };
- 51E4ADB60C42B4CF0042BC55 /* FTPDirectoryDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E4ADB20C42B4CF0042BC55 /* FTPDirectoryDocument.cpp */; };
- 51E4ADB70C42B4CF0042BC55 /* FTPDirectoryDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E4ADB30C42B4CF0042BC55 /* FTPDirectoryDocument.h */; };
51EC92590CE90DB400F90308 /* SQLError.h in Headers */ = {isa = PBXBuildFile; fileRef = 51EC92570CE90DB400F90308 /* SQLError.h */; settings = {ATTRIBUTES = (Private, ); }; };
51EC92650CE90DD400F90308 /* JSCustomSQLStatementErrorCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51EC925D0CE90DD400F90308 /* JSCustomSQLStatementErrorCallback.cpp */; };
51FAFE340CECBF2D00BB3F24 /* DatabaseTrackerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FAFE330CECBF2D00BB3F24 /* DatabaseTrackerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2381,6 +2375,12 @@
85FF315A0AAFBFCB00374F38 /* DOMKeyboardEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */; };
85FF315B0AAFBFCB00374F38 /* DOMKeyboardEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */; };
86243D0111BC31F700CC006A /* JSArrayBufferViewHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */; };
+ 893C47A71238908B002B3D86 /* FileCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 893C47A51238908B002B3D86 /* FileCallback.h */; };
+ 893C47A81238908B002B3D86 /* FileWriterCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 893C47A61238908B002B3D86 /* FileWriterCallback.h */; };
+ 893C47B71238A099002B3D86 /* JSFileCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 893C47B51238A099002B3D86 /* JSFileCallback.cpp */; };
+ 893C47B81238A099002B3D86 /* JSFileCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 893C47B61238A099002B3D86 /* JSFileCallback.h */; };
+ 893C47BB1238A0A9002B3D86 /* JSFileWriterCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 893C47B91238A0A9002B3D86 /* JSFileWriterCallback.cpp */; };
+ 893C47BC1238A0A9002B3D86 /* JSFileWriterCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 893C47BA1238A0A9002B3D86 /* JSFileWriterCallback.h */; };
89878552122CA064003AABDA /* DirectoryEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 89878539122CA064003AABDA /* DirectoryEntry.cpp */; };
89878553122CA064003AABDA /* DirectoryEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 8987853A122CA064003AABDA /* DirectoryEntry.h */; };
89878554122CA064003AABDA /* DirectoryReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8987853B122CA064003AABDA /* DirectoryReader.cpp */; };
@@ -2726,7 +2726,14 @@
97059978107D975200A50A7C /* PolicyCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 97059974107D975200A50A7C /* PolicyCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
97059979107D975200A50A7C /* PolicyChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97059975107D975200A50A7C /* PolicyChecker.cpp */; };
9705997A107D975200A50A7C /* PolicyChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 97059976107D975200A50A7C /* PolicyChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 9719AF0011D09F2C00D45831 /* HTMLInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 9719AEFF11D09F2C00D45831 /* HTMLInputStream.h */; };
+ 97205AAF123928CA00B17380 /* FTPDirectoryDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97205AAD123928CA00B17380 /* FTPDirectoryDocument.cpp */; };
+ 97205AB0123928CA00B17380 /* FTPDirectoryDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 97205AAE123928CA00B17380 /* FTPDirectoryDocument.h */; };
+ 97205AB51239291000B17380 /* ImageDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97205AB11239291000B17380 /* ImageDocument.cpp */; };
+ 97205AB61239291000B17380 /* ImageDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 97205AB21239291000B17380 /* ImageDocument.h */; };
+ 97205AB71239291000B17380 /* MediaDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97205AB31239291000B17380 /* MediaDocument.cpp */; };
+ 97205AB81239291000B17380 /* MediaDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 97205AB41239291000B17380 /* MediaDocument.h */; };
+ 97205ABB1239292700B17380 /* PluginDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97205AB91239292700B17380 /* PluginDocument.cpp */; };
+ 97205ABC1239292700B17380 /* PluginDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 97205ABA1239292700B17380 /* PluginDocument.h */; };
973889A0116EA9DC00ADF313 /* DocumentWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9738899E116EA9DC00ADF313 /* DocumentWriter.cpp */; };
973889A1116EA9DC00ADF313 /* DocumentWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9738899F116EA9DC00ADF313 /* DocumentWriter.h */; settings = {ATTRIBUTES = (Private, ); }; };
973E325610883B7C005BC493 /* ResourceLoadNotifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 973E325410883B7C005BC493 /* ResourceLoadNotifier.cpp */; };
@@ -2785,6 +2792,13 @@
977B387A122883E900B81FF8 /* HTMLViewSourceParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 977B3861122883E900B81FF8 /* HTMLViewSourceParser.h */; };
979F43D31075E44A0000F83B /* RedirectScheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 979F43D11075E44A0000F83B /* RedirectScheduler.cpp */; };
979F43D41075E44A0000F83B /* RedirectScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 979F43D21075E44A0000F83B /* RedirectScheduler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 97BC84831236FD93000C6161 /* TextDocumentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC84811236FD93000C6161 /* TextDocumentParser.cpp */; };
+ 97BC84841236FD93000C6161 /* TextDocumentParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC84821236FD93000C6161 /* TextDocumentParser.h */; };
+ 97BC849B12370A4B000C6161 /* HTMLInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC849A12370A4B000C6161 /* HTMLInputStream.h */; };
+ 97BC84A412370DC8000C6161 /* TextViewSourceParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC84A212370DC7000C6161 /* TextViewSourceParser.cpp */; };
+ 97BC84A512370DC8000C6161 /* TextViewSourceParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC84A312370DC8000C6161 /* TextViewSourceParser.h */; };
+ 97BC84B312371180000C6161 /* TextDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC84B112371180000C6161 /* TextDocument.cpp */; };
+ 97BC84B412371180000C6161 /* TextDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC84B212371180000C6161 /* TextDocument.h */; };
97C078501165D5BE003A32EF /* SuffixTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 97C0784F1165D5BE003A32EF /* SuffixTree.h */; };
97DCE20110807C750057D394 /* HistoryController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97DCE1FF10807C750057D394 /* HistoryController.cpp */; };
97DCE20210807C750057D394 /* HistoryController.h in Headers */ = {isa = PBXBuildFile; fileRef = 97DCE20010807C750057D394 /* HistoryController.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2837,6 +2851,15 @@
A59E3C1F11580F510072928E /* KeyEventIPhone.mm in Sources */ = {isa = PBXBuildFile; fileRef = A59E3C1D11580F510072928E /* KeyEventIPhone.mm */; };
A5AFB34F115151A700B045CB /* StepRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5AFB34D115151A700B045CB /* StepRange.cpp */; };
A5AFB350115151A700B045CB /* StepRange.h in Headers */ = {isa = PBXBuildFile; fileRef = A5AFB34E115151A700B045CB /* StepRange.h */; };
+ A622A8EE122C442A00A785B3 /* JSBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8ED122C442A00A785B3 /* JSBinding.h */; };
+ A622A8F2122C444500A785B3 /* JSBindingState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A622A8F0122C444500A785B3 /* JSBindingState.cpp */; };
+ A622A8F3122C444500A785B3 /* JSBindingState.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F1122C444500A785B3 /* JSBindingState.h */; };
+ A622A8FA122C44A600A785B3 /* BindingLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F4122C44A600A785B3 /* BindingLocation.h */; };
+ A622A8FB122C44A600A785B3 /* BindingSecurity.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F5122C44A600A785B3 /* BindingSecurity.h */; };
+ A622A8FC122C44A600A785B3 /* BindingSecurityBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A622A8F6122C44A600A785B3 /* BindingSecurityBase.cpp */; };
+ A622A8FD122C44A600A785B3 /* BindingSecurityBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F7122C44A600A785B3 /* BindingSecurityBase.h */; };
+ A622A8FE122C44A600A785B3 /* BindingUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F8122C44A600A785B3 /* BindingUtilities.h */; };
+ A622A8FF122C44A600A785B3 /* GenericBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = A622A8F9122C44A600A785B3 /* GenericBinding.h */; };
A718760E0B2A120100A16ECE /* DragActions.h in Headers */ = {isa = PBXBuildFile; fileRef = A718760D0B2A120100A16ECE /* DragActions.h */; settings = {ATTRIBUTES = (Private, ); }; };
A71878900B2D04AC00A16ECE /* DragControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A718788F0B2D04AC00A16ECE /* DragControllerMac.mm */; };
A7352C190B1BB89D00A986D0 /* RenderSVGBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7352C170B1BB89D00A986D0 /* RenderSVGBlock.cpp */; };
@@ -3727,8 +3750,6 @@
AB247A6C0AFD6383003FA5FD /* RenderSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB247A6A0AFD6383003FA5FD /* RenderSlider.cpp */; };
AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = AB247A6B0AFD6383003FA5FD /* RenderSlider.h */; };
AB31C91E10AE1B8E000C7B92 /* LineClampValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AB31C91D10AE1B8E000C7B92 /* LineClampValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
- AB40484D0E083FA8007D6920 /* MediaDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB40484B0E083FA8007D6920 /* MediaDocument.cpp */; };
- AB40484E0E083FA8007D6920 /* MediaDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = AB40484C0E083FA8007D6920 /* MediaDocument.h */; };
AB4261D80A2F6C9700BDD17D /* missingImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = AB4261D70A2F6C9700BDD17D /* missingImage.tiff */; };
AB4CB4EB0B8BDA3D009F40B0 /* JSHTMLSelectElementCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = AB4CB4EA0B8BDA3D009F40B0 /* JSHTMLSelectElementCustom.h */; };
AB67D1A8097F3AE300F9392E /* RenderTextControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB67D1A6097F3AE300F9392E /* RenderTextControl.cpp */; };
@@ -4836,7 +4857,8 @@
BC99812E0DBE807A008CE9EF /* DOMAbstractViewFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = BC99812D0DBE807A008CE9EF /* DOMAbstractViewFrame.h */; };
BC9ADD230CC4032600098C4C /* WebKitCSSTransformValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9ADD220CC4032600098C4C /* WebKitCSSTransformValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC9ADD800CC4092200098C4C /* WebKitCSSTransformValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9ADD7F0CC4092200098C4C /* WebKitCSSTransformValue.cpp */; };
- BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9BC64D0E7C4889008B9849 /* ScrollbarClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC9BC64D0E7C4889008B9849 /* ScrollbarClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCA169A20BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */; };
BCA169A30BFD55B40019CA76 /* JSHTMLTableCaptionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */; };
BCA2B061105047600043BD1C /* UserScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA2B0601050475F0043BD1C /* UserScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4871,8 +4893,8 @@
BCB16C240979C3BD00467741 /* CachedScript.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0B0979C3BD00467741 /* CachedScript.h */; };
BCB16C270979C3BD00467741 /* CachedXSLStyleSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */; };
BCB16C280979C3BD00467741 /* CachedXSLStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */; };
- BCB16C290979C3BD00467741 /* DocLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C100979C3BD00467741 /* DocLoader.cpp */; };
- BCB16C2A0979C3BD00467741 /* DocLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C110979C3BD00467741 /* DocLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BCB16C290979C3BD00467741 /* CachedResourceLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C100979C3BD00467741 /* CachedResourceLoader.cpp */; };
+ BCB16C2A0979C3BD00467741 /* CachedResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C110979C3BD00467741 /* CachedResourceLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCB16C2C0979C3BD00467741 /* loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C130979C3BD00467741 /* loader.cpp */; };
BCB16C2D0979C3BD00467741 /* loader.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB16C140979C3BD00467741 /* loader.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCB16C2E0979C3BD00467741 /* Request.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB16C150979C3BD00467741 /* Request.cpp */; };
@@ -4930,6 +4952,7 @@
BCD9C2C10C17B69E005C90A2 /* JSNamedNodeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD9C2BD0C17B69E005C90A2 /* JSNamedNodeMap.h */; };
BCD9C2C20C17B69E005C90A2 /* JSNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD9C2BE0C17B69E005C90A2 /* JSNodeList.cpp */; };
BCD9C2C30C17B69E005C90A2 /* JSNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD9C2BF0C17B69E005C90A2 /* JSNodeList.h */; };
+ BCDD454E1236C95C009A7985 /* ColumnInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDD454D1236C95C009A7985 /* ColumnInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCDF317B11F8D683003C5BF8 /* UserTypingGestureIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDF317911F8D683003C5BF8 /* UserTypingGestureIndicator.cpp */; };
BCDF317C11F8D683003C5BF8 /* UserTypingGestureIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDF317A11F8D683003C5BF8 /* UserTypingGestureIndicator.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCDFD48E0E305290009D10AD /* XMLHttpRequestUpload.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDFD48C0E305290009D10AD /* XMLHttpRequestUpload.h */; };
@@ -5126,6 +5149,8 @@
C5EBDD84105EDDEC0056816F /* StorageEventDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */; };
C6D74AD509AA282E000B0A52 /* ModifySelectionListLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */; };
C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
+ CA3BF67C10D99BAE00E6CE53 /* ScrollAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */; };
+ CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */; };
CE02F0C411E83ADD00C6684A /* ScriptControllerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */; };
CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE057FA41220731100A476D5 /* DocumentMarkerController.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -6136,6 +6161,8 @@
1921327111C0E6BB00456238 /* SVGFEConvolveMatrixElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFEConvolveMatrixElement.cpp; sourceTree = "<group>"; };
1921327211C0E6BB00456238 /* SVGFEConvolveMatrixElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGFEConvolveMatrixElement.h; sourceTree = "<group>"; };
1921327311C0E6BB00456238 /* SVGFEConvolveMatrixElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SVGFEConvolveMatrixElement.idl; sourceTree = "<group>"; };
+ 19423B4E1234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourceFilterPrimitive.cpp; sourceTree = "<group>"; };
+ 19423B4F1234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceFilterPrimitive.h; sourceTree = "<group>"; };
19BFF64611C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMSVGFEConvolveMatrixElement.h; sourceTree = "<group>"; };
19BFF64711C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMSVGFEConvolveMatrixElement.mm; sourceTree = "<group>"; };
19BFF64811C0F2AC00B8C04D /* DOMSVGFEConvolveMatrixElementInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMSVGFEConvolveMatrixElementInternal.h; sourceTree = "<group>"; };
@@ -6224,8 +6251,6 @@
1A569CF40D7E2B82007C3983 /* runtime_object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = runtime_object.h; path = bridge/runtime_object.h; sourceTree = "<group>"; };
1A569CF50D7E2B82007C3983 /* runtime_root.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = runtime_root.cpp; path = bridge/runtime_root.cpp; sourceTree = "<group>"; };
1A569CF60D7E2B82007C3983 /* runtime_root.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = runtime_root.h; path = bridge/runtime_root.h; sourceTree = "<group>"; };
- 1A6937FF0A11100A00C127FE /* TextDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TextDocument.cpp; sourceTree = "<group>"; };
- 1A6938000A11100A00C127FE /* TextDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextDocument.h; sourceTree = "<group>"; };
1A71D5790F33819000F9CE4E /* IdentifierRep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IdentifierRep.cpp; path = bridge/IdentifierRep.cpp; sourceTree = "<group>"; };
1A71D57A0F33819000F9CE4E /* IdentifierRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IdentifierRep.h; path = bridge/IdentifierRep.h; sourceTree = "<group>"; };
1A750D3C0A90DE35000FF215 /* TreeWalker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TreeWalker.idl; sourceTree = "<group>"; };
@@ -6255,8 +6280,6 @@
1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkStateNotifier.cpp; sourceTree = "<group>"; };
1A7FA6470DDA3CBA0028F8A5 /* NetworkStateNotifierMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkStateNotifierMac.cpp; sourceTree = "<group>"; };
1A7FA7CB0DDA4B770028F8A5 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = "<absolute>"; };
- 1A820D8F0A13EBA600AF843C /* ImageDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDocument.cpp; sourceTree = "<group>"; };
- 1A820D900A13EBA600AF843C /* ImageDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageDocument.h; sourceTree = "<group>"; };
1A85B17D0A1B183600D8C87C /* HTMLHtmlElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLHtmlElement.idl; sourceTree = "<group>"; };
1A85B18D0A1B18A200D8C87C /* JSHTMLHtmlElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLHtmlElement.cpp; sourceTree = "<group>"; };
1A85B18E0A1B18A200D8C87C /* JSHTMLHtmlElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLHtmlElement.h; sourceTree = "<group>"; };
@@ -6328,8 +6351,6 @@
1AC2260A0DB69F190089B669 /* JSDOMApplicationCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMApplicationCache.cpp; sourceTree = "<group>"; };
1AC2260B0DB69F190089B669 /* JSDOMApplicationCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMApplicationCache.h; sourceTree = "<group>"; };
1AC226160DB69F740089B669 /* JSDOMApplicationCacheCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMApplicationCacheCustom.cpp; sourceTree = "<group>"; };
- 1AC694C50A3B1676003F5049 /* PluginDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PluginDocument.cpp; sourceTree = "<group>"; };
- 1AC694C60A3B1676003F5049 /* PluginDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginDocument.h; sourceTree = "<group>"; };
1ACE53DD0A8D18810022947D /* JSDOMParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMParser.cpp; sourceTree = "<group>"; };
1ACE53DE0A8D18810022947D /* JSDOMParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSDOMParser.h; sourceTree = "<group>"; };
1ACE53E10A8D18E70022947D /* DOMParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DOMParser.cpp; sourceTree = "<group>"; };
@@ -7128,8 +7149,6 @@
51E3F9D10DA05D7100250911 /* Storage.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Storage.idl; sourceTree = "<group>"; };
51E3F9D40DA05E1D00250911 /* JSStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStorage.cpp; sourceTree = "<group>"; };
51E3F9D50DA05E1D00250911 /* JSStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStorage.h; sourceTree = "<group>"; };
- 51E4ADB20C42B4CF0042BC55 /* FTPDirectoryDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectoryDocument.cpp; sourceTree = "<group>"; };
- 51E4ADB30C42B4CF0042BC55 /* FTPDirectoryDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FTPDirectoryDocument.h; sourceTree = "<group>"; };
51EC92570CE90DB400F90308 /* SQLError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLError.h; sourceTree = "<group>"; };
51EC92580CE90DB400F90308 /* SQLError.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLError.idl; sourceTree = "<group>"; };
51EC925D0CE90DD400F90308 /* JSCustomSQLStatementErrorCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomSQLStatementErrorCallback.cpp; sourceTree = "<group>"; };
@@ -8259,6 +8278,12 @@
85FF31580AAFBFCB00374F38 /* DOMKeyboardEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMKeyboardEvent.h; sourceTree = "<group>"; };
85FF31590AAFBFCB00374F38 /* DOMKeyboardEvent.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMKeyboardEvent.mm; sourceTree = "<group>"; };
86243D0011BC31F700CC006A /* JSArrayBufferViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayBufferViewHelper.h; sourceTree = "<group>"; };
+ 893C47A51238908B002B3D86 /* FileCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileCallback.h; path = fileapi/FileCallback.h; sourceTree = "<group>"; };
+ 893C47A61238908B002B3D86 /* FileWriterCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileWriterCallback.h; path = fileapi/FileWriterCallback.h; sourceTree = "<group>"; };
+ 893C47B51238A099002B3D86 /* JSFileCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFileCallback.cpp; sourceTree = "<group>"; };
+ 893C47B61238A099002B3D86 /* JSFileCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFileCallback.h; sourceTree = "<group>"; };
+ 893C47B91238A0A9002B3D86 /* JSFileWriterCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFileWriterCallback.cpp; sourceTree = "<group>"; };
+ 893C47BA1238A0A9002B3D86 /* JSFileWriterCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFileWriterCallback.h; sourceTree = "<group>"; };
89878539122CA064003AABDA /* DirectoryEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DirectoryEntry.cpp; path = fileapi/DirectoryEntry.cpp; sourceTree = "<group>"; };
8987853A122CA064003AABDA /* DirectoryEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DirectoryEntry.h; path = fileapi/DirectoryEntry.h; sourceTree = "<group>"; };
8987853B122CA064003AABDA /* DirectoryReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DirectoryReader.cpp; path = fileapi/DirectoryReader.cpp; sourceTree = "<group>"; };
@@ -8590,7 +8615,14 @@
97059974107D975200A50A7C /* PolicyCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolicyCallback.h; sourceTree = "<group>"; };
97059975107D975200A50A7C /* PolicyChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolicyChecker.cpp; sourceTree = "<group>"; };
97059976107D975200A50A7C /* PolicyChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolicyChecker.h; sourceTree = "<group>"; };
- 9719AEFF11D09F2C00D45831 /* HTMLInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLInputStream.h; sourceTree = "<group>"; };
+ 97205AAD123928CA00B17380 /* FTPDirectoryDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectoryDocument.cpp; sourceTree = "<group>"; };
+ 97205AAE123928CA00B17380 /* FTPDirectoryDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FTPDirectoryDocument.h; sourceTree = "<group>"; };
+ 97205AB11239291000B17380 /* ImageDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDocument.cpp; sourceTree = "<group>"; };
+ 97205AB21239291000B17380 /* ImageDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDocument.h; sourceTree = "<group>"; };
+ 97205AB31239291000B17380 /* MediaDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaDocument.cpp; sourceTree = "<group>"; };
+ 97205AB41239291000B17380 /* MediaDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaDocument.h; sourceTree = "<group>"; };
+ 97205AB91239292700B17380 /* PluginDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginDocument.cpp; sourceTree = "<group>"; };
+ 97205ABA1239292700B17380 /* PluginDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginDocument.h; sourceTree = "<group>"; };
9738899E116EA9DC00ADF313 /* DocumentWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentWriter.cpp; sourceTree = "<group>"; };
9738899F116EA9DC00ADF313 /* DocumentWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentWriter.h; sourceTree = "<group>"; };
973E325410883B7C005BC493 /* ResourceLoadNotifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadNotifier.cpp; sourceTree = "<group>"; };
@@ -8650,6 +8682,13 @@
977B3861122883E900B81FF8 /* HTMLViewSourceParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLViewSourceParser.h; path = parser/HTMLViewSourceParser.h; sourceTree = "<group>"; };
979F43D11075E44A0000F83B /* RedirectScheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RedirectScheduler.cpp; sourceTree = "<group>"; };
979F43D21075E44A0000F83B /* RedirectScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RedirectScheduler.h; sourceTree = "<group>"; };
+ 97BC84811236FD93000C6161 /* TextDocumentParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TextDocumentParser.cpp; path = parser/TextDocumentParser.cpp; sourceTree = "<group>"; };
+ 97BC84821236FD93000C6161 /* TextDocumentParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextDocumentParser.h; path = parser/TextDocumentParser.h; sourceTree = "<group>"; };
+ 97BC849A12370A4B000C6161 /* HTMLInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLInputStream.h; path = parser/HTMLInputStream.h; sourceTree = "<group>"; };
+ 97BC84A212370DC7000C6161 /* TextViewSourceParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TextViewSourceParser.cpp; path = parser/TextViewSourceParser.cpp; sourceTree = "<group>"; };
+ 97BC84A312370DC8000C6161 /* TextViewSourceParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TextViewSourceParser.h; path = parser/TextViewSourceParser.h; sourceTree = "<group>"; };
+ 97BC84B112371180000C6161 /* TextDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextDocument.cpp; sourceTree = "<group>"; };
+ 97BC84B212371180000C6161 /* TextDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextDocument.h; sourceTree = "<group>"; };
97C0784F1165D5BE003A32EF /* SuffixTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuffixTree.h; sourceTree = "<group>"; };
97C1F552122855CB00EDE616 /* HTMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLToken.h; path = parser/HTMLToken.h; sourceTree = "<group>"; };
97DCE1FF10807C750057D394 /* HistoryController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HistoryController.cpp; sourceTree = "<group>"; };
@@ -8707,6 +8746,15 @@
A5AFB34E115151A700B045CB /* StepRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StepRange.h; sourceTree = "<group>"; };
A5C974CF11485FF10066F2AB /* KeyEventCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyEventCocoa.h; path = cocoa/KeyEventCocoa.h; sourceTree = "<group>"; };
A5C974D011485FF10066F2AB /* KeyEventCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = KeyEventCocoa.mm; path = cocoa/KeyEventCocoa.mm; sourceTree = "<group>"; };
+ A622A8ED122C442A00A785B3 /* JSBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBinding.h; sourceTree = "<group>"; };
+ A622A8F0122C444500A785B3 /* JSBindingState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBindingState.cpp; sourceTree = "<group>"; };
+ A622A8F1122C444500A785B3 /* JSBindingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBindingState.h; sourceTree = "<group>"; };
+ A622A8F4122C44A600A785B3 /* BindingLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingLocation.h; path = generic/BindingLocation.h; sourceTree = "<group>"; };
+ A622A8F5122C44A600A785B3 /* BindingSecurity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingSecurity.h; path = generic/BindingSecurity.h; sourceTree = "<group>"; };
+ A622A8F6122C44A600A785B3 /* BindingSecurityBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BindingSecurityBase.cpp; path = generic/BindingSecurityBase.cpp; sourceTree = "<group>"; };
+ A622A8F7122C44A600A785B3 /* BindingSecurityBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingSecurityBase.h; path = generic/BindingSecurityBase.h; sourceTree = "<group>"; };
+ A622A8F8122C44A600A785B3 /* BindingUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingUtilities.h; path = generic/BindingUtilities.h; sourceTree = "<group>"; };
+ A622A8F9122C44A600A785B3 /* GenericBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GenericBinding.h; path = generic/GenericBinding.h; sourceTree = "<group>"; };
A718760D0B2A120100A16ECE /* DragActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragActions.h; sourceTree = "<group>"; };
A718788F0B2D04AC00A16ECE /* DragControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragControllerMac.mm; sourceTree = "<group>"; };
A71A70C911AFB02000989D6D /* HTMLMeterElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLMeterElement.idl; sourceTree = "<group>"; };
@@ -9344,8 +9392,6 @@
AB247A6A0AFD6383003FA5FD /* RenderSlider.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSlider.cpp; sourceTree = "<group>"; };
AB247A6B0AFD6383003FA5FD /* RenderSlider.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderSlider.h; sourceTree = "<group>"; };
AB31C91D10AE1B8E000C7B92 /* LineClampValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LineClampValue.h; path = style/LineClampValue.h; sourceTree = "<group>"; };
- AB40484B0E083FA8007D6920 /* MediaDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaDocument.cpp; sourceTree = "<group>"; };
- AB40484C0E083FA8007D6920 /* MediaDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaDocument.h; sourceTree = "<group>"; };
AB4261D70A2F6C9700BDD17D /* missingImage.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = missingImage.tiff; sourceTree = "<group>"; };
AB4CB4EA0B8BDA3D009F40B0 /* JSHTMLSelectElementCustom.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLSelectElementCustom.h; sourceTree = "<group>"; };
AB67D1A6097F3AE300F9392E /* RenderTextControl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTextControl.cpp; sourceTree = "<group>"; };
@@ -10631,7 +10677,8 @@
BC99812D0DBE807A008CE9EF /* DOMAbstractViewFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAbstractViewFrame.h; sourceTree = "<group>"; };
BC9ADD220CC4032600098C4C /* WebKitCSSTransformValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebKitCSSTransformValue.h; sourceTree = "<group>"; };
BC9ADD7F0CC4092200098C4C /* WebKitCSSTransformValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSTransformValue.cpp; sourceTree = "<group>"; };
- BC9BC64D0E7C4889008B9849 /* ScrollbarClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarClient.h; sourceTree = "<group>"; };
+ BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarClient.cpp; sourceTree = "<group>"; };
+ BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarClient.h; sourceTree = "<group>"; };
BCA169A00BFD55B40019CA76 /* JSHTMLTableCaptionElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLTableCaptionElement.cpp; sourceTree = "<group>"; };
BCA169A10BFD55B40019CA76 /* JSHTMLTableCaptionElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLTableCaptionElement.h; sourceTree = "<group>"; };
BCA2B0601050475F0043BD1C /* UserScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserScript.h; sourceTree = "<group>"; };
@@ -10669,8 +10716,8 @@
BCB16C0B0979C3BD00467741 /* CachedScript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedScript.h; sourceTree = "<group>"; };
BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedXSLStyleSheet.cpp; sourceTree = "<group>"; };
BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedXSLStyleSheet.h; sourceTree = "<group>"; };
- BCB16C100979C3BD00467741 /* DocLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DocLoader.cpp; sourceTree = "<group>"; };
- BCB16C110979C3BD00467741 /* DocLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DocLoader.h; sourceTree = "<group>"; };
+ BCB16C100979C3BD00467741 /* CachedResourceLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CachedResourceLoader.cpp; sourceTree = "<group>"; };
+ BCB16C110979C3BD00467741 /* CachedResourceLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CachedResourceLoader.h; sourceTree = "<group>"; };
BCB16C130979C3BD00467741 /* loader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = loader.cpp; sourceTree = "<group>"; };
BCB16C140979C3BD00467741 /* loader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = loader.h; sourceTree = "<group>"; };
BCB16C150979C3BD00467741 /* Request.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Request.cpp; sourceTree = "<group>"; };
@@ -10730,6 +10777,7 @@
BCD9C2BD0C17B69E005C90A2 /* JSNamedNodeMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSNamedNodeMap.h; sourceTree = "<group>"; };
BCD9C2BE0C17B69E005C90A2 /* JSNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSNodeList.cpp; sourceTree = "<group>"; };
BCD9C2BF0C17B69E005C90A2 /* JSNodeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSNodeList.h; sourceTree = "<group>"; };
+ BCDD454D1236C95C009A7985 /* ColumnInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColumnInfo.h; sourceTree = "<group>"; };
BCDF317911F8D683003C5BF8 /* UserTypingGestureIndicator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserTypingGestureIndicator.cpp; sourceTree = "<group>"; };
BCDF317A11F8D683003C5BF8 /* UserTypingGestureIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserTypingGestureIndicator.h; sourceTree = "<group>"; };
BCDFD48C0E305290009D10AD /* XMLHttpRequestUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLHttpRequestUpload.h; sourceTree = "<group>"; };
@@ -10950,6 +10998,8 @@
C5EBDD81105EDDEC0056816F /* StorageEventDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageEventDispatcher.h; sourceTree = "<group>"; };
C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModifySelectionListLevel.h; sourceTree = "<group>"; };
C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModifySelectionListLevel.cpp; sourceTree = "<group>"; };
+ CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollAnimator.cpp; sourceTree = "<group>"; };
+ CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimator.h; sourceTree = "<group>"; };
CD4E0AFA11F7BC27009D3811 /* fullscreen.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreen.css; sourceTree = "<group>"; };
CE02F0C311E83ADD00C6684A /* ScriptControllerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptControllerBase.h; sourceTree = "<group>"; };
CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
@@ -13864,6 +13914,8 @@
89878599122CA2A7003AABDA /* JSErrorCallback.h */,
BC00F0100E0A189500FD04E3 /* JSFile.cpp */,
BC00F0110E0A189500FD04E3 /* JSFile.h */,
+ 893C47B51238A099002B3D86 /* JSFileCallback.cpp */,
+ 893C47B61238A099002B3D86 /* JSFileCallback.h */,
8987859A122CA2A7003AABDA /* JSFileEntry.cpp */,
8987859B122CA2A7003AABDA /* JSFileEntry.h */,
2E3BC0C8117D3E0800B9409A /* JSFileError.cpp */,
@@ -13880,6 +13932,8 @@
8987859D122CA2A7003AABDA /* JSFileSystemCallback.h */,
46DA844B1224A0710060D006 /* JSFileWriter.cpp */,
46DA844C1224A0710060D006 /* JSFileWriter.h */,
+ 893C47B91238A0A9002B3D86 /* JSFileWriterCallback.cpp */,
+ 893C47BA1238A0A9002B3D86 /* JSFileWriterCallback.h */,
8987859E122CA2A7003AABDA /* JSFlags.cpp */,
8987859F122CA2A7003AABDA /* JSFlags.h */,
898785A0122CA2A7003AABDA /* JSMetadata.cpp */,
@@ -14061,6 +14115,8 @@
2ED609BA1145B07100C8684E /* DOMFormData.cpp */,
2ED609BB1145B07100C8684E /* DOMFormData.h */,
2E0888C3114883A900AF4265 /* DOMFormData.idl */,
+ 97205AAD123928CA00B17380 /* FTPDirectoryDocument.cpp */,
+ 97205AAE123928CA00B17380 /* FTPDirectoryDocument.h */,
A8136D370973A8E700D74463 /* FormDataList.cpp */,
A8136D360973A8E700D74463 /* FormDataList.h */,
BC97E239109144950010D361 /* HTMLAllCollection.cpp */,
@@ -14182,7 +14238,6 @@
A81369B1097374F500D74463 /* HTMLInputElement.cpp */,
A81369B0097374F500D74463 /* HTMLInputElement.h */,
A80E7E170A1A7CCB007FB8C5 /* HTMLInputElement.idl */,
- 9719AEFF11D09F2C00D45831 /* HTMLInputStream.h */,
A81369AF097374F500D74463 /* HTMLIsIndexElement.cpp */,
A81369AE097374F500D74463 /* HTMLIsIndexElement.h */,
1AE2AA850A1CDCCE00B42B25 /* HTMLIsIndexElement.idl */,
@@ -14314,14 +14369,22 @@
A77979130D6B9D0C003851B9 /* ImageData.cpp */,
A77979140D6B9D0C003851B9 /* ImageData.h */,
A77979150D6B9D0C003851B9 /* ImageData.idl */,
+ 97205AB11239291000B17380 /* ImageDocument.cpp */,
+ 97205AB21239291000B17380 /* ImageDocument.h */,
B0149E7B11A4B21500196A7B /* ImageResizerThread.cpp */,
B0149E7C11A4B21500196A7B /* ImageResizerThread.h */,
A456FA2411AD4A830020B420 /* LabelsNodeList.cpp */,
A456FA2511AD4A830020B420 /* LabelsNodeList.h */,
+ 97205AB31239291000B17380 /* MediaDocument.cpp */,
+ 97205AB41239291000B17380 /* MediaDocument.h */,
E446139B0CD6331000FADA75 /* MediaError.h */,
E446139C0CD6331000FADA75 /* MediaError.idl */,
+ 97205AB91239292700B17380 /* PluginDocument.cpp */,
+ 97205ABA1239292700B17380 /* PluginDocument.h */,
A5AFB34D115151A700B045CB /* StepRange.cpp */,
A5AFB34E115151A700B045CB /* StepRange.h */,
+ 97BC84B112371180000C6161 /* TextDocument.cpp */,
+ 97BC84B212371180000C6161 /* TextDocument.h */,
BCEF45E80E687767001C1287 /* TextMetrics.h */,
BCEF453F0E676AC1001C1287 /* TextMetrics.idl */,
E446139D0CD6331000FADA75 /* TimeRanges.cpp */,
@@ -14365,6 +14428,7 @@
89878547122CA064003AABDA /* ErrorCallback.h */,
976D6C61122B8A3D001FD1F7 /* File.cpp */,
976D6C62122B8A3D001FD1F7 /* File.h */,
+ 893C47A51238908B002B3D86 /* FileCallback.h */,
89878548122CA064003AABDA /* FileEntry.cpp */,
89878549122CA064003AABDA /* FileEntry.h */,
976D6C64122B8A3D001FD1F7 /* FileError.h */,
@@ -14385,6 +14449,7 @@
976D6C70122B8A3D001FD1F7 /* FileThreadTask.h */,
976D6C71122B8A3D001FD1F7 /* FileWriter.cpp */,
976D6C72122B8A3D001FD1F7 /* FileWriter.h */,
+ 893C47A61238908B002B3D86 /* FileWriterCallback.h */,
976D6C74122B8A3D001FD1F7 /* FileWriterClient.h */,
8987854D122CA064003AABDA /* Flags.h */,
8987854E122CA064003AABDA /* LocalFileSystem.cpp */,
@@ -14416,6 +14481,7 @@
977B3854122883E900B81FF8 /* HTMLEntityTable.h */,
977B3855122883E900B81FF8 /* HTMLFormattingElementList.cpp */,
977B3856122883E900B81FF8 /* HTMLFormattingElementList.h */,
+ 97BC849A12370A4B000C6161 /* HTMLInputStream.h */,
977B3857122883E900B81FF8 /* HTMLParserScheduler.cpp */,
977B3858122883E900B81FF8 /* HTMLParserScheduler.h */,
977B3859122883E900B81FF8 /* HTMLPreloadScanner.cpp */,
@@ -14430,6 +14496,10 @@
977B37221228721700B81FF8 /* HTMLTreeBuilder.h */,
977B3860122883E900B81FF8 /* HTMLViewSourceParser.cpp */,
977B3861122883E900B81FF8 /* HTMLViewSourceParser.h */,
+ 97BC84811236FD93000C6161 /* TextDocumentParser.cpp */,
+ 97BC84821236FD93000C6161 /* TextDocumentParser.h */,
+ 97BC84A212370DC7000C6161 /* TextViewSourceParser.cpp */,
+ 97BC84A312370DC8000C6161 /* TextViewSourceParser.h */,
);
name = parser;
sourceTree = "<group>";
@@ -14452,6 +14522,15 @@
name = cocoa;
sourceTree = "<group>";
};
+ A622A8EF122C444500A785B3 /* specialization */ = {
+ isa = PBXGroup;
+ children = (
+ A622A8F0122C444500A785B3 /* JSBindingState.cpp */,
+ A622A8F1122C444500A785B3 /* JSBindingState.h */,
+ );
+ path = specialization;
+ sourceTree = "<group>";
+ };
A75E8B7F0E1DE2B0007F2481 /* filters */ = {
isa = PBXGroup;
children = (
@@ -16069,6 +16148,12 @@
children = (
B5D31DF811CF610B009F22B4 /* ActiveDOMCallback.cpp */,
B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */,
+ A622A8F4122C44A600A785B3 /* BindingLocation.h */,
+ A622A8F5122C44A600A785B3 /* BindingSecurity.h */,
+ A622A8F6122C44A600A785B3 /* BindingSecurityBase.cpp */,
+ A622A8F7122C44A600A785B3 /* BindingSecurityBase.h */,
+ A622A8F8122C44A600A785B3 /* BindingUtilities.h */,
+ A622A8F9122C44A600A785B3 /* GenericBinding.h */,
);
name = generic;
sourceTree = "<group>";
@@ -16108,6 +16193,7 @@
BCCE58A71061E82F008FB35A /* Callback Objects */,
BCCE58B41061E925008FB35A /* Constructors */,
BC4EDEF70C08F414007EDD49 /* Custom */,
+ A622A8EF122C444500A785B3 /* specialization */,
14DFB33F0A7DF7630018F769 /* Derived Sources */,
BCD533630ED6848900887468 /* CachedScriptSourceProvider.h */,
93F8B3060A300FEA00F61AB8 /* CodeGeneratorJS.pm */,
@@ -16121,6 +16207,7 @@
C585A66111D4FAC5004C3E4B /* IDBBindingUtilities.h */,
1C81BA030E97348300266E07 /* JavaScriptCallFrame.cpp */,
1C81BA040E97348300266E07 /* JavaScriptCallFrame.h */,
+ A622A8ED122C442A00A785B3 /* JSBinding.h */,
BC53DAC411432FD9000D817E /* JSDebugWrapperSet.cpp */,
BC53DAC111432EEE000D817E /* JSDebugWrapperSet.h */,
93B70D4709EB0C7C009D8468 /* JSDOMBinding.cpp */,
@@ -16502,8 +16589,8 @@
E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */,
E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */,
E1C415D90F655D6F0092D2FB /* CrossOriginPreflightResultCache.h */,
- BCB16C100979C3BD00467741 /* DocLoader.cpp */,
- BCB16C110979C3BD00467741 /* DocLoader.h */,
+ BCB16C100979C3BD00467741 /* CachedResourceLoader.cpp */,
+ BCB16C110979C3BD00467741 /* CachedResourceLoader.h */,
93E227DB0AF589AD00D48324 /* DocumentLoader.cpp */,
656D371E0ADBA5DE00A4554D /* DocumentLoader.h */,
8A12E35C11FA33280025836A /* DocumentLoadTiming.h */,
@@ -16522,22 +16609,16 @@
D000EBA011BDAFD400C47726 /* FrameLoaderStateMachine.cpp */,
D000EBA111BDAFD400C47726 /* FrameLoaderStateMachine.h */,
93B77A370ADD792500EA4B81 /* FrameLoaderTypes.h */,
- 51E4ADB20C42B4CF0042BC55 /* FTPDirectoryDocument.cpp */,
- 51E4ADB30C42B4CF0042BC55 /* FTPDirectoryDocument.h */,
51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */,
51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */,
97DCE1FF10807C750057D394 /* HistoryController.cpp */,
97DCE20010807C750057D394 /* HistoryController.h */,
- 1A820D8F0A13EBA600AF843C /* ImageDocument.cpp */,
- 1A820D900A13EBA600AF843C /* ImageDocument.h */,
089582530E857A7E00F82C83 /* ImageLoader.cpp */,
089582540E857A7E00F82C83 /* ImageLoader.h */,
BCB16C130979C3BD00467741 /* loader.cpp */,
BCB16C140979C3BD00467741 /* loader.h */,
93E227DC0AF589AD00D48324 /* MainResourceLoader.cpp */,
656D37290ADBA5DE00A4554D /* MainResourceLoader.h */,
- AB40484B0E083FA8007D6920 /* MediaDocument.cpp */,
- AB40484C0E083FA8007D6920 /* MediaDocument.h */,
93CCF05F0AF6CA7600018E89 /* NavigationAction.cpp */,
93CCF0260AF6C52900018E89 /* NavigationAction.h */,
93E227DD0AF589AD00D48324 /* NetscapePlugInStreamLoader.cpp */,
@@ -16546,8 +16627,6 @@
D0FF2A5C11F8C45A007E74E0 /* PingLoader.h */,
377C4CDE1014E9F600B9AE42 /* PlaceholderDocument.cpp */,
377C4CDD1014E9F600B9AE42 /* PlaceholderDocument.h */,
- 1AC694C50A3B1676003F5049 /* PluginDocument.cpp */,
- 1AC694C60A3B1676003F5049 /* PluginDocument.h */,
97059973107D975200A50A7C /* PolicyCallback.cpp */,
97059974107D975200A50A7C /* PolicyCallback.h */,
97059975107D975200A50A7C /* PolicyChecker.cpp */,
@@ -16571,8 +16650,6 @@
1A3178920B20A81600316987 /* SubresourceLoaderClient.h */,
659A7D120B6DB4D9001155B3 /* SubstituteData.h */,
1A8F6B010DB53006001DB794 /* SubstituteResource.h */,
- 1A6937FF0A11100A00C127FE /* TextDocument.cpp */,
- 1A6938000A11100A00C127FE /* TextDocument.h */,
F523D27802DE43D7018635CA /* TextResourceDecoder.cpp */,
F523D27902DE43D7018635CA /* TextResourceDecoder.h */,
0B90561D0F257E930095FF6A /* ThreadableLoader.cpp */,
@@ -16717,8 +16794,11 @@
1C63A2460F71646600C09D5A /* RunLoopTimer.h */,
5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */,
5162C7F311F77EFB00612EFE /* SchemeRegistry.h */,
+ CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */,
+ CA3BF67D10D99BAE00E6CE53 /* ScrollAnimator.h */,
BC7B2AF80450824100A8000F /* Scrollbar.h */,
- BC9BC64D0E7C4889008B9849 /* ScrollbarClient.h */,
+ BC9BC64B0E7C4889008B9849 /* ScrollbarClient.cpp */,
+ BC9BC64C0E7C4889008B9849 /* ScrollbarClient.h */,
BC8B854A0E7C7F5600AB6984 /* ScrollbarTheme.h */,
BC1402880E83680800319717 /* ScrollbarThemeComposite.cpp */,
BC1402890E83680800319717 /* ScrollbarThemeComposite.h */,
@@ -17090,6 +17170,7 @@
BCE789851120E7A60060ECE5 /* BidiRun.h */,
BCEA4815097D93020094C9E4 /* break_lines.cpp */,
BCEA4816097D93020094C9E4 /* break_lines.h */,
+ BCDD454D1236C95C009A7985 /* ColumnInfo.h */,
9392F14F0AD1862300691BD4 /* CounterNode.cpp */,
9392F14B0AD1861B00691BD4 /* CounterNode.h */,
A8CFF6CA0A1561CD000A4234 /* EllipsisBox.cpp */,
@@ -17245,6 +17326,8 @@
08082372117987C100241DE8 /* RenderSVGResourceContainer.h */,
841FDC241178C9BE00F8AC9B /* RenderSVGResourceFilter.cpp */,
841FDC251178C9BE00F8AC9B /* RenderSVGResourceFilter.h */,
+ 19423B4E1234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.cpp */,
+ 19423B4F1234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.h */,
08C34AF11179C056002D7456 /* RenderSVGResourceGradient.cpp */,
08C34AF21179C057002D7456 /* RenderSVGResourceGradient.h */,
08C34AF31179C057002D7456 /* RenderSVGResourceLinearGradient.cpp */,
@@ -17952,7 +18035,7 @@
59A8F1D611A69513001AC34A /* DeviceOrientationController.h in Headers */,
59A85EA4119D68EC00DEF1EF /* DeviceOrientationEvent.h in Headers */,
B2F34FE60E82F81400F627CD /* DNS.h in Headers */,
- BCB16C2A0979C3BD00467741 /* DocLoader.h in Headers */,
+ BCB16C2A0979C3BD00467741 /* CachedResourceLoader.h in Headers */,
A8185F4009765766005826D9 /* Document.h in Headers */,
A8185F3D09765766005826D9 /* DocumentFragment.h in Headers */,
656D37360ADBA5DE00A4554D /* DocumentLoader.h in Headers */,
@@ -18800,7 +18883,6 @@
628D214E12131EF40055DCFC /* FrameNetworkingContext.h in Headers */,
65A21485097A3F5300B9050A /* FrameTree.h in Headers */,
65CBFEFA0974F607001DAC25 /* FrameView.h in Headers */,
- 51E4ADB70C42B4CF0042BC55 /* FTPDirectoryDocument.h in Headers */,
51C81B8A0C4422F70019ECE3 /* FTPDirectoryParser.h in Headers */,
935C477509AC4D8E00A6AAB4 /* GapRects.h in Headers */,
1432E8470C51493800B1500F /* GCController.h in Headers */,
@@ -18878,7 +18960,6 @@
A8EA7D2D0A19385500A8EF5F /* HTMLImageElement.h in Headers */,
A8EA7D2B0A19385500A8EF5F /* HTMLImageLoader.h in Headers */,
A81369CC097374F600D74463 /* HTMLInputElement.h in Headers */,
- 9719AF0011D09F2C00D45831 /* HTMLInputStream.h in Headers */,
93309DE6099E64920056E581 /* HTMLInterchange.h in Headers */,
A81369CA097374F600D74463 /* HTMLIsIndexElement.h in Headers */,
A81369E4097374F600D74463 /* HTMLKeygenElement.h in Headers */,
@@ -18970,7 +19051,6 @@
B27535700B053814002CE64F /* Image.h in Headers */,
B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */,
A779791A0D6B9D0C003851B9 /* ImageData.h in Headers */,
- 1A820D920A13EBA600AF843C /* ImageDocument.h in Headers */,
089582560E857A7E00F82C83 /* ImageLoader.h in Headers */,
BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */,
B0149E8011A4B21500196A7B /* ImageResizerThread.h in Headers */,
@@ -19503,7 +19583,6 @@
49E911C70EF86D47009D0CAF /* MatrixTransformOperation.h in Headers */,
931BCC611124DFCB00BE70DD /* MediaCanStartListener.h in Headers */,
ABFE7E130D32FAF60066F4D2 /* MediaControlElements.h in Headers */,
- AB40484E0E083FA8007D6920 /* MediaDocument.h in Headers */,
E44613AD0CD6331000FADA75 /* MediaError.h in Headers */,
4E1959220A39DABA00220FE5 /* MediaFeatureNames.h in Headers */,
A8EA800E0A19516E00A8EF5F /* MediaList.h in Headers */,
@@ -19605,7 +19684,6 @@
B2C3DA2B0D006C1D00EF6F26 /* PlatformString.h in Headers */,
935C476B09AC4D4F00A6AAB4 /* PlatformWheelEvent.h in Headers */,
A9C6E4F40D745E48006442E9 /* PluginData.h in Headers */,
- 1AC694C80A3B1676003F5049 /* PluginDocument.h in Headers */,
7693BAD4106C2DCA007B0823 /* PluginHalter.h in Headers */,
7693BAD5106C2DCA007B0823 /* PluginHalterClient.h in Headers */,
1ADA14110E1AE5D900023EE5 /* PluginMainThreadScheduler.h in Headers */,
@@ -19723,6 +19801,7 @@
84BDA16C11358D2A00DBF64C /* RenderSVGResourceClipper.h in Headers */,
08082373117987C100241DE8 /* RenderSVGResourceContainer.h in Headers */,
841FDC271178C9BE00F8AC9B /* RenderSVGResourceFilter.h in Headers */,
+ 19423B511234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.h in Headers */,
08C34AF61179C057002D7456 /* RenderSVGResourceGradient.h in Headers */,
08C34AF81179C057002D7456 /* RenderSVGResourceLinearGradient.h in Headers */,
8499A515115FB33000F566E3 /* RenderSVGResourceMarker.h in Headers */,
@@ -19809,6 +19888,7 @@
416F45F00ED7B311008215B6 /* ScriptString.h in Headers */,
934CC0E20ED39D6F00A658F2 /* ScriptValue.h in Headers */,
228C284510D82500009D0D0E /* ScriptWrappable.h in Headers */,
+ CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */,
93F199B808245E59001E9ABC /* Scrollbar.h in Headers */,
BC9BC64E0E7C4889008B9849 /* ScrollbarClient.h in Headers */,
BC8B854B0E7C7F5600AB6984 /* ScrollbarTheme.h in Headers */,
@@ -20146,7 +20226,6 @@
B2C3DA420D006C1D00EF6F26 /* TextCodecUTF16.h in Headers */,
AB014DE40E689A4300E10445 /* TextControlInnerElements.h in Headers */,
B2C3DA450D006C1D00EF6F26 /* TextDirection.h in Headers */,
- 1A6938020A11100A00C127FE /* TextDocument.h in Headers */,
B2C3DA470D006C1D00EF6F26 /* TextEncoding.h in Headers */,
C105DA640F3AA6B8001DD44F /* TextEncodingDetector.h in Headers */,
B2C3DA490D006C1D00EF6F26 /* TextEncodingRegistry.h in Headers */,
@@ -20432,6 +20511,26 @@
898785B9122CA2A7003AABDA /* JSMetadataCallback.h in Headers */,
898785F1122E1E87003AABDA /* JSFileException.h in Headers */,
898785F5122E1EAC003AABDA /* JSFileReaderSync.h in Headers */,
+ BCDD454E1236C95C009A7985 /* ColumnInfo.h in Headers */,
+ 97BC84841236FD93000C6161 /* TextDocumentParser.h in Headers */,
+ 97BC849B12370A4B000C6161 /* HTMLInputStream.h in Headers */,
+ 97BC84A512370DC8000C6161 /* TextViewSourceParser.h in Headers */,
+ 97BC84B412371180000C6161 /* TextDocument.h in Headers */,
+ 97205AB0123928CA00B17380 /* FTPDirectoryDocument.h in Headers */,
+ 97205AB61239291000B17380 /* ImageDocument.h in Headers */,
+ 97205AB81239291000B17380 /* MediaDocument.h in Headers */,
+ 97205ABC1239292700B17380 /* PluginDocument.h in Headers */,
+ A622A8EE122C442A00A785B3 /* JSBinding.h in Headers */,
+ A622A8F3122C444500A785B3 /* JSBindingState.h in Headers */,
+ A622A8FA122C44A600A785B3 /* BindingLocation.h in Headers */,
+ A622A8FB122C44A600A785B3 /* BindingSecurity.h in Headers */,
+ A622A8FD122C44A600A785B3 /* BindingSecurityBase.h in Headers */,
+ A622A8FE122C44A600A785B3 /* BindingUtilities.h in Headers */,
+ A622A8FF122C44A600A785B3 /* GenericBinding.h in Headers */,
+ 893C47A71238908B002B3D86 /* FileCallback.h in Headers */,
+ 893C47A81238908B002B3D86 /* FileWriterCallback.h in Headers */,
+ 893C47B81238A099002B3D86 /* JSFileCallback.h in Headers */,
+ 893C47BC1238A0A9002B3D86 /* JSFileWriterCallback.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -20942,7 +21041,7 @@
59A8F1D411A69508001AC34A /* DeviceOrientationController.cpp in Sources */,
59A85EA2119D68D900DEF1EF /* DeviceOrientationEvent.cpp in Sources */,
B2F34FE90E82F82700F627CD /* DNSCFNet.cpp in Sources */,
- BCB16C290979C3BD00467741 /* DocLoader.cpp in Sources */,
+ BCB16C290979C3BD00467741 /* CachedResourceLoader.cpp in Sources */,
A8185F3C09765766005826D9 /* Document.cpp in Sources */,
A8185F3F09765766005826D9 /* DocumentFragment.cpp in Sources */,
93E227E00AF589AD00D48324 /* DocumentLoader.cpp in Sources */,
@@ -21323,7 +21422,6 @@
65BF02450974819000C43196 /* FrameMac.mm in Sources */,
65A21484097A3F5300B9050A /* FrameTree.cpp in Sources */,
65CBFEF90974F607001DAC25 /* FrameView.cpp in Sources */,
- 51E4ADB60C42B4CF0042BC55 /* FTPDirectoryDocument.cpp in Sources */,
51C81B890C4422F70019ECE3 /* FTPDirectoryParser.cpp in Sources */,
1432E8490C51493F00B1500F /* GCController.cpp in Sources */,
BCE04C940DAFF902007A0F41 /* GeneratedImage.cpp in Sources */,
@@ -21475,7 +21573,6 @@
B2A10B940B3818D700099AA4 /* ImageBufferCG.cpp in Sources */,
B275355E0B053814002CE64F /* ImageCG.cpp in Sources */,
A77979190D6B9D0C003851B9 /* ImageData.cpp in Sources */,
- 1A820D910A13EBA600AF843C /* ImageDocument.cpp in Sources */,
089582550E857A7E00F82C83 /* ImageLoader.cpp in Sources */,
B275357B0B053814002CE64F /* ImageMac.mm in Sources */,
B0149E7F11A4B21500196A7B /* ImageResizerThread.cpp in Sources */,
@@ -22096,7 +22193,6 @@
49D5DC2B0F423A73008F20FD /* Matrix3DTransformOperation.cpp in Sources */,
49E911C60EF86D47009D0CAF /* MatrixTransformOperation.cpp in Sources */,
ABFE7E120D32FAF60066F4D2 /* MediaControlElements.cpp in Sources */,
- AB40484D0E083FA8007D6920 /* MediaDocument.cpp in Sources */,
4E1959210A39DABA00220FE5 /* MediaFeatureNames.cpp in Sources */,
A8EA80090A19516E00A8EF5F /* MediaList.cpp in Sources */,
E44613E30CD6819F00FADA75 /* MediaPlayer.cpp in Sources */,
@@ -22176,7 +22272,6 @@
BC94D1080C274F88006BC617 /* PlatformScreenMac.mm in Sources */,
1AD8F81C11CAB9E900E93E54 /* PlatformStrategies.cpp in Sources */,
A9C6E4F30D745E48006442E9 /* PluginData.cpp in Sources */,
- 1AC694C70A3B1676003F5049 /* PluginDocument.cpp in Sources */,
7693BAD3106C2DCA007B0823 /* PluginHalter.cpp in Sources */,
1ADA14100E1AE5D900023EE5 /* PluginMainThreadScheduler.cpp in Sources */,
76FF17E311235673001D61B5 /* PluginViewNone.cpp in Sources */,
@@ -22277,6 +22372,7 @@
84BDA16B11358D2A00DBF64C /* RenderSVGResourceClipper.cpp in Sources */,
086A400611F6D6B7002CEC53 /* RenderSVGResourceContainer.cpp in Sources */,
841FDC261178C9BE00F8AC9B /* RenderSVGResourceFilter.cpp in Sources */,
+ 19423B501234E86B00D1EE9E /* RenderSVGResourceFilterPrimitive.cpp in Sources */,
08C34AF51179C057002D7456 /* RenderSVGResourceGradient.cpp in Sources */,
08C34AF71179C057002D7456 /* RenderSVGResourceLinearGradient.cpp in Sources */,
8499A514115FB33000F566E3 /* RenderSVGResourceMarker.cpp in Sources */,
@@ -22357,7 +22453,9 @@
9F72305011184B4100AD0126 /* ScriptProfiler.cpp in Sources */,
4127D5370F8AAB1D00E424F5 /* ScriptState.cpp in Sources */,
934CC0E10ED39D6F00A658F2 /* ScriptValue.cpp in Sources */,
+ CA3BF67C10D99BAE00E6CE53 /* ScrollAnimator.cpp in Sources */,
BCAA90C30A7EBA60008B1229 /* Scrollbar.cpp in Sources */,
+ BC9BC64D0E7C4889008B9849 /* ScrollbarClient.cpp in Sources */,
BC14028A0E83680800319717 /* ScrollbarThemeComposite.cpp in Sources */,
BCEF869F0E844E9D00A85CD5 /* ScrollbarThemeMac.mm in Sources */,
5D925B670F64D4DD00B847F0 /* ScrollBehavior.cpp in Sources */,
@@ -22664,7 +22762,6 @@
B2C3DA3F0D006C1D00EF6F26 /* TextCodecUserDefined.cpp in Sources */,
B2C3DA410D006C1D00EF6F26 /* TextCodecUTF16.cpp in Sources */,
AB014DE30E689A4300E10445 /* TextControlInnerElements.cpp in Sources */,
- 1A6938010A11100A00C127FE /* TextDocument.cpp in Sources */,
B2C3DA460D006C1D00EF6F26 /* TextEncoding.cpp in Sources */,
C105DA620F3AA68F001DD44F /* TextEncodingDetectorICU.cpp in Sources */,
B2C3DA480D006C1D00EF6F26 /* TextEncodingRegistry.cpp in Sources */,
@@ -22895,6 +22992,17 @@
898785B8122CA2A7003AABDA /* JSMetadataCallback.cpp in Sources */,
898785F0122E1E87003AABDA /* JSFileException.cpp in Sources */,
898785F4122E1EAC003AABDA /* JSFileReaderSync.cpp in Sources */,
+ 97BC84831236FD93000C6161 /* TextDocumentParser.cpp in Sources */,
+ 97BC84A412370DC8000C6161 /* TextViewSourceParser.cpp in Sources */,
+ 97BC84B312371180000C6161 /* TextDocument.cpp in Sources */,
+ 97205AAF123928CA00B17380 /* FTPDirectoryDocument.cpp in Sources */,
+ 97205AB51239291000B17380 /* ImageDocument.cpp in Sources */,
+ 97205AB71239291000B17380 /* MediaDocument.cpp in Sources */,
+ 97205ABB1239292700B17380 /* PluginDocument.cpp in Sources */,
+ A622A8F2122C444500A785B3 /* JSBindingState.cpp in Sources */,
+ A622A8FC122C44A600A785B3 /* BindingSecurityBase.cpp in Sources */,
+ 893C47B71238A099002B3D86 /* JSFileCallback.cpp in Sources */,
+ 893C47BB1238A0A9002B3D86 /* JSFileWriterCallback.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
index d00574b..b22a51e 100644
--- a/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
+++ b/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
@@ -71,6 +71,10 @@ AccessibilityObjectInclusion AccessibilityObject::accessibilityPlatformIncludesO
if (role == StaticTextRole)
return IgnoreObject;
+ // Bullets/numbers for list items shouldn't be exposed as AtkObjects.
+ if (roleValue() == ListMarkerRole)
+ return IgnoreObject;
+
return DefaultBehavior;
}
diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
index b162346..90f363f 100644
--- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -34,6 +34,7 @@
#if HAVE(ACCESSIBILITY)
#include "AXObjectCache.h"
+#include "AccessibilityList.h"
#include "AccessibilityListBox.h"
#include "AccessibilityListBoxOption.h"
#include "AccessibilityRenderObject.h"
@@ -54,6 +55,7 @@
#include "InlineTextBox.h"
#include "IntRect.h"
#include "NotImplemented.h"
+#include "RenderListMarker.h"
#include "RenderText.h"
#include "TextEncoding.h"
#include <wtf/text/CString.h>
@@ -933,6 +935,16 @@ static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, g
ret = ret.substring(start, endOffset - startOffset);
}
+ // Prefix a item number/bullet if needed
+ if (coreObject->roleValue() == ListItemRole) {
+ RenderObject* objRenderer = static_cast<AccessibilityRenderObject*>(coreObject)->renderer();
+ RenderObject* markerRenderer = objRenderer ? objRenderer->firstChild() : 0;
+ if (markerRenderer && markerRenderer->isListMarker()) {
+ String markerTxt = toRenderListMarker(markerRenderer)->text();
+ ret = markerTxt.length() > 0 ? markerTxt + " " + ret : ret;
+ }
+ }
+
return g_strdup(ret.utf8().data());
}
diff --git a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
index 9595e25..859a799 100644
--- a/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
@@ -2352,37 +2352,37 @@ static RenderObject* rendererForView(NSView* view)
}
// dispatch
- if ([attribute isEqualToString: @"AXUIElementForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return m_object->accessibilityObjectForPosition(visiblePos)->wrapper();
}
- if ([attribute isEqualToString: @"AXTextMarkerRangeForUIElement"]) {
+ if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) {
VisiblePositionRange vpRange = uiElement.get()->visiblePositionRange();
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXLineForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXLineForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return [NSNumber numberWithUnsignedInt:m_object->lineForPosition(visiblePos)];
}
- if ([attribute isEqualToString: @"AXTextMarkerRangeForLine"]) {
+ if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) {
VisiblePositionRange vpRange = m_object->visiblePositionRangeForLine([number intValue]);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXStringForTextMarkerRange"]) {
+ if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) {
VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
return m_object->stringForVisiblePositionRange(visiblePosRange);
}
- if ([attribute isEqualToString: @"AXTextMarkerForPosition"]) {
+ if ([attribute isEqualToString:@"AXTextMarkerForPosition"]) {
IntPoint webCorePoint = IntPoint(point);
return pointSet ? textMarkerForVisiblePosition(m_object->visiblePositionForPoint(webCorePoint)) : nil;
}
- if ([attribute isEqualToString: @"AXBoundsForTextMarkerRange"]) {
+ if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
NSRect rect = m_object->boundsForVisiblePositionRange(visiblePosRange);
return [NSValue valueWithRect:rect];
@@ -2405,10 +2405,10 @@ static RenderObject* rendererForView(NSView* view)
return m_object->stringForVisiblePositionRange(VisiblePositionRange(start, end));
}
- if ([attribute isEqualToString: @"AXAttributedStringForTextMarkerRange"])
+ if ([attribute isEqualToString:@"AXAttributedStringForTextMarkerRange"])
return [self doAXAttributedStringForTextMarkerRange:textMarkerRange];
- if ([attribute isEqualToString: @"AXTextMarkerRangeForUnorderedTextMarkers"]) {
+ if ([attribute isEqualToString:@"AXTextMarkerRangeForUnorderedTextMarkers"]) {
if ([array count] < 2)
return nil;
@@ -2424,99 +2424,99 @@ static RenderObject* rendererForView(NSView* view)
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXNextTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->nextVisiblePosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXPreviousTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->previousVisiblePosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXLeftWordTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->positionOfLeftWord(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXRightWordTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->positionOfRightWord(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXLeftLineTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->leftLineVisiblePositionRange(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXRightLineTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->rightLineVisiblePositionRange(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXSentenceTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->sentenceForPosition(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXParagraphTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->paragraphForPosition(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXNextWordEndTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->nextWordEnd(visiblePos));
}
- if ([attribute isEqualToString: @"AXPreviousWordStartTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->previousWordStart(visiblePos));
}
- if ([attribute isEqualToString: @"AXNextLineEndTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->nextLineEndPosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXPreviousLineStartTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->previousLineStartPosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXNextSentenceEndTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->nextSentenceEndPosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXPreviousSentenceStartTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->previousSentenceStartPosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXNextParagraphEndTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->nextParagraphEndPosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXPreviousParagraphStartTextMarkerForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
return textMarkerForVisiblePosition(m_object->previousParagraphStartPosition(visiblePos));
}
- if ([attribute isEqualToString: @"AXStyleTextMarkerRangeForTextMarker"]) {
+ if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
VisiblePosition visiblePos = visiblePositionForTextMarker(textMarker);
VisiblePositionRange vpRange = m_object->styleRangeForPosition(visiblePos);
return (id)textMarkerRangeFromVisiblePositions(vpRange.start, vpRange.end);
}
- if ([attribute isEqualToString: @"AXLengthForTextMarkerRange"]) {
+ if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) {
VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
int length = m_object->lengthForVisiblePositionRange(visiblePosRange);
if (length < 0)
@@ -2524,6 +2524,17 @@ static RenderObject* rendererForView(NSView* view)
return [NSNumber numberWithInt:length];
}
+ // Used only by DumpRenderTree (so far).
+ if ([attribute isEqualToString:@"AXStartTextMarkerForTextMarkerRange"]) {
+ VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
+ return textMarkerForVisiblePosition(visiblePosRange.start);
+ }
+
+ if ([attribute isEqualToString:@"AXEndTextMarkerForTextMarkerRange"]) {
+ VisiblePositionRange visiblePosRange = [self visiblePositionRangeForTextMarkerRange:textMarkerRange];
+ return textMarkerForVisiblePosition(visiblePosRange.end);
+ }
+
if (m_object->isDataTable()) {
if ([attribute isEqualToString:NSAccessibilityCellForColumnAndRowParameterizedAttribute]) {
if (array == nil || [array count] != 2)
diff --git a/WebCore/bindings/generic/ActiveDOMCallback.cpp b/WebCore/bindings/generic/ActiveDOMCallback.cpp
index c42c93a..f62bf83 100644
--- a/WebCore/bindings/generic/ActiveDOMCallback.cpp
+++ b/WebCore/bindings/generic/ActiveDOMCallback.cpp
@@ -61,7 +61,6 @@ private:
OwnPtr<ActiveDOMObjectCallbackImpl> m_impl;
};
-// Instances of this class are accessed only on the context thread, so we don't need to use locks.
class ActiveDOMObjectCallbackImpl : public ActiveDOMObject {
public:
ActiveDOMObjectCallbackImpl(ScriptExecutionContext* context)
diff --git a/WebCore/bindings/generic/BindingDOMWindow.h b/WebCore/bindings/generic/BindingDOMWindow.h
index 0c450a5..96b8b9d 100644
--- a/WebCore/bindings/generic/BindingDOMWindow.h
+++ b/WebCore/bindings/generic/BindingDOMWindow.h
@@ -65,9 +65,6 @@ public:
const String& frameName,
const WindowFeatures& rawFeatures);
- // FIXME: There should be a place for generic binding utilities.
- static KURL completeURL(State<Binding>*, const String& relativeURL);
-
private:
// Horizontal and vertical offset, from the parent content area,
// around newly opened popups that don't specify a location.
@@ -268,18 +265,6 @@ WebCore::DOMWindow* BindingDOMWindow<Binding>::open(State<Binding>* state,
return frame->domWindow();
}
-template <class Binding>
-KURL BindingDOMWindow<Binding>::completeURL(State<Binding>* state,
- const String& relativeURL)
-{
- // For historical reasons, we need to complete the URL using the
- // dynamic frame.
- Frame* frame = state->getFirstFrame();
- if (!frame)
- return KURL();
- return frame->loader()->completeURL(relativeURL);
-}
-
} // namespace WebCore
#endif // BindingDOMWindow_h
diff --git a/WebCore/bindings/generic/BindingFrame.h b/WebCore/bindings/generic/BindingFrame.h
new file mode 100644
index 0000000..f1fdc79
--- /dev/null
+++ b/WebCore/bindings/generic/BindingFrame.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BindingFrame_h
+#define BindingFrame_h
+
+#include "Frame.h"
+#include "GenericBinding.h"
+
+namespace WebCore {
+
+template <class Binding>
+class BindingFrame {
+public:
+ static void navigateIfAllowed(State<Binding>*, Frame*, const KURL&, bool lockHistory, bool lockBackForwardList);
+};
+
+template <class Binding>
+void BindingFrame<Binding>::navigateIfAllowed(State<Binding>* state, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
+{
+ Frame* activeFrame = state->getActiveFrame();
+ if (!activeFrame)
+ return;
+ if (!protocolIsJavaScript(url) || state->allowsAccessFromFrame(frame))
+ frame->redirectScheduler()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, state->processingUserGesture());
+}
+
+} // namespace WebCore
+
+#endif // BindingFrame_h
diff --git a/WebCore/bindings/generic/BindingLocation.h b/WebCore/bindings/generic/BindingLocation.h
new file mode 100644
index 0000000..ca52814
--- /dev/null
+++ b/WebCore/bindings/generic/BindingLocation.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BindingLocation_h
+#define BindingLocation_h
+
+#include "BindingSecurity.h"
+#include "GenericBinding.h"
+#include "Location.h"
+
+namespace WebCore {
+
+template <class Binding>
+class BindingLocation {
+public:
+ static void replace(State<Binding>*, Location*, const String& url);
+};
+
+template <class Binding>
+void BindingLocation<Binding>::replace(State<Binding>* state, Location* location, const String& url)
+{
+ Frame* frame = location->frame();
+ if (!frame)
+ return;
+
+ KURL fullURL = completeURL(state, url);
+ if (fullURL.isNull())
+ return;
+
+ if (!BindingSecurity<Binding>::shouldAllowNavigation(state, frame))
+ return;
+
+ Binding::Frame::navigateIfAllowed(state, frame, fullURL, true, true);
+}
+
+} // namespace WebCore
+
+#endif // BindingLocation_h
diff --git a/WebCore/bindings/generic/GenericBinding.h b/WebCore/bindings/generic/GenericBinding.h
index d030b45..8bf1343 100644
--- a/WebCore/bindings/generic/GenericBinding.h
+++ b/WebCore/bindings/generic/GenericBinding.h
@@ -31,6 +31,9 @@
#ifndef GenericBinding_h
#define GenericBinding_h
+#include "Frame.h"
+#include "FrameLoader.h"
+
namespace WebCore {
// Used to instantiate binding templates for any methods shared among all
@@ -47,6 +50,17 @@ class State<GenericBinding> {
// Any methods shared across bindings can go here.
};
+template <class Binding>
+KURL completeURL(State<Binding>* state, const String& relativeURL)
+{
+ // For historical reasons, we need to complete the URL using the
+ // dynamic frame.
+ Frame* frame = state->getFirstFrame();
+ if (!frame)
+ return KURL();
+ return frame->loader()->completeURL(relativeURL);
+}
+
}
#endif // GenericBinding_h
diff --git a/WebCore/bindings/generic/RuntimeEnabledFeatures.h b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
index fb43f3f..91768b0 100644
--- a/WebCore/bindings/generic/RuntimeEnabledFeatures.h
+++ b/WebCore/bindings/generic/RuntimeEnabledFeatures.h
@@ -56,7 +56,19 @@ public:
static void setIndexedDBEnabled(bool isEnabled) { isIndexedDBEnabled = isEnabled; }
static bool indexedDBEnabled() { return isIndexedDBEnabled; }
- static bool iDBKeyRangeEnabled() { return indexedDBEnabled(); }
+ static bool iDBCursorEnabled() { return isIndexedDBEnabled; }
+ static bool iDBDatabaseEnabled() { return isIndexedDBEnabled; }
+ static bool iDBDatabaseErrorEnabled() { return isIndexedDBEnabled; }
+ static bool iDBDatabaseExceptionEnabled() { return isIndexedDBEnabled; }
+ static bool iDBErrorEventEnabled() { return isIndexedDBEnabled; }
+ static bool iDBEventEnabled() { return isIndexedDBEnabled; }
+ static bool iDBFactoryEnabled() { return isIndexedDBEnabled; }
+ static bool iDBIndexEnabled() { return isIndexedDBEnabled; }
+ static bool iDBKeyRangeEnabled() { return isIndexedDBEnabled; }
+ static bool iDBObjectStoreEnabled() { return isIndexedDBEnabled; }
+ static bool iDBRequestEnabled() { return isIndexedDBEnabled; }
+ static bool iDBSuccessEventEnabled() { return isIndexedDBEnabled; }
+ static bool iDBTransactionEnabled() { return isIndexedDBEnabled; }
#if ENABLE(VIDEO)
static bool audioEnabled();
diff --git a/WebCore/bindings/js/JSBinding.h b/WebCore/bindings/js/JSBinding.h
new file mode 100644
index 0000000..b42c9be
--- /dev/null
+++ b/WebCore/bindings/js/JSBinding.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSBinding_h
+#define JSBinding_h
+
+#include "BindingFrame.h"
+#include "BindingLocation.h"
+#include "BindingSecurity.h"
+
+namespace WebCore {
+
+// Instantiate binding template classes for JSC.
+class JSBinding {
+public:
+ typedef BindingFrame<JSBinding> Frame;
+ typedef BindingLocation<JSBinding> Location;
+};
+
+typedef BindingSecurity<JSBinding> JSBindingSecurity;
+
+} // namespace WebCore
+
+#endif // JSBinding_h
diff --git a/WebCore/bindings/js/JSBindingsAllInOne.cpp b/WebCore/bindings/js/JSBindingsAllInOne.cpp
index 922e449..6e1cc1e 100644
--- a/WebCore/bindings/js/JSBindingsAllInOne.cpp
+++ b/WebCore/bindings/js/JSBindingsAllInOne.cpp
@@ -30,6 +30,7 @@
#include "GCController.cpp"
#include "JSAttrCustom.cpp"
#include "JSAudioConstructor.cpp"
+#include "JSBindingState.cpp"
#include "JSCDATASectionCustom.cpp"
#include "JSCSSRuleCustom.cpp"
#include "JSCSSRuleListCustom.cpp"
diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp
index 96394eb..74c8131 100644
--- a/WebCore/bindings/js/JSDOMBinding.cpp
+++ b/WebCore/bindings/js/JSDOMBinding.cpp
@@ -38,11 +38,14 @@
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "HTMLScriptElement.h"
+#include "JSBinding.h"
+#include "JSBindingState.h"
#include "JSDOMCoreException.h"
#include "JSDOMWindowCustom.h"
#include "JSDebugWrapperSet.h"
#include "JSEventException.h"
#include "JSExceptionBase.h"
+#include "JSMainThreadExecState.h"
#include "JSNode.h"
#include "JSRangeException.h"
#include "JSXMLHttpRequestException.h"
@@ -639,8 +642,8 @@ bool allowsAccessFromFrame(ExecState* exec, Frame* frame, String& message)
bool shouldAllowNavigation(ExecState* exec, Frame* frame)
{
- Frame* lexicalFrame = toLexicalFrame(exec);
- return lexicalFrame && lexicalFrame->loader()->shouldAllowNavigation(frame);
+ JSBindingState state(exec);
+ return JSBindingSecurity::shouldAllowNavigation(&state, frame);
}
bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value)
@@ -671,26 +674,23 @@ void printErrorMessageForFrame(Frame* frame, const String& message)
Frame* toLexicalFrame(ExecState* exec)
{
- return asJSDOMWindow(exec->lexicalGlobalObject())->impl()->frame();
+ return JSBindingState(exec).getActiveFrame();
}
Frame* toDynamicFrame(ExecState* exec)
{
- return asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
+ return JSBindingState(exec).getFirstFrame();
}
bool processingUserGesture()
{
- return ScriptController::processingUserGesture();
+ return JSBindingState(JSMainThreadExecState::currentState()).processingUserGesture();
}
KURL completeURL(ExecState* exec, const String& relativeURL)
{
- // For historical reasons, we need to complete the URL using the dynamic frame.
- Frame* frame = toDynamicFrame(exec);
- if (!frame)
- return KURL();
- return frame->loader()->completeURL(relativeURL);
+ JSBindingState state(exec);
+ return completeURL(&state, relativeURL);
}
JSValue objectToStringFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
diff --git a/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp
index 23eda7e..8a1df5c 100644
--- a/WebCore/bindings/js/JSElementCustom.cpp
+++ b/WebCore/bindings/js/JSElementCustom.cpp
@@ -60,6 +60,8 @@ void JSElement::markChildren(MarkStack& markStack)
JSGlobalData& globalData = *Heap::heap(this)->globalData();
markDOMObjectWrapper(markStack, globalData, element->attributeMap());
+ markDOMObjectWrapper(markStack, globalData, element->optionalDataset());
+
if (element->isStyledElement())
markDOMObjectWrapper(markStack, globalData, static_cast<StyledElement*>(element)->inlineStyleDecl());
}
diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp
index 99166cd..09e7294 100644
--- a/WebCore/bindings/js/JSLocationCustom.cpp
+++ b/WebCore/bindings/js/JSLocationCustom.cpp
@@ -27,6 +27,8 @@
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "JSBinding.h"
+#include "JSBindingState.h"
#include "JSDOMBinding.h"
#include "JSDOMWindowCustom.h"
#include "KURL.h"
@@ -186,12 +188,8 @@ void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, J
static void navigateIfAllowed(ExecState* exec, Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
{
- Frame* lexicalFrame = toLexicalFrame(exec);
- if (!lexicalFrame)
- return;
-
- if (!protocolIsJavaScript(url) || allowsAccessFromFrame(exec, frame))
- frame->redirectScheduler()->scheduleLocationChange(url.string(), lexicalFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
+ JSBindingState state(exec);
+ JSBinding::Frame::navigateIfAllowed(&state, frame, url, lockHistory, lockBackForwardList);
}
void JSLocation::setHref(ExecState* exec, JSValue value)
@@ -303,18 +301,8 @@ void JSLocation::setHash(ExecState* exec, JSValue value)
JSValue JSLocation::replace(ExecState* exec)
{
- Frame* frame = impl()->frame();
- if (!frame)
- return jsUndefined();
-
- KURL url = completeURL(exec, ustringToString(exec->argument(0).toString(exec)));
- if (url.isNull())
- return jsUndefined();
-
- if (!shouldAllowNavigation(exec, frame))
- return jsUndefined();
-
- navigateIfAllowed(exec, frame, url, true, true);
+ JSBindingState state(exec);
+ JSBinding::Location::replace(&state, impl(), ustringToString(exec->argument(0).toString(exec)));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp
index ca18ec0..fcd3314 100644
--- a/WebCore/bindings/js/SerializedScriptValue.cpp
+++ b/WebCore/bindings/js/SerializedScriptValue.cpp
@@ -36,334 +36,560 @@
#include "JSFile.h"
#include "JSFileList.h"
#include "JSImageData.h"
+#include "SharedBuffer.h"
+#include <limits>
#include <JavaScriptCore/APICast.h>
#include <runtime/DateInstance.h>
#include <runtime/Error.h>
#include <runtime/ExceptionHelpers.h>
#include <runtime/JSLock.h>
#include <runtime/PropertyNameArray.h>
+#include <runtime/RegExp.h>
+#include <runtime/RegExpObject.h>
#include <wtf/ByteArray.h>
#include <wtf/HashTraits.h>
#include <wtf/Vector.h>
using namespace JSC;
+using namespace std;
+
+#if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN)
+#define ASSUME_LITTLE_ENDIAN 0
+#else
+#define ASSUME_LITTLE_ENDIAN 1
+#endif
namespace WebCore {
-class SerializedObject : public SharedSerializedData
-{
-public:
- typedef Vector<RefPtr<StringImpl> > PropertyNameList;
- typedef Vector<SerializedScriptValueData> ValueList;
+static const unsigned maximumFilterRecursion = 40000;
- void set(const Identifier& propertyName, const SerializedScriptValueData& value)
- {
- ASSERT(m_names.size() == m_values.size());
- m_names.append(identifierToString(propertyName).crossThreadString().impl());
- m_values.append(value);
- }
+enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
+ ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
+
+// These can't be reordered, and any new types must be added to the end of the list
+enum SerializationTag {
+ ArrayTag = 1,
+ ObjectTag = 2,
+ UndefinedTag = 3,
+ NullTag = 4,
+ IntTag = 5,
+ ZeroTag = 6,
+ OneTag = 7,
+ FalseTag = 8,
+ TrueTag = 9,
+ DoubleTag = 10,
+ DateTag = 11,
+ FileTag = 12,
+ FileListTag = 13,
+ ImageDataTag = 14,
+ BlobTag = 15,
+ StringTag = 16,
+ EmptyStringTag = 17,
+ RegExpTag = 18,
+ ErrorTag = 255
+};
- PropertyNameList& names() { return m_names; }
- ValueList& values() { return m_values; }
+static const unsigned int CurrentVersion = 1;
+static const unsigned int TerminatorTag = 0xFFFFFFFF;
+static const unsigned int StringPoolTag = 0xFFFFFFFE;
- static PassRefPtr<SerializedObject> create()
+/*
+ * Object serialization is performed according to the following grammar, all tags
+ * are recorded as a single uint8_t.
+ *
+ * IndexType (used for StringData's constant pool) is the sized unsigned integer type
+ * required to represent the maximum index in the constant pool.
+ *
+ * SerializedValue :- <CurrentVersion:uint32_t> Value
+ * Value :- Array | Object | Terminal
+ *
+ * Array :-
+ * ArrayTag <length:uint32_t>(<index:uint32_t><value:Value>)* TerminatorTag
+ *
+ * Object :-
+ * ObjectTag (<name:StringData><value:Value>)* TerminatorTag
+ *
+ * Terminal :-
+ * UndefinedTag
+ * | NullTag
+ * | IntTag <value:int32_t>
+ * | ZeroTag
+ * | OneTag
+ * | DoubleTag <value:double>
+ * | DateTag <value:double>
+ * | String
+ * | EmptyStringTag
+ * | File
+ * | FileList
+ * | ImageData
+ * | Blob
+ *
+ * String :-
+ * EmptyStringTag
+ * StringTag StringData
+ *
+ * StringData :-
+ * StringPoolTag <cpIndex:IndexType>
+ * (not (TerminatorTag | StringPoolTag))<length:uint32_t><characters:UChar{length}> // Added to constant pool when seen, string length 0xFFFFFFFF is disallowed
+ *
+ * File :-
+ * FileTag FileData
+ *
+ * FileData :-
+ * <path:StringData> <url:StringData> <type:StringData>
+ *
+ * FileList :-
+ * FileListTag <length:uint32_t>(<file:FileData>){length}
+ *
+ * ImageData :-
+ * ImageDataTag <width:uint32_t><height:uint32_t><length:uint32_t><data:uint8_t{length}>
+ *
+ * Blob :-
+ * BlobTag <url:StringData><type:StringData><size:long long>
+ *
+ * RegExp :-
+ * RegExpTag <pattern:StringData><flags:StringData>
+ */
+
+class CloneBase {
+protected:
+ CloneBase(ExecState* exec)
+ : m_exec(exec)
+ , m_failed(false)
+ , m_timeoutChecker(exec->globalData().timeoutChecker)
{
- return adoptRef(new SerializedObject);
}
- void clear()
+ bool shouldTerminate()
{
- m_names.clear();
- m_values.clear();
+ return m_exec->hadException();
}
-private:
- SerializedObject() { }
- PropertyNameList m_names;
- ValueList m_values;
-};
-
-class SerializedArray : public SharedSerializedData
-{
- typedef HashMap<unsigned, SerializedScriptValueData, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > SparseMap;
-public:
- void setIndex(unsigned index, const SerializedScriptValueData& value)
+ unsigned ticksUntilNextCheck()
{
- ASSERT(index < m_length);
- if (index == m_compactStorage.size())
- m_compactStorage.append(value);
- else
- m_sparseStorage.set(index, value);
+ return m_timeoutChecker.ticksUntilNextCheck();
}
- bool canDoFastRead(unsigned index) const
+ bool didTimeOut()
{
- ASSERT(index < m_length);
- return index < m_compactStorage.size();
+ return m_timeoutChecker.didTimeOut(m_exec);
}
- const SerializedScriptValueData& getIndex(unsigned index)
+ void throwStackOverflow()
{
- ASSERT(index < m_compactStorage.size());
- return m_compactStorage[index];
+ throwError(m_exec, createStackOverflowError(m_exec));
}
- SerializedScriptValueData getSparseIndex(unsigned index, bool& hasIndex)
+ void throwInterruptedException()
{
- ASSERT(index >= m_compactStorage.size());
- ASSERT(index < m_length);
- SparseMap::iterator iter = m_sparseStorage.find(index);
- if (iter == m_sparseStorage.end()) {
- hasIndex = false;
- return SerializedScriptValueData();
- }
- hasIndex = true;
- return iter->second;
+ throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData()));
}
- unsigned length() const
+ void fail()
{
- return m_length;
+ ASSERT_NOT_REACHED();
+ m_failed = true;
}
- static PassRefPtr<SerializedArray> create(unsigned length)
+ ExecState* m_exec;
+ bool m_failed;
+ TimeoutChecker m_timeoutChecker;
+ MarkedArgumentBuffer m_gcBuffer;
+};
+
+class CloneSerializer : CloneBase {
+public:
+ static bool serialize(ExecState* exec, JSValue value, Vector<uint8_t>& out)
{
- return adoptRef(new SerializedArray(length));
+ CloneSerializer serializer(exec, out);
+ return serializer.serialize(value);
}
- void clear()
+ static bool serialize(String s, Vector<uint8_t>& out)
{
- m_compactStorage.clear();
- m_sparseStorage.clear();
- m_length = 0;
+ writeLittleEndian(out, CurrentVersion);
+ if (s.isEmpty()) {
+ writeLittleEndian<uint8_t>(out, EmptyStringTag);
+ return true;
+ }
+ writeLittleEndian<uint8_t>(out, StringTag);
+ writeLittleEndian(out, s.length());
+ return writeLittleEndian(out, s.impl()->characters(), s.length());
}
+
private:
- SerializedArray(unsigned length)
- : m_length(length)
+ CloneSerializer(ExecState* exec, Vector<uint8_t>& out)
+ : CloneBase(exec)
+ , m_buffer(out)
+ , m_emptyIdentifier(exec, UString("", 0))
{
+ write(CurrentVersion);
}
- Vector<SerializedScriptValueData> m_compactStorage;
- SparseMap m_sparseStorage;
- unsigned m_length;
-};
+ bool serialize(JSValue in);
-class SerializedBlob : public SharedSerializedData {
-public:
- static PassRefPtr<SerializedBlob> create(const Blob* blob)
+ bool isArray(JSValue value)
{
- return adoptRef(new SerializedBlob(blob));
+ if (!value.isObject())
+ return false;
+ JSObject* object = asObject(value);
+ return isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::info);
}
- const KURL& url() const { return m_url; }
- const String& type() const { return m_type; }
- unsigned long long size() const { return m_size; }
+ bool startObject(JSObject* object)
+ {
+ // Cycle detection
+ if (!m_cycleDetector.add(object).second) {
+ throwError(m_exec, createTypeError(m_exec, "Cannot post cyclic structures."));
+ return false;
+ }
+ m_gcBuffer.append(object);
+ write(ObjectTag);
+ return true;
+ }
-private:
- SerializedBlob(const Blob* blob)
- : m_url(blob->url().copy())
- , m_type(blob->type().crossThreadString())
- , m_size(blob->size())
+
+ bool startArray(JSArray* array)
{
+ // Cycle detection
+ if (!m_cycleDetector.add(array).second) {
+ throwError(m_exec, createTypeError(m_exec, "Cannot post cyclic structures."));
+ return false;
+ }
+ m_gcBuffer.append(array);
+ unsigned length = array->length();
+ write(ArrayTag);
+ write(length);
+ return true;
}
- KURL m_url;
- String m_type;
- unsigned long long m_size;
-};
+ void endObject(JSObject* object)
+ {
+ write(TerminatorTag);
+ m_cycleDetector.remove(object);
+ m_gcBuffer.removeLast();
+ }
-class SerializedFile : public SharedSerializedData {
-public:
- static PassRefPtr<SerializedFile> create(const File* file)
+ JSValue getSparseIndex(JSArray* array, unsigned propertyName, bool& hasIndex)
{
- return adoptRef(new SerializedFile(file));
+ PropertySlot slot(array);
+ if (isJSArray(&m_exec->globalData(), array)) {
+ if (array->JSArray::getOwnPropertySlot(m_exec, propertyName, slot)) {
+ hasIndex = true;
+ return slot.getValue(m_exec, propertyName);
+ }
+ } else if (array->getOwnPropertySlot(m_exec, propertyName, slot)) {
+ hasIndex = true;
+ return slot.getValue(m_exec, propertyName);
+ }
+ hasIndex = false;
+ return jsNull();
}
- const String& path() const { return m_path; }
- const KURL& url() const { return m_url; }
- const String& type() const { return m_type; }
+ JSValue getProperty(JSObject* object, const Identifier& propertyName)
+ {
+ PropertySlot slot(object);
+ if (object->getOwnPropertySlot(m_exec, propertyName, slot))
+ return slot.getValue(m_exec, propertyName);
+ return JSValue();
+ }
-private:
- SerializedFile(const File* file)
- : m_path(file->path().crossThreadString())
- , m_url(file->url().copy())
- , m_type(file->type().crossThreadString())
+ void dumpImmediate(JSValue value)
{
+ if (value.isNull())
+ write(NullTag);
+ else if (value.isUndefined())
+ write(UndefinedTag);
+ else if (value.isNumber()) {
+ if (value.isInt32()) {
+ if (!value.asInt32())
+ write(ZeroTag);
+ else if (value.asInt32() == 1)
+ write(OneTag);
+ else {
+ write(IntTag);
+ write(static_cast<uint32_t>(value.asInt32()));
+ }
+ } else {
+ write(DoubleTag);
+ write(value.asDouble());
+ }
+ } else if (value.isBoolean()) {
+ if (value.isTrue())
+ write(TrueTag);
+ else
+ write(FalseTag);
+ }
}
- String m_path;
- KURL m_url;
- String m_type;
-};
+ void dumpString(UString str)
+ {
+ if (str.isEmpty())
+ write(EmptyStringTag);
+ else {
+ write(StringTag);
+ write(str);
+ }
+ }
-class SerializedFileList : public SharedSerializedData {
-public:
- struct FileData {
- String path;
- KURL url;
- String type;
- };
+ bool dumpIfTerminal(JSValue value)
+ {
+ if (!value.isCell()) {
+ dumpImmediate(value);
+ return true;
+ }
- static PassRefPtr<SerializedFileList> create(const FileList* list)
+ if (value.isString()) {
+ UString str = asString(value)->value(m_exec);
+ dumpString(str);
+ return true;
+ }
+
+ if (value.isNumber()) {
+ write(DoubleTag);
+ write(value.uncheckedGetNumber());
+ return true;
+ }
+
+ if (value.isObject() && asObject(value)->inherits(&DateInstance::info)) {
+ write(DateTag);
+ write(asDateInstance(value)->internalNumber());
+ return true;
+ }
+
+ if (isArray(value))
+ return false;
+
+ if (value.isObject()) {
+ JSObject* obj = asObject(value);
+ if (obj->inherits(&JSFile::s_info)) {
+ write(FileTag);
+ write(toFile(obj));
+ return true;
+ }
+ if (obj->inherits(&JSFileList::s_info)) {
+ FileList* list = toFileList(obj);
+ write(FileListTag);
+ unsigned length = list->length();
+ write(length);
+ for (unsigned i = 0; i < length; i++)
+ write(list->item(i));
+ return true;
+ }
+ if (obj->inherits(&JSBlob::s_info)) {
+ write(BlobTag);
+ Blob* blob = toBlob(obj);
+ write(blob->url());
+ write(blob->type());
+ write(blob->size());
+ return true;
+ }
+ if (obj->inherits(&JSImageData::s_info)) {
+ ImageData* data = toImageData(obj);
+ write(ImageDataTag);
+ write(data->width());
+ write(data->height());
+ write(data->data()->length());
+ write(data->data()->data()->data(), data->data()->length());
+ return true;
+ }
+ if (obj->inherits(&RegExpObject::info)) {
+ RegExpObject* regExp = asRegExpObject(obj);
+ char flags[3];
+ int flagCount = 0;
+ if (regExp->regExp()->global())
+ flags[flagCount++] = 'g';
+ if (regExp->regExp()->ignoreCase())
+ flags[flagCount++] = 'i';
+ if (regExp->regExp()->multiline())
+ flags[flagCount++] = 'm';
+ write(RegExpTag);
+ write(regExp->regExp()->pattern());
+ write(UString(flags, flagCount));
+ return true;
+ }
+
+ CallData unusedData;
+ if (getCallData(value, unusedData) == CallTypeNone)
+ return false;
+ }
+ // Any other types are expected to serialize as null.
+ write(NullTag);
+ return true;
+ }
+
+ void write(SerializationTag tag)
{
- return adoptRef(new SerializedFileList(list));
+ writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag));
}
- unsigned length() const { return m_files.size(); }
- const FileData& item(unsigned idx) { return m_files[idx]; }
+ void write(uint8_t c)
+ {
+ writeLittleEndian(m_buffer, c);
+ }
-private:
- SerializedFileList(const FileList* list)
+#if ASSUME_LITTLE_ENDIAN
+ template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
+ {
+ if (sizeof(T) == 1)
+ buffer.append(value);
+ else
+ buffer.append(reinterpret_cast<uint8_t*>(&value), sizeof(value));
+ }
+#else
+ template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
{
- unsigned length = list->length();
- m_files.reserveCapacity(length);
+ for (unsigned i = 0; i < sizeof(T); i++) {
+ buffer.append(value & 0xFF);
+ value >>= 8;
+ }
+ }
+#endif
+
+ template <typename T> static bool writeLittleEndian(Vector<uint8_t>& buffer, const T* values, uint32_t length)
+ {
+ if (length > numeric_limits<uint32_t>::max() / sizeof(T))
+ return false;
+
+#if ASSUME_LITTLE_ENDIAN
+ buffer.append(reinterpret_cast<const uint8_t*>(values), length * sizeof(T));
+#else
for (unsigned i = 0; i < length; i++) {
- File* file = list->item(i);
- FileData fileData;
- fileData.path = file->path().crossThreadString();
- fileData.url = file->url().copy();
- fileData.type = file->type().crossThreadString();
- m_files.append(fileData);
+ T value = values[i];
+ for (unsigned j = 0; j < sizeof(T); j++) {
+ buffer.append(static_cast<uint8_t>(value & 0xFF));
+ value >>= 8;
+ }
}
+#endif
+ return true;
}
- Vector<FileData> m_files;
-};
+ void write(uint32_t i)
+ {
+ writeLittleEndian(m_buffer, i);
+ }
-class SerializedImageData : public SharedSerializedData {
-public:
- static PassRefPtr<SerializedImageData> create(const ImageData* imageData)
+ void write(double d)
{
- return adoptRef(new SerializedImageData(imageData));
+ union {
+ double d;
+ int64_t i;
+ } u;
+ u.d = d;
+ writeLittleEndian(m_buffer, u.i);
+ }
+
+ void write(unsigned long long i)
+ {
+ writeLittleEndian(m_buffer, i);
}
- unsigned width() const { return m_width; }
- unsigned height() const { return m_height; }
- WTF::ByteArray* data() const { return m_storage.get(); }
-private:
- SerializedImageData(const ImageData* imageData)
- : m_width(imageData->width())
- , m_height(imageData->height())
+ void write(uint16_t ch)
{
- WTF::ByteArray* array = imageData->data()->data();
- m_storage = WTF::ByteArray::create(array->length());
- memcpy(m_storage->data(), array->data(), array->length());
+ writeLittleEndian(m_buffer, ch);
}
- unsigned m_width;
- unsigned m_height;
- RefPtr<WTF::ByteArray> m_storage;
-};
-SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedObject> data)
- : m_type(ObjectType)
- , m_sharedData(data)
-{
-}
-
-SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedArray> data)
- : m_type(ArrayType)
- , m_sharedData(data)
-{
-}
-
-SerializedScriptValueData::SerializedScriptValueData(const FileList* fileList)
- : m_type(FileListType)
- , m_sharedData(SerializedFileList::create(fileList))
-{
-}
+ void writeStringIndex(unsigned i)
+ {
+ if (m_constantPool.size() <= 0xFF)
+ write(static_cast<uint8_t>(i));
+ else if (m_constantPool.size() <= 0xFFFF)
+ write(static_cast<uint16_t>(i));
+ else
+ write(static_cast<uint32_t>(i));
+ }
-SerializedScriptValueData::SerializedScriptValueData(const ImageData* imageData)
- : m_type(ImageDataType)
- , m_sharedData(SerializedImageData::create(imageData))
-{
-}
+ void write(const Identifier& ident)
+ {
+ UString str = ident.ustring();
+ pair<ConstantPool::iterator, bool> iter = m_constantPool.add(str.impl(), m_constantPool.size());
+ if (!iter.second) {
+ write(StringPoolTag);
+ writeStringIndex(iter.first->second);
+ return;
+ }
-SerializedScriptValueData::SerializedScriptValueData(const Blob* blob)
- : m_type(BlobType)
- , m_sharedData(SerializedBlob::create(blob))
-{
-}
+ // This condition is unlikely to happen as they would imply an ~8gb
+ // string but we should guard against it anyway
+ if (str.length() >= StringPoolTag) {
+ fail();
+ return;
+ }
-SerializedScriptValueData::SerializedScriptValueData(const File* file)
- : m_type(FileType)
- , m_sharedData(SerializedFile::create(file))
-{
-}
+ // Guard against overflow
+ if (str.length() > (numeric_limits<uint32_t>::max() - sizeof(uint32_t)) / sizeof(UChar)) {
+ fail();
+ return;
+ }
-SerializedArray* SharedSerializedData::asArray()
-{
- return static_cast<SerializedArray*>(this);
-}
+ writeLittleEndian<uint32_t>(m_buffer, str.length());
+ if (!writeLittleEndian<uint16_t>(m_buffer, reinterpret_cast<const uint16_t*>(str.characters()), str.length()))
+ fail();
+ }
-SerializedObject* SharedSerializedData::asObject()
-{
- return static_cast<SerializedObject*>(this);
-}
+ void write(const UString& str)
+ {
+ if (str.isNull())
+ write(m_emptyIdentifier);
+ else
+ write(Identifier(m_exec, str));
+ }
-SerializedBlob* SharedSerializedData::asBlob()
-{
- return static_cast<SerializedBlob*>(this);
-}
+ void write(const String& str)
+ {
+ if (str.isEmpty())
+ write(m_emptyIdentifier);
+ else
+ write(Identifier(m_exec, str.impl()));
+ }
-SerializedFile* SharedSerializedData::asFile()
-{
- return static_cast<SerializedFile*>(this);
-}
+ void write(const File* file)
+ {
+ write(file->path());
+ write(file->url());
+ write(file->type());
+ }
-SerializedFileList* SharedSerializedData::asFileList()
-{
- return static_cast<SerializedFileList*>(this);
-}
+ void write(const uint8_t* data, unsigned length)
+ {
+ m_buffer.append(data, length);
+ }
-SerializedImageData* SharedSerializedData::asImageData()
-{
- return static_cast<SerializedImageData*>(this);
-}
+ Vector<uint8_t>& m_buffer;
+ HashSet<JSObject*> m_cycleDetector;
+ typedef HashMap<RefPtr<StringImpl>, uint32_t, IdentifierRepHash> ConstantPool;
+ ConstantPool m_constantPool;
+ Identifier m_emptyIdentifier;
+};
-static const unsigned maximumFilterRecursion = 40000;
-enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
- ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
-template <typename TreeWalker> typename TreeWalker::OutputType walk(TreeWalker& context, typename TreeWalker::InputType in)
+bool CloneSerializer::serialize(JSValue in)
{
- typedef typename TreeWalker::InputObject InputObject;
- typedef typename TreeWalker::InputArray InputArray;
- typedef typename TreeWalker::OutputObject OutputObject;
- typedef typename TreeWalker::OutputArray OutputArray;
- typedef typename TreeWalker::InputType InputType;
- typedef typename TreeWalker::OutputType OutputType;
- typedef typename TreeWalker::PropertyList PropertyList;
-
Vector<uint32_t, 16> indexStack;
Vector<uint32_t, 16> lengthStack;
- Vector<PropertyList, 16> propertyStack;
- Vector<InputObject, 16> inputObjectStack;
- Vector<InputArray, 16> inputArrayStack;
- Vector<OutputObject, 16> outputObjectStack;
- Vector<OutputArray, 16> outputArrayStack;
+ Vector<PropertyNameArray, 16> propertyStack;
+ Vector<JSObject*, 16> inputObjectStack;
+ Vector<JSArray*, 16> inputArrayStack;
Vector<WalkerState, 16> stateStack;
WalkerState state = StateUnknown;
- InputType inValue = in;
- OutputType outValue = context.null();
-
- unsigned tickCount = context.ticksUntilNextCheck();
+ JSValue inValue = in;
+ unsigned tickCount = ticksUntilNextCheck();
while (1) {
switch (state) {
arrayStartState:
case ArrayStartState: {
- ASSERT(context.isArray(inValue));
+ ASSERT(isArray(inValue));
if (inputObjectStack.size() + inputArrayStack.size() > maximumFilterRecursion) {
- context.throwStackOverflow();
- return context.null();
+ throwStackOverflow();
+ return false;
}
- InputArray inArray = context.asInputArray(inValue);
- unsigned length = context.length(inArray);
- OutputArray outArray = context.createOutputArray(length);
- if (!context.startArray(inArray, outArray))
- return context.null();
+ JSArray* inArray = asArray(inValue);
+ unsigned length = inArray->length();
+ if (!startArray(inArray))
+ return false;
inputArrayStack.append(inArray);
- outputArrayStack.append(outArray);
indexStack.append(0);
lengthStack.append(length);
// fallthrough
@@ -371,120 +597,114 @@ template <typename TreeWalker> typename TreeWalker::OutputType walk(TreeWalker&
arrayStartVisitMember:
case ArrayStartVisitMember: {
if (!--tickCount) {
- if (context.didTimeOut()) {
- context.throwInterruptedException();
- return context.null();
+ if (didTimeOut()) {
+ throwInterruptedException();
+ return false;
}
- tickCount = context.ticksUntilNextCheck();
+ tickCount = ticksUntilNextCheck();
}
- InputArray array = inputArrayStack.last();
+ JSArray* array = inputArrayStack.last();
uint32_t index = indexStack.last();
if (index == lengthStack.last()) {
- InputArray inArray = inputArrayStack.last();
- OutputArray outArray = outputArrayStack.last();
- context.endArray(inArray, outArray);
- outValue = outArray;
+ endObject(array);
inputArrayStack.removeLast();
- outputArrayStack.removeLast();
indexStack.removeLast();
lengthStack.removeLast();
break;
}
- if (context.canDoFastRead(array, index))
- inValue = context.getIndex(array, index);
+ if (array->canGetIndex(index))
+ inValue = array->getIndex(index);
else {
bool hasIndex = false;
- inValue = context.getSparseIndex(array, index, hasIndex);
+ inValue = getSparseIndex(array, index, hasIndex);
if (!hasIndex) {
indexStack.last()++;
goto arrayStartVisitMember;
}
}
- if (OutputType transformed = context.convertIfTerminal(inValue))
- outValue = transformed;
- else {
- stateStack.append(ArrayEndVisitMember);
- goto stateUnknown;
+ write(index);
+ if (dumpIfTerminal(inValue)) {
+ indexStack.last()++;
+ goto arrayStartVisitMember;
}
- // fallthrough
+ stateStack.append(ArrayEndVisitMember);
+ goto stateUnknown;
}
case ArrayEndVisitMember: {
- OutputArray outArray = outputArrayStack.last();
- context.putProperty(outArray, indexStack.last(), outValue);
indexStack.last()++;
goto arrayStartVisitMember;
}
objectStartState:
case ObjectStartState: {
- ASSERT(context.isObject(inValue));
+ ASSERT(inValue.isObject());
if (inputObjectStack.size() + inputArrayStack.size() > maximumFilterRecursion) {
- context.throwStackOverflow();
- return context.null();
+ throwStackOverflow();
+ return false;
}
- InputObject inObject = context.asInputObject(inValue);
- OutputObject outObject = context.createOutputObject();
- if (!context.startObject(inObject, outObject))
- return context.null();
+ JSObject* inObject = asObject(inValue);
+ if (!startObject(inObject))
+ return false;
inputObjectStack.append(inObject);
- outputObjectStack.append(outObject);
indexStack.append(0);
- context.getPropertyNames(inObject, propertyStack);
+ propertyStack.append(PropertyNameArray(m_exec));
+ inObject->getOwnPropertyNames(m_exec, propertyStack.last());
// fallthrough
}
objectStartVisitMember:
case ObjectStartVisitMember: {
if (!--tickCount) {
- if (context.didTimeOut()) {
- context.throwInterruptedException();
- return context.null();
+ if (didTimeOut()) {
+ throwInterruptedException();
+ return false;
}
- tickCount = context.ticksUntilNextCheck();
+ tickCount = ticksUntilNextCheck();
}
- InputObject object = inputObjectStack.last();
+ JSObject* object = inputObjectStack.last();
uint32_t index = indexStack.last();
- PropertyList& properties = propertyStack.last();
+ PropertyNameArray& properties = propertyStack.last();
if (index == properties.size()) {
- InputObject inObject = inputObjectStack.last();
- OutputObject outObject = outputObjectStack.last();
- context.endObject(inObject, outObject);
- outValue = outObject;
+ endObject(object);
inputObjectStack.removeLast();
- outputObjectStack.removeLast();
indexStack.removeLast();
propertyStack.removeLast();
break;
}
- inValue = context.getProperty(object, properties[index], index);
+ inValue = getProperty(object, properties[index]);
+ if (shouldTerminate())
+ return false;
+
+ if (!inValue) {
+ // Property was removed during serialisation
+ indexStack.last()++;
+ goto objectStartVisitMember;
+ }
+ write(properties[index]);
- if (context.shouldTerminate())
- return context.null();
+ if (shouldTerminate())
+ return false;
- if (OutputType transformed = context.convertIfTerminal(inValue))
- outValue = transformed;
- else {
+ if (!dumpIfTerminal(inValue)) {
stateStack.append(ObjectEndVisitMember);
goto stateUnknown;
}
// fallthrough
}
case ObjectEndVisitMember: {
- context.putProperty(outputObjectStack.last(), propertyStack.last()[indexStack.last()], outValue);
- if (context.shouldTerminate())
- return context.null();
+ if (shouldTerminate())
+ return false;
indexStack.last()++;
goto objectStartVisitMember;
}
stateUnknown:
case StateUnknown:
- if (OutputType transformed = context.convertIfTerminal(inValue)) {
- outValue = transformed;
+ if (dumpIfTerminal(inValue))
break;
- }
- if (context.isArray(inValue))
+
+ if (isArray(inValue))
goto arrayStartState;
goto objectStartState;
}
@@ -495,573 +715,579 @@ template <typename TreeWalker> typename TreeWalker::OutputType walk(TreeWalker&
stateStack.removeLast();
if (!--tickCount) {
- if (context.didTimeOut()) {
- context.throwInterruptedException();
- return context.null();
+ if (didTimeOut()) {
+ throwInterruptedException();
+ return false;
}
- tickCount = context.ticksUntilNextCheck();
+ tickCount = ticksUntilNextCheck();
}
}
- return outValue;
-}
-
-struct BaseWalker {
- BaseWalker(ExecState* exec)
- : m_exec(exec)
- , m_timeoutChecker(exec->globalData().timeoutChecker)
- {
- m_timeoutChecker.reset();
- }
- ExecState* m_exec;
- TimeoutChecker m_timeoutChecker;
- MarkedArgumentBuffer m_gcBuffer;
-
- bool shouldTerminate()
- {
- return m_exec->hadException();
- }
+ if (m_failed)
+ return false;
- unsigned ticksUntilNextCheck()
- {
- return m_timeoutChecker.ticksUntilNextCheck();
- }
+ return true;
+}
- bool didTimeOut()
- {
- return m_timeoutChecker.didTimeOut(m_exec);
+class CloneDeserializer : CloneBase {
+public:
+ static String deserializeString(const Vector<uint8_t>& buffer)
+ {
+ const uint8_t* ptr = buffer.begin();
+ const uint8_t* end = buffer.end();
+ uint32_t version;
+ if (!readLittleEndian(ptr, end, version) || version > CurrentVersion)
+ return String();
+ uint8_t tag;
+ if (!readLittleEndian(ptr, end, tag) || tag != StringTag)
+ return String();
+ uint32_t length;
+ if (!readLittleEndian(ptr, end, length) || length >= StringPoolTag)
+ return String();
+ UString str;
+ if (!readString(ptr, end, str, length))
+ return String();
+ return String(str.impl());
+ }
+
+ static JSValue deserialize(ExecState* exec, JSGlobalObject* globalObject, const Vector<uint8_t>& buffer)
+ {
+ if (!buffer.size())
+ return jsNull();
+ CloneDeserializer deserializer(exec, globalObject, buffer);
+ if (!deserializer.isValid()) {
+ deserializer.throwValidationError();
+ return JSValue();
+ }
+ return deserializer.deserialize();
}
- void throwStackOverflow()
+private:
+ CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, const Vector<uint8_t>& buffer)
+ : CloneBase(exec)
+ , m_globalObject(globalObject)
+ , m_isDOMGlobalObject(globalObject->inherits(&JSDOMGlobalObject::s_info))
+ , m_ptr(buffer.data())
+ , m_end(buffer.data() + buffer.size())
+ , m_version(0xFFFFFFFF)
{
- throwError(m_exec, createStackOverflowError(m_exec));
+ if (!read(m_version))
+ m_version = 0xFFFFFFFF;
}
- void throwInterruptedException()
- {
- throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData()));
- }
-};
+ JSValue deserialize();
-struct SerializingTreeWalker : public BaseWalker {
- typedef JSValue InputType;
- typedef JSArray* InputArray;
- typedef JSObject* InputObject;
- typedef SerializedScriptValueData OutputType;
- typedef RefPtr<SerializedArray> OutputArray;
- typedef RefPtr<SerializedObject> OutputObject;
- typedef PropertyNameArray PropertyList;
-
- SerializingTreeWalker(ExecState* exec)
- : BaseWalker(exec)
+ void throwValidationError()
{
+ throwError(m_exec, createTypeError(m_exec, "Unable to deserialize data."));
}
- OutputType null() { return SerializedScriptValueData(); }
+ bool isValid() const { return m_version <= CurrentVersion; }
- bool isArray(JSValue value)
+ template <typename T> bool readLittleEndian(T& value)
{
- if (!value.isObject())
+ if (m_failed || !readLittleEndian(m_ptr, m_end, value)) {
+ fail();
return false;
- JSObject* object = asObject(value);
- return isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::info);
+ }
+ return true;
}
-
- bool isObject(JSValue value)
+#if ASSUME_LITTLE_ENDIAN
+ template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value)
{
- return value.isObject();
- }
+ if (ptr > end - sizeof(value))
+ return false;
- JSArray* asInputArray(JSValue value)
- {
- return asArray(value);
+ if (sizeof(T) == 1)
+ value = *ptr++;
+ else {
+ value = *reinterpret_cast_ptr<const T*>(ptr);
+ ptr += sizeof(T);
+ }
+ return true;
}
-
- JSObject* asInputObject(JSValue value)
+#else
+ template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value)
{
- return asObject(value);
- }
+ if (ptr > end - sizeof(value))
+ return false;
- PassRefPtr<SerializedArray> createOutputArray(unsigned length)
- {
- return SerializedArray::create(length);
+ if (sizeof(T) == 1)
+ value = *ptr++;
+ else {
+ value = 0;
+ for (unsigned i = 0; i < sizeof(T); i++)
+ value += ((T)*ptr++) << (i * 8);
+ }
+ return true;
}
+#endif
- PassRefPtr<SerializedObject> createOutputObject()
+ bool read(uint32_t& i)
{
- return SerializedObject::create();
+ return readLittleEndian(i);
}
- uint32_t length(JSValue array)
+ bool read(int32_t& i)
{
- ASSERT(array.isObject());
- JSObject* object = asObject(array);
- return object->get(m_exec, m_exec->propertyNames().length).toUInt32(m_exec);
+ return readLittleEndian(*reinterpret_cast<uint32_t*>(&i));
}
- bool canDoFastRead(JSArray* array, unsigned index)
+ bool read(uint16_t& i)
{
- return isJSArray(&m_exec->globalData(), array) && array->canGetIndex(index);
+ return readLittleEndian(i);
}
- JSValue getIndex(JSArray* array, unsigned index)
+ bool read(uint8_t& i)
{
- return array->getIndex(index);
+ return readLittleEndian(i);
}
- JSValue getSparseIndex(JSObject* object, unsigned propertyName, bool& hasIndex)
+ bool read(double& d)
{
- PropertySlot slot(object);
- if (object->getOwnPropertySlot(m_exec, propertyName, slot)) {
- hasIndex = true;
- return slot.getValue(m_exec, propertyName);
- }
- hasIndex = false;
- return jsNull();
+ union {
+ double d;
+ uint64_t i64;
+ } u;
+ if (!readLittleEndian(u.i64))
+ return false;
+ d = u.d;
+ return true;
}
- JSValue getProperty(JSObject* object, const Identifier& propertyName, unsigned)
+ bool read(unsigned long long& i)
{
- PropertySlot slot(object);
- if (object->getOwnPropertySlot(m_exec, propertyName, slot))
- return slot.getValue(m_exec, propertyName);
- return jsNull();
+ return readLittleEndian(i);
}
- SerializedScriptValueData convertIfTerminal(JSValue value)
+ bool readStringIndex(uint32_t& i)
{
- if (!value.isCell())
- return SerializedScriptValueData(value);
-
- if (value.isString())
- return SerializedScriptValueData(ustringToString(asString(value)->value(m_exec)));
-
- if (value.isNumber())
- return SerializedScriptValueData(SerializedScriptValueData::NumberType, value.uncheckedGetNumber());
-
- if (value.isObject() && asObject(value)->inherits(&DateInstance::info))
- return SerializedScriptValueData(SerializedScriptValueData::DateType, asDateInstance(value)->internalNumber());
-
- if (isArray(value))
- return SerializedScriptValueData();
-
- if (value.isObject()) {
- JSObject* obj = asObject(value);
- if (obj->inherits(&JSFile::s_info))
- return SerializedScriptValueData(toFile(obj));
- if (obj->inherits(&JSBlob::s_info))
- return SerializedScriptValueData(toBlob(obj));
- if (obj->inherits(&JSFileList::s_info))
- return SerializedScriptValueData(toFileList(obj));
- if (obj->inherits(&JSImageData::s_info))
- return SerializedScriptValueData(toImageData(obj));
-
- CallData unusedData;
- if (getCallData(value, unusedData) == CallTypeNone)
- return SerializedScriptValueData();
+ if (m_constantPool.size() <= 0xFF) {
+ uint8_t i8;
+ if (!read(i8))
+ return false;
+ i = i8;
+ return true;
}
- // Any other types are expected to serialize as null.
- return SerializedScriptValueData(jsNull());
- }
-
- void getPropertyNames(JSObject* object, Vector<PropertyNameArray, 16>& propertyStack)
- {
- propertyStack.append(PropertyNameArray(m_exec));
- object->getOwnPropertyNames(m_exec, propertyStack.last());
- }
-
- void putProperty(RefPtr<SerializedArray> array, unsigned propertyName, const SerializedScriptValueData& value)
- {
- array->setIndex(propertyName, value);
+ if (m_constantPool.size() <= 0xFFFF) {
+ uint16_t i16;
+ if (!read(i16))
+ return false;
+ i = i16;
+ return true;
+ }
+ return read(i);
}
- void putProperty(RefPtr<SerializedObject> object, const Identifier& propertyName, const SerializedScriptValueData& value)
+ static bool readString(const uint8_t*& ptr, const uint8_t* end, UString& str, unsigned length)
{
- object->set(propertyName, value);
- }
+ if (length >= numeric_limits<int32_t>::max() / sizeof(UChar))
+ return false;
- bool startArray(JSArray* inArray, RefPtr<SerializedArray>)
- {
- // Cycle detection
- if (!m_cycleDetector.add(inArray).second) {
- throwError(m_exec, createTypeError(m_exec, "Cannot post cyclic structures."));
+ unsigned size = length * sizeof(UChar);
+ if ((end - ptr) < static_cast<int>(size))
return false;
+
+#if ASSUME_LITTLE_ENDIAN
+ str = UString(reinterpret_cast_ptr<const UChar*>(ptr), length);
+ ptr += length * sizeof(UChar);
+#else
+ Vector<UChar> buffer;
+ buffer.reserveCapacity(length);
+ for (unsigned i = 0; i < length; i++) {
+ uint16_t ch;
+ readLittleEndian(ptr, end, ch);
+ buffer.append(ch);
}
- m_gcBuffer.append(inArray);
+ str = UString::adopt(buffer);
+#endif
return true;
}
- void endArray(JSArray* inArray, RefPtr<SerializedArray>)
+ bool readStringData(Identifier& ident)
{
- m_cycleDetector.remove(inArray);
- m_gcBuffer.removeLast();
+ bool scratch;
+ return readStringData(ident, scratch);
}
- bool startObject(JSObject* inObject, RefPtr<SerializedObject>)
+ bool readStringData(Identifier& ident, bool& wasTerminator)
{
- // Cycle detection
- if (!m_cycleDetector.add(inObject).second) {
- throwError(m_exec, createTypeError(m_exec, "Cannot post cyclic structures."));
+ if (m_failed)
+ return false;
+ uint32_t length = 0;
+ if (!read(length))
return false;
+ if (length == TerminatorTag) {
+ wasTerminator = true;
+ return false;
+ }
+ if (length == StringPoolTag) {
+ unsigned index = 0;
+ if (!readStringIndex(index)) {
+ fail();
+ return false;
+ }
+ if (index >= m_constantPool.size()) {
+ fail();
+ return false;
+ }
+ ident = m_constantPool[index];
+ return true;
}
- m_gcBuffer.append(inObject);
+ UString str;
+ if (!readString(m_ptr, m_end, str, length)) {
+ fail();
+ return false;
+ }
+ ident = Identifier(m_exec, str);
+ m_constantPool.append(ident);
return true;
}
- void endObject(JSObject* inObject, RefPtr<SerializedObject>)
- {
- m_cycleDetector.remove(inObject);
- m_gcBuffer.removeLast();
- }
-
-private:
- HashSet<JSObject*> m_cycleDetector;
-};
-
-SerializedScriptValueData SerializedScriptValueData::serialize(ExecState* exec, JSValue inValue)
-{
- SerializingTreeWalker context(exec);
- return walk<SerializingTreeWalker>(context, inValue);
-}
-
-
-struct DeserializingTreeWalker : public BaseWalker {
- typedef SerializedScriptValueData InputType;
- typedef RefPtr<SerializedArray> InputArray;
- typedef RefPtr<SerializedObject> InputObject;
- typedef JSValue OutputType;
- typedef JSArray* OutputArray;
- typedef JSObject* OutputObject;
- typedef SerializedObject::PropertyNameList PropertyList;
-
- DeserializingTreeWalker(ExecState* exec, JSGlobalObject* globalObject, bool mustCopy)
- : BaseWalker(exec)
- , m_globalObject(globalObject)
- , m_isDOMGlobalObject(globalObject->inherits(&JSDOMGlobalObject::s_info))
- , m_mustCopy(mustCopy)
- {
- }
-
- OutputType null() { return jsNull(); }
-
- bool isArray(const SerializedScriptValueData& value)
- {
- return value.type() == SerializedScriptValueData::ArrayType;
- }
-
- bool isObject(const SerializedScriptValueData& value)
+ SerializationTag readTag()
{
- return value.type() == SerializedScriptValueData::ObjectType;
+ if (m_ptr >= m_end)
+ return ErrorTag;
+ return static_cast<SerializationTag>(*m_ptr++);
}
- SerializedArray* asInputArray(const SerializedScriptValueData& value)
+ void putProperty(JSArray* array, unsigned index, JSValue value)
{
- return value.asArray();
- }
-
- SerializedObject* asInputObject(const SerializedScriptValueData& value)
- {
- return value.asObject();
- }
-
- JSArray* createOutputArray(unsigned length)
- {
- JSArray* array = constructEmptyArray(m_exec, m_globalObject);
- array->setLength(length);
- return array;
- }
-
- JSObject* createOutputObject()
- {
- return constructEmptyObject(m_exec, m_globalObject);
- }
-
- uint32_t length(RefPtr<SerializedArray> array)
- {
- return array->length();
- }
-
- bool canDoFastRead(RefPtr<SerializedArray> array, unsigned index)
- {
- return array->canDoFastRead(index);
- }
-
- SerializedScriptValueData getIndex(RefPtr<SerializedArray> array, unsigned index)
- {
- return array->getIndex(index);
+ if (array->canSetIndex(index))
+ array->setIndex(index, value);
+ else
+ array->put(m_exec, index, value);
}
- SerializedScriptValueData getSparseIndex(RefPtr<SerializedArray> array, unsigned propertyName, bool& hasIndex)
+ void putProperty(JSObject* object, Identifier& property, JSValue value)
{
- return array->getSparseIndex(propertyName, hasIndex);
+ object->putDirect(property, value);
}
- SerializedScriptValueData getProperty(RefPtr<SerializedObject> object, const RefPtr<StringImpl>& propertyName, unsigned propertyIndex)
+ bool readFile(RefPtr<File>& file)
{
- ASSERT(object->names()[propertyIndex] == propertyName);
- UNUSED_PARAM(propertyName);
- return object->values()[propertyIndex];
+ Identifier path;
+ if (!readStringData(path))
+ return 0;
+ Identifier url;
+ if (!readStringData(url))
+ return 0;
+ Identifier type;
+ if (!readStringData(type))
+ return 0;
+ if (m_isDOMGlobalObject) {
+ ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject())->scriptExecutionContext();
+ file = File::create(scriptExecutionContext, String(path.ustring().impl()), KURL(KURL(), String(url.ustring().impl())), String(type.ustring().impl()));
+ }
+ return true;
}
- JSValue convertIfTerminal(SerializedScriptValueData& value)
+ JSValue readTerminal()
{
- switch (value.type()) {
- case SerializedScriptValueData::ArrayType:
- case SerializedScriptValueData::ObjectType:
+ SerializationTag tag = readTag();
+ switch (tag) {
+ case UndefinedTag:
+ return jsUndefined();
+ case NullTag:
+ return jsNull();
+ case IntTag: {
+ int32_t i;
+ if (!read(i))
return JSValue();
- case SerializedScriptValueData::StringType:
- return jsString(m_exec, value.asString().crossThreadString());
- case SerializedScriptValueData::ImmediateType:
- return value.asImmediate();
- case SerializedScriptValueData::NumberType:
- return jsNumber(m_exec, value.asDouble());
- case SerializedScriptValueData::DateType:
- return new (m_exec) DateInstance(m_exec, m_globalObject->dateStructure(), value.asDouble());
- case SerializedScriptValueData::BlobType: {
- if (!m_isDOMGlobalObject)
- return jsNull();
- SerializedBlob* serializedBlob = value.asBlob();
- ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject())->scriptExecutionContext();
- ASSERT(scriptExecutionContext);
- return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), Blob::create(scriptExecutionContext, serializedBlob->url(), serializedBlob->type(), serializedBlob->size()));
- }
- case SerializedScriptValueData::FileType: {
- if (!m_isDOMGlobalObject)
- return jsNull();
- SerializedFile* serializedFile = value.asFile();
- ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject())->scriptExecutionContext();
- ASSERT(scriptExecutionContext);
- return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), File::create(scriptExecutionContext, serializedFile->path(), serializedFile->url(), serializedFile->type()));
+ return jsNumber(m_exec, i);
+ }
+ case ZeroTag:
+ return jsNumber(m_exec, 0);
+ case OneTag:
+ return jsNumber(m_exec, 1);
+ case FalseTag:
+ return jsBoolean(false);
+ case TrueTag:
+ return jsBoolean(true);
+ case DoubleTag: {
+ double d;
+ if (!read(d))
+ return JSValue();
+ return jsNumber(m_exec, d);
+ }
+ case DateTag: {
+ double d;
+ if (!read(d))
+ return JSValue();
+ return new (m_exec) DateInstance(m_exec, m_globalObject->dateStructure(), d);
+ }
+ case FileTag: {
+ RefPtr<File> file;
+ if (!readFile(file))
+ return JSValue();
+ if (!m_isDOMGlobalObject)
+ return jsNull();
+ return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), file.get());
+ }
+ case FileListTag: {
+ unsigned length = 0;
+ if (!read(length))
+ return JSValue();
+ RefPtr<FileList> result = FileList::create();
+ for (unsigned i = 0; i < length; i++) {
+ RefPtr<File> file;
+ if (!readFile(file))
+ return JSValue();
+ if (m_isDOMGlobalObject)
+ result->append(file.get());
}
- case SerializedScriptValueData::FileListType: {
- if (!m_isDOMGlobalObject)
- return jsNull();
- RefPtr<FileList> result = FileList::create();
- SerializedFileList* serializedFileList = value.asFileList();
- unsigned length = serializedFileList->length();
- ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject())->scriptExecutionContext();
- ASSERT(scriptExecutionContext);
- for (unsigned i = 0; i < length; i++) {
- const SerializedFileList::FileData& fileData = serializedFileList->item(i);
- result->append(File::create(scriptExecutionContext, fileData.path, fileData.url, fileData.type));
- }
- return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get());
+ if (!m_isDOMGlobalObject)
+ return jsNull();
+ return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get());
+ }
+ case ImageDataTag: {
+ uint32_t width;
+ if (!read(width))
+ return JSValue();
+ uint32_t height;
+ if (!read(height))
+ return JSValue();
+ uint32_t length;
+ if (!read(length))
+ return JSValue();
+ if (m_end < ((uint8_t*)0) + length || m_ptr > m_end - length) {
+ fail();
+ return JSValue();
}
- case SerializedScriptValueData::ImageDataType: {
- if (!m_isDOMGlobalObject)
- return jsNull();
- SerializedImageData* serializedImageData = value.asImageData();
- RefPtr<ImageData> result = ImageData::create(serializedImageData->width(), serializedImageData->height());
- memcpy(result->data()->data()->data(), serializedImageData->data()->data(), serializedImageData->data()->length());
- return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get());
+ if (!m_isDOMGlobalObject) {
+ m_ptr += length;
+ return jsNull();
}
- case SerializedScriptValueData::EmptyType:
- ASSERT_NOT_REACHED();
+ RefPtr<ImageData> result = ImageData::create(width, height);
+ memcpy(result->data()->data()->data(), m_ptr, length);
+ m_ptr += length;
+ return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get());
+ }
+ case BlobTag: {
+ Identifier url;
+ if (!readStringData(url))
+ return JSValue();
+ Identifier type;
+ if (!readStringData(type))
+ return JSValue();
+ unsigned long long size = 0;
+ if (!read(size))
+ return JSValue();
+ if (!m_isDOMGlobalObject)
return jsNull();
+ ScriptExecutionContext* scriptExecutionContext = static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject())->scriptExecutionContext();
+ ASSERT(scriptExecutionContext);
+ return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), Blob::create(scriptExecutionContext, KURL(KURL(), url.ustring().impl()), String(type.ustring().impl()), size));
+ }
+ case StringTag: {
+ Identifier ident;
+ if (!readStringData(ident))
+ return JSValue();
+ return jsString(m_exec, ident.ustring());
+ }
+ case EmptyStringTag:
+ return jsEmptyString(&m_exec->globalData());
+ case RegExpTag: {
+ Identifier pattern;
+ if (!readStringData(pattern))
+ return JSValue();
+ Identifier flags;
+ if (!readStringData(flags))
+ return JSValue();
+ RefPtr<RegExp> regExp = RegExp::create(&m_exec->globalData(), pattern.ustring(), flags.ustring());
+ return new (m_exec) RegExpObject(m_exec->lexicalGlobalObject(), m_globalObject->regExpStructure(), regExp);
+ }
+ default:
+ m_ptr--; // Push the tag back
+ return JSValue();
}
- ASSERT_NOT_REACHED();
- return jsNull();
- }
-
- void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties)
- {
- properties.append(object->names());
- }
-
- void putProperty(JSArray* array, unsigned propertyName, JSValue value)
- {
- array->put(m_exec, propertyName, value);
- }
-
- void putProperty(JSObject* object, const RefPtr<StringImpl> propertyName, JSValue value)
- {
- object->putDirect(Identifier(m_exec, stringToUString(String(propertyName))), value);
- }
-
- bool startArray(RefPtr<SerializedArray>, JSArray* outArray)
- {
- m_gcBuffer.append(outArray);
- return true;
- }
- void endArray(RefPtr<SerializedArray>, JSArray*)
- {
- m_gcBuffer.removeLast();
- }
- bool startObject(RefPtr<SerializedObject>, JSObject* outObject)
- {
- m_gcBuffer.append(outObject);
- return true;
- }
- void endObject(RefPtr<SerializedObject>, JSObject*)
- {
- m_gcBuffer.removeLast();
}
-private:
- void* operator new(size_t);
JSGlobalObject* m_globalObject;
bool m_isDOMGlobalObject;
- bool m_mustCopy;
+ const uint8_t* m_ptr;
+ const uint8_t* m_end;
+ unsigned m_version;
+ Vector<Identifier> m_constantPool;
};
-JSValue SerializedScriptValueData::deserialize(ExecState* exec, JSGlobalObject* global, bool mustCopy) const
+JSValue CloneDeserializer::deserialize()
{
- DeserializingTreeWalker context(exec, global, mustCopy);
- return walk<DeserializingTreeWalker>(context, *this);
-}
-
-struct TeardownTreeWalker {
- typedef SerializedScriptValueData InputType;
- typedef RefPtr<SerializedArray> InputArray;
- typedef RefPtr<SerializedObject> InputObject;
- typedef bool OutputType;
- typedef bool OutputArray;
- typedef bool OutputObject;
- typedef SerializedObject::PropertyNameList PropertyList;
-
- bool shouldTerminate()
- {
- return false;
- }
-
- unsigned ticksUntilNextCheck()
- {
- return 0xFFFFFFFF;
- }
-
- bool didTimeOut()
- {
- return false;
- }
-
- void throwStackOverflow()
- {
- }
-
- void throwInterruptedException()
- {
- }
-
- bool null() { return false; }
-
- bool isArray(const SerializedScriptValueData& value)
- {
- return value.type() == SerializedScriptValueData::ArrayType;
- }
-
- bool isObject(const SerializedScriptValueData& value)
- {
- return value.type() == SerializedScriptValueData::ObjectType;
- }
-
- SerializedArray* asInputArray(const SerializedScriptValueData& value)
- {
- return value.asArray();
- }
-
- SerializedObject* asInputObject(const SerializedScriptValueData& value)
- {
- return value.asObject();
- }
-
- bool createOutputArray(unsigned)
- {
- return false;
- }
+ Vector<uint32_t, 16> indexStack;
+ Vector<Identifier, 16> propertyNameStack;
+ Vector<JSObject*, 16> outputObjectStack;
+ Vector<JSArray*, 16> outputArrayStack;
+ Vector<WalkerState, 16> stateStack;
+ WalkerState state = StateUnknown;
+ JSValue outValue;
- bool createOutputObject()
- {
- return false;
- }
+ unsigned tickCount = ticksUntilNextCheck();
+ while (1) {
+ switch (state) {
+ arrayStartState:
+ case ArrayStartState: {
+ uint32_t length;
+ if (!read(length)) {
+ fail();
+ goto error;
+ }
+ JSArray* outArray = constructEmptyArray(m_exec, m_globalObject);
+ outArray->setLength(length);
+ m_gcBuffer.append(outArray);
+ outputArrayStack.append(outArray);
+ // fallthrough
+ }
+ arrayStartVisitMember:
+ case ArrayStartVisitMember: {
+ if (!--tickCount) {
+ if (didTimeOut()) {
+ throwInterruptedException();
+ return JSValue();
+ }
+ tickCount = ticksUntilNextCheck();
+ }
- uint32_t length(RefPtr<SerializedArray> array)
- {
- return array->length();
- }
+ uint32_t index;
+ if (!read(index)) {
+ fail();
+ goto error;
+ }
+ if (index == TerminatorTag) {
+ JSArray* outArray = outputArrayStack.last();
+ m_gcBuffer.removeLast();
+ outValue = outArray;
+ outputArrayStack.removeLast();
+ break;
+ }
- bool canDoFastRead(RefPtr<SerializedArray> array, unsigned index)
- {
- return array->canDoFastRead(index);
- }
+ if (JSValue terminal = readTerminal()) {
+ putProperty(outputArrayStack.last(), index, terminal);
+ goto arrayStartVisitMember;
+ }
+ if (m_failed)
+ goto error;
+ indexStack.append(index);
+ stateStack.append(ArrayEndVisitMember);
+ goto stateUnknown;
+ }
+ case ArrayEndVisitMember: {
+ JSArray* outArray = outputArrayStack.last();
+ putProperty(outArray, indexStack.last(), outValue);
+ indexStack.removeLast();
+ goto arrayStartVisitMember;
+ }
+ objectStartState:
+ case ObjectStartState: {
+ if (outputObjectStack.size() + outputArrayStack.size() > maximumFilterRecursion) {
+ throwStackOverflow();
+ return JSValue();
+ }
+ JSObject* outObject = constructEmptyObject(m_exec, m_globalObject);
+ m_gcBuffer.append(outObject);
+ outputObjectStack.append(outObject);
+ // fallthrough
+ }
+ objectStartVisitMember:
+ case ObjectStartVisitMember: {
+ if (!--tickCount) {
+ if (didTimeOut()) {
+ throwInterruptedException();
+ return JSValue();
+ }
+ tickCount = ticksUntilNextCheck();
+ }
- SerializedScriptValueData getIndex(RefPtr<SerializedArray> array, unsigned index)
- {
- return array->getIndex(index);
- }
+ Identifier ident;
+ bool wasTerminator = false;
+ if (!readStringData(ident, wasTerminator)) {
+ if (!wasTerminator)
+ goto error;
+ JSObject* outObject = outputObjectStack.last();
+ m_gcBuffer.removeLast();
+ outValue = outObject;
+ outputObjectStack.removeLast();
+ break;
+ }
- SerializedScriptValueData getSparseIndex(RefPtr<SerializedArray> array, unsigned propertyName, bool& hasIndex)
- {
- return array->getSparseIndex(propertyName, hasIndex);
- }
+ if (JSValue terminal = readTerminal()) {
+ putProperty(outputObjectStack.last(), ident, terminal);
+ goto objectStartVisitMember;
+ }
+ stateStack.append(ObjectEndVisitMember);
+ propertyNameStack.append(ident);
+ goto stateUnknown;
+ }
+ case ObjectEndVisitMember: {
+ putProperty(outputObjectStack.last(), propertyNameStack.last(), outValue);
+ propertyNameStack.removeLast();
+ goto objectStartVisitMember;
+ }
+ stateUnknown:
+ case StateUnknown:
+ if (JSValue terminal = readTerminal()) {
+ outValue = terminal;
+ break;
+ }
+ SerializationTag tag = readTag();
+ if (tag == ArrayTag)
+ goto arrayStartState;
+ if (tag == ObjectTag)
+ goto objectStartState;
+ goto error;
+ }
+ if (stateStack.isEmpty())
+ break;
- SerializedScriptValueData getProperty(RefPtr<SerializedObject> object, const RefPtr<StringImpl>& propertyName, unsigned propertyIndex)
- {
- ASSERT(object->names()[propertyIndex] == propertyName);
- UNUSED_PARAM(propertyName);
- return object->values()[propertyIndex];
- }
+ state = stateStack.last();
+ stateStack.removeLast();
- bool convertIfTerminal(SerializedScriptValueData& value)
- {
- switch (value.type()) {
- case SerializedScriptValueData::ArrayType:
- case SerializedScriptValueData::ObjectType:
- return false;
- case SerializedScriptValueData::StringType:
- case SerializedScriptValueData::ImmediateType:
- case SerializedScriptValueData::NumberType:
- case SerializedScriptValueData::DateType:
- case SerializedScriptValueData::EmptyType:
- case SerializedScriptValueData::BlobType:
- case SerializedScriptValueData::FileType:
- case SerializedScriptValueData::FileListType:
- case SerializedScriptValueData::ImageDataType:
- return true;
+ if (!--tickCount) {
+ if (didTimeOut()) {
+ throwInterruptedException();
+ return JSValue();
+ }
+ tickCount = ticksUntilNextCheck();
}
- ASSERT_NOT_REACHED();
- return true;
}
+ ASSERT(outValue);
+ ASSERT(!m_failed);
+ return outValue;
+error:
+ fail();
+ throwValidationError();
+ return JSValue();
+}
- void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties)
- {
- properties.append(object->names());
- }
- void putProperty(bool, unsigned, bool)
- {
- }
- void putProperty(bool, const RefPtr<StringImpl>&, bool)
- {
- }
+SerializedScriptValue::~SerializedScriptValue()
+{
+}
- bool startArray(RefPtr<SerializedArray>, bool)
- {
- return true;
- }
- void endArray(RefPtr<SerializedArray> array, bool)
- {
- array->clear();
- }
- bool startObject(RefPtr<SerializedObject>, bool)
- {
- return true;
- }
- void endObject(RefPtr<SerializedObject> object, bool)
- {
- object->clear();
- }
-};
+SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer)
+{
+ m_data.swap(buffer);
+}
-void SerializedScriptValueData::tearDownSerializedData()
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState* exec, JSValue value)
{
- if (m_sharedData && m_sharedData->refCount() > 1)
- return;
- TeardownTreeWalker context;
- walk<TeardownTreeWalker>(context, *this);
+ Vector<uint8_t> buffer;
+ if (!CloneSerializer::serialize(exec, value, buffer))
+ return 0;
+ return adoptRef(new SerializedScriptValue(buffer));
}
-SerializedScriptValue::~SerializedScriptValue()
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create()
{
+ Vector<uint8_t> buffer;
+ return adoptRef(new SerializedScriptValue(buffer));
+}
+
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(String string)
+{
+ Vector<uint8_t> buffer;
+ if (!CloneSerializer::serialize(string, buffer))
+ return 0;
+ return adoptRef(new SerializedScriptValue(buffer));
}
PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue, JSValueRef* exception)
@@ -1076,14 +1302,18 @@ PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef ori
exec->clearException();
return 0;
}
-
+ ASSERT(serializedValue);
return serializedValue;
}
-SerializedScriptValue* SerializedScriptValue::nullValue()
+String SerializedScriptValue::toString()
+{
+ return CloneDeserializer::deserializeString(m_data);
+}
+
+JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject)
{
- DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, nullValue, (SerializedScriptValue::create()));
- return nullValue.get();
+ return CloneDeserializer::deserialize(exec, globalObject, m_data);
}
JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception)
@@ -1097,7 +1327,14 @@ JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, J
exec->clearException();
return 0;
}
+ ASSERT(value);
return toRef(exec, value);
}
+SerializedScriptValue* SerializedScriptValue::nullValue()
+{
+ DEFINE_STATIC_LOCAL(RefPtr<SerializedScriptValue>, emptyValue, (SerializedScriptValue::create()));
+ return emptyValue.get();
+}
+
}
diff --git a/WebCore/bindings/js/SerializedScriptValue.h b/WebCore/bindings/js/SerializedScriptValue.h
index 32ce418..94bc477 100644
--- a/WebCore/bindings/js/SerializedScriptValue.h
+++ b/WebCore/bindings/js/SerializedScriptValue.h
@@ -28,229 +28,40 @@
#define SerializedScriptValue_h
#include "ScriptValue.h"
+#include <wtf/Forward.h>
typedef const struct OpaqueJSContext* JSContextRef;
typedef const struct OpaqueJSValue* JSValueRef;
namespace WebCore {
- class Blob;
- class File;
- class FileList;
- class ImageData;
- class SerializedArray;
- class SerializedBlob;
- class SerializedFile;
- class SerializedFileList;
- class SerializedImageData;
- class SerializedObject;
- class SharedSerializedData : public RefCounted<SharedSerializedData> {
- public:
- virtual ~SharedSerializedData() { }
- SerializedArray* asArray();
- SerializedObject* asObject();
- SerializedBlob* asBlob();
- SerializedFile* asFile();
- SerializedFileList* asFileList();
- SerializedImageData* asImageData();
- };
+class SharedBuffer;
- class SerializedScriptValue;
+class SerializedScriptValue : public RefCounted<SerializedScriptValue> {
+public:
+ static PassRefPtr<SerializedScriptValue> create(JSC::ExecState* exec, JSC::JSValue value);
+ static PassRefPtr<SerializedScriptValue> create(JSContextRef, JSValueRef value, JSValueRef* exception);
+ static PassRefPtr<SerializedScriptValue> create(String string);
+ static PassRefPtr<SerializedScriptValue> adopt(Vector<uint8_t>& buffer)
+ {
+ return adoptRef(new SerializedScriptValue(buffer));
+ }
- class SerializedScriptValueData {
- public:
- enum SerializedType {
- EmptyType,
- DateType,
- NumberType,
- ImmediateType,
- ObjectType,
- ArrayType,
- StringType,
- BlobType,
- FileType,
- FileListType,
- ImageDataType
- };
+ static PassRefPtr<SerializedScriptValue> create();
+ static SerializedScriptValue* nullValue();
- SerializedType type() const { return m_type; }
- static SerializedScriptValueData serialize(JSC::ExecState*, JSC::JSValue);
- JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, bool mustCopy) const;
+ JSC::JSValue deserialize(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject);
+ String toString();
+ JSValueRef deserialize(JSContextRef, JSValueRef* exception);
+ const Vector<uint8_t>& data() { return m_data; }
- ~SerializedScriptValueData()
- {
- if (m_sharedData)
- tearDownSerializedData();
- }
+ ~SerializedScriptValue();
- SerializedScriptValueData()
- : m_type(EmptyType)
- {
- }
+private:
+ SerializedScriptValue(Vector<unsigned char>&);
+ Vector<unsigned char> m_data;
+};
- explicit SerializedScriptValueData(const String& string)
- : m_type(StringType)
- , m_string(string.crossThreadString()) // FIXME: Should be able to just share the StringImpl
- {
- }
-
- explicit SerializedScriptValueData(const Blob*);
- explicit SerializedScriptValueData(const File*);
- explicit SerializedScriptValueData(const FileList*);
- explicit SerializedScriptValueData(const ImageData*);
-
- explicit SerializedScriptValueData(JSC::JSValue value)
- : m_type(ImmediateType)
- {
- ASSERT(!value.isCell());
- m_data.m_immediate = JSC::JSValue::encode(value);
- }
-
- SerializedScriptValueData(SerializedType type, double value)
- : m_type(type)
- {
- m_data.m_double = value;
- }
-
- SerializedScriptValueData(RefPtr<SerializedObject>);
- SerializedScriptValueData(RefPtr<SerializedArray>);
-
- JSC::JSValue asImmediate() const
- {
- ASSERT(m_type == ImmediateType);
- return JSC::JSValue::decode(m_data.m_immediate);
- }
-
- double asDouble() const
- {
- ASSERT(m_type == NumberType || m_type == DateType);
- return m_data.m_double;
- }
-
- String asString() const
- {
- ASSERT(m_type == StringType);
- return m_string;
- }
-
- SerializedObject* asObject() const
- {
- ASSERT(m_type == ObjectType);
- ASSERT(m_sharedData);
- return m_sharedData->asObject();
- }
-
- SerializedArray* asArray() const
- {
- ASSERT(m_type == ArrayType);
- ASSERT(m_sharedData);
- return m_sharedData->asArray();
- }
-
- SerializedBlob* asBlob() const
- {
- ASSERT(m_type == BlobType);
- ASSERT(m_sharedData);
- return m_sharedData->asBlob();
- }
-
- SerializedFile* asFile() const
- {
- ASSERT(m_type == FileType);
- ASSERT(m_sharedData);
- return m_sharedData->asFile();
- }
-
- SerializedFileList* asFileList() const
- {
- ASSERT(m_type == FileListType);
- ASSERT(m_sharedData);
- return m_sharedData->asFileList();
- }
-
- SerializedImageData* asImageData() const
- {
- ASSERT(m_type == ImageDataType);
- ASSERT(m_sharedData);
- return m_sharedData->asImageData();
- }
-
- operator bool() const { return m_type != EmptyType; }
-
- SerializedScriptValueData release()
- {
- SerializedScriptValueData result = *this;
- *this = SerializedScriptValueData();
- return result;
- }
-
- private:
- void tearDownSerializedData();
- SerializedType m_type;
- RefPtr<SharedSerializedData> m_sharedData;
- String m_string;
- union {
- double m_double;
- JSC::EncodedJSValue m_immediate;
- } m_data;
- };
-
- class SerializedScriptValue : public RefCounted<SerializedScriptValue> {
- public:
- static PassRefPtr<SerializedScriptValue> create(JSC::ExecState* exec, JSC::JSValue value)
- {
- return adoptRef(new SerializedScriptValue(SerializedScriptValueData::serialize(exec, value)));
- }
-
- static PassRefPtr<SerializedScriptValue> create(JSContextRef, JSValueRef value, JSValueRef* exception);
-
- static PassRefPtr<SerializedScriptValue> create(String string)
- {
- return adoptRef(new SerializedScriptValue(SerializedScriptValueData(string)));
- }
-
- static PassRefPtr<SerializedScriptValue> create()
- {
- return adoptRef(new SerializedScriptValue(SerializedScriptValueData()));
- }
-
- static SerializedScriptValue* nullValue();
-
- PassRefPtr<SerializedScriptValue> release()
- {
- PassRefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_value));
- m_value = SerializedScriptValueData();
- result->m_mustCopy = true;
- return result;
- }
-
- String toString()
- {
- if (m_value.type() != SerializedScriptValueData::StringType)
- return "";
- return m_value.asString();
- }
-
- JSC::JSValue deserialize(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject)
- {
- if (!m_value)
- return JSC::jsNull();
- return m_value.deserialize(exec, globalObject, m_mustCopy);
- }
-
- JSValueRef deserialize(JSContextRef, JSValueRef* exception);
- ~SerializedScriptValue();
-
- private:
- SerializedScriptValue(SerializedScriptValueData value)
- : m_value(value)
- , m_mustCopy(false)
- {
- }
-
- SerializedScriptValueData m_value;
- bool m_mustCopy;
- };
}
#endif // SerializedScriptValue_h
diff --git a/WebCore/bindings/js/specialization/JSBindingState.cpp b/WebCore/bindings/js/specialization/JSBindingState.cpp
new file mode 100644
index 0000000..950b813
--- /dev/null
+++ b/WebCore/bindings/js/specialization/JSBindingState.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 "JSBindingState.h"
+
+#include "DOMWindow.h"
+#include "JSDOMWindow.h"
+#include "JSDOMWindowCustom.h"
+#include "ScriptController.h"
+
+namespace WebCore {
+
+class Frame;
+
+Frame* State<JSBinding>::getActiveFrame()
+{
+ return asJSDOMWindow(m_exec->lexicalGlobalObject())->impl()->frame();
+}
+
+Frame* State<JSBinding>::getFirstFrame()
+{
+ return asJSDOMWindow(m_exec->dynamicGlobalObject())->impl()->frame();
+}
+
+bool State<JSBinding>::processingUserGesture()
+{
+ return ScriptController::processingUserGesture();
+}
+
+bool State<JSBinding>::allowsAccessFromFrame(Frame* frame)
+{
+ return WebCore::allowsAccessFromFrame(m_exec, frame);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/specialization/JSBindingState.h b/WebCore/bindings/js/specialization/JSBindingState.h
new file mode 100644
index 0000000..6640140
--- /dev/null
+++ b/WebCore/bindings/js/specialization/JSBindingState.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 JSBindingState_h
+#define JSBindingState_h
+
+#include "GenericBinding.h"
+#include "JSBinding.h"
+
+namespace JSC {
+
+class ExecState;
+
+} // namespace JSC
+
+namespace WebCore {
+
+class Frame;
+
+template <>
+class State<JSBinding> : public State<GenericBinding> {
+public:
+ explicit State(JSC::ExecState* exec)
+ : m_exec(exec)
+ {
+ }
+
+ virtual ~State()
+ {
+ }
+
+ Frame* getActiveFrame();
+ Frame* getFirstFrame();
+
+ bool processingUserGesture();
+
+ // FIXME: This should be shared in BindingSecurity
+ bool allowsAccessFromFrame(Frame*);
+
+private:
+ JSC::ExecState* m_exec;
+};
+
+typedef State<JSBinding> JSBindingState;
+
+} // namespace WebCore
+
+#endif // JSBindingState_h
diff --git a/WebCore/bindings/objc/DOMHTML.mm b/WebCore/bindings/objc/DOMHTML.mm
index db64afe..884a5b0 100644
--- a/WebCore/bindings/objc/DOMHTML.mm
+++ b/WebCore/bindings/objc/DOMHTML.mm
@@ -166,6 +166,15 @@
select->setSelectedIndexByUser(index, true, true);
}
+- (void)_activateItemAtIndex:(int)index allowMultipleSelection:(BOOL)allowMultipleSelection
+{
+ // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590>
+ // If this is a <select multiple> the allowMultipleSelection flag will allow setting multiple
+ // selections without clearing the other selections.
+ if (WebCore::HTMLSelectElement* select = core(self))
+ select->setSelectedIndexByUser(index, true, true, allowMultipleSelection);
+}
+
@end
@implementation DOMHTMLInputElement (FormPromptAdditions)
diff --git a/WebCore/bindings/objc/DOMPrivate.h b/WebCore/bindings/objc/DOMPrivate.h
index b8e4460..ab3b563 100644
--- a/WebCore/bindings/objc/DOMPrivate.h
+++ b/WebCore/bindings/objc/DOMPrivate.h
@@ -69,7 +69,7 @@
// All the methods in this category are used by Safari forms autofill and should not be used for any other purpose.
// Each one should eventually be replaced by public DOM API, and when that happens Safari will switch to implementations
// using that public API, and these will be deleted.
-@interface DOMHTMLInputElement (FormsAutoFillTransition)
+@interface DOMHTMLInputElement (FormAutoFillTransition)
- (BOOL)_isAutofilled;
- (BOOL)_isTextField;
- (NSRect)_rectOnScreen; // bounding box of the text field, in screen coordinates
@@ -92,6 +92,7 @@
// They are stopgap measures until we finish transitioning form controls to not use NSView. Each one should become
// replaceable by public DOM API, and when that happens Safari will switch to implementations using that public API,
// and these will be deleted.
-@interface DOMHTMLSelectElement (FormsAutoFillTransition)
+@interface DOMHTMLSelectElement (FormAutoFillTransition)
- (void)_activateItemAtIndex:(int)index;
+- (void)_activateItemAtIndex:(int)index allowMultipleSelection:(BOOL)allowMultipleSelection;
@end
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 84e3919..1a114a4 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -1134,9 +1134,14 @@ sub GenerateParametersCheckExpression
# For DOMString, Null, Undefined and any Object are accepted too, as
# these are acceptable values for a DOMString argument (any Object can
# be converted to a string via .toString).
- push(@andExpression, "(${value}.isNull() || ${value}.isUndefined() || ${value}.isString() || ${value}.isObject())") if $codeGenerator->IsStringType($type);
- push(@andExpression, "(${value}.isNull() || (${value}.isObject() && asObject(${value})->inherits(&JS${type}::s_info)))") unless IsNativeType($type);
-
+ if ($codeGenerator->IsStringType($type)) {
+ push(@andExpression, "(${value}.isNull() || ${value}.isUndefined() || ${value}.isString() || ${value}.isObject())");
+ } elsif ($parameter->extendedAttributes->{"Callback"}) {
+ # For Callbacks only checks if the value is null or object.
+ push(@andExpression, "(${value}.isNull() || ${value}.isObject())");
+ } elsif (!IsNativeType($type)) {
+ push(@andExpression, "(${value}.isNull() || (${value}.isObject() && asObject(${value})->inherits(&JS${type}::s_info)))");
+ }
$parameterIndex++;
}
my $res = join(" && ", @andExpression);
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 718bcb2..06bce04 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -233,6 +233,7 @@ sub GenerateHeader
$headerIncludes{"$podType.h"} = 1 if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
$headerIncludes{"wtf/text/StringHash.h"} = 1;
$headerIncludes{"WrapperTypeInfo.h"} = 1;
+ $headerIncludes{"V8DOMWrapper.h"} = 1;
my $headerClassInclude = GetHeaderClassInclude($implClassName);
$headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
@@ -253,15 +254,23 @@ sub GenerateHeader
if ($podType) {
$nativeType = "V8SVGPODTypeWrapper<${nativeType} >";
}
+
+ my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
+ my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
+ my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
+
push(@headerContent, <<END);
public:
static bool HasInstance(v8::Handle<v8::Value> value);
static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
- static ${nativeType}* toNative(v8::Handle<v8::Object>);
- static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+ static ${nativeType}* toNative(v8::Handle<v8::Object> object)
+ {
+ return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
+ }
+ inline static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
static void derefObject(void*);
static WrapperTypeInfo info;
END
@@ -336,13 +345,72 @@ END
}
push(@headerContent, <<END);
+private:
+ static v8::Handle<v8::Object> wrapSlow(${nativeType}*);
};
+END
+
+ push(@headerContent, <<END);
+
+v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+{
+END
+ if ($domMapFunction) {
+ push(@headerContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
+ my $getWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getWrapper(impl)" : "${domMapFunction}.get(impl)";
+ push(@headerContent, <<END);
+ v8::Handle<v8::Object> wrapper = ${getWrapper};
+ if (!wrapper.IsEmpty())
+ return wrapper;
+END
+ push(@headerContent, " }\n") if IsDOMNodeType($interfaceName);
+ }
+ push(@headerContent, <<END);
+ return ${className}::wrapSlow(impl);
+}
+END
+
+ if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
+ push(@headerContent, <<END);
+
+inline v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectParameter})
+{
+ if (!impl)
+ return v8::Null();
+ return ${className}::wrap(impl${forceNewObjectCall});
+}
+END
+ } elsif ($interfaceName ne 'Node') {
+ push(@headerContent, <<END);
+
v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
END
+ } else {
+ push(@headerContent, <<END);
+
+v8::Handle<v8::Value> toV8Slow(Node*, bool);
+
+inline v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject = false)
+{
+ if (!impl)
+ return v8::Null();
+ if (!forceNewObject) {
+ v8::Handle<v8::Value> wrapper = V8DOMWrapper::getWrapper(impl);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+ }
+ return toV8Slow(impl, forceNewObject);
+}
+END
+ }
+
if (IsRefPtrType($implClassName)) {
push(@headerContent, <<END);
-v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
+inline v8::Handle<v8::Value> toV8(PassRefPtr< ${nativeType} > impl${forceNewObjectParameter})
+{
+ return toV8(impl.get()${forceNewObjectCall});
+}
END
}
@@ -1031,8 +1099,14 @@ sub GenerateParametersCheckExpression
# For DOMString, Null, Undefined and any Object are accepted too, as
# these are acceptable values for a DOMString argument (any Object can
# be converted to a string via .toString).
- push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())") if $codeGenerator->IsStringType($type);
- push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))") if IsWrapperType($type);
+ if ($codeGenerator->IsStringType($type)) {
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsUndefined() || ${value}->IsString() || ${value}->IsObject())");
+ } elsif ($parameter->extendedAttributes->{"Callback"}) {
+ # For Callbacks only checks if the value is null or object.
+ push(@andExpression, "(${value}->IsNull() || ${value}->IsObject())");
+ } elsif (IsWrapperType($type)) {
+ push(@andExpression, "(${value}->IsNull() || V8${type}::HasInstance($value))");
+ }
$parameterIndex++;
}
@@ -1144,7 +1218,7 @@ END
push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* impWrapper = V8SVGPODTypeWrapper<$nativeClassName>::toNative(args.Holder());\n");
push(@implContentDecls, " $nativeClassName impInstance = *impWrapper;\n");
push(@implContentDecls, " $nativeClassName* imp = &impInstance;\n");
- } else {
+ } elsif (!$function->signature->extendedAttributes->{"ClassMethod"}) {
push(@implContentDecls, <<END);
${implClassName}* imp = V8${implClassName}::toNative(args.Holder());
END
@@ -1765,6 +1839,9 @@ sub GenerateImplementation
if ($attrExt->{"V8OnInstance"}) {
next;
}
+ if ($attrExt->{"ClassMethod"}) {
+ next;
+ }
if ($attrExt->{"EnabledAtRuntime"} || RequiresCustomSignature($function) || $attrExt->{"V8DoNotCheckSignature"}) {
next;
}
@@ -1950,6 +2027,9 @@ END
if ($attrExt->{"V8OnInstance"}) {
$template = "instance";
}
+ if ($attrExt->{"ClassMethod"}) {
+ $template = "desc";
+ }
my $conditional = "";
if ($attrExt->{"EnabledAtRuntime"}) {
@@ -1985,7 +2065,7 @@ END
}
my $signature = "defaultSignature";
- if ($attrExt->{"V8DoNotCheckSignature"}) {
+ if ($attrExt->{"V8DoNotCheckSignature"} || $attrExt->{"ClassMethod"}) {
$signature = "v8::Local<v8::Signature>()";
}
@@ -2074,11 +2154,6 @@ v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\
return ${className}Cache;
}
-${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
-{
- return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
-}
-
bool ${className}::HasInstance(v8::Handle<v8::Value> value)
{
return GetRawTemplate()->HasInstance(value);
@@ -2347,7 +2422,7 @@ sub GenerateToV8Converters
push(@implContent, <<END);
-v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+v8::Handle<v8::Object> ${className}::wrapSlow(${nativeType}* impl)
{
v8::Handle<v8::Object> wrapper;
V8Proxy* proxy = 0;
@@ -2357,26 +2432,17 @@ END
push(@implContent, <<END);
if (impl->document()) {
proxy = V8Proxy::retrieve(impl->document()->frame());
- if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
- proxy->windowShell()->initContextIfNeeded();
+ if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) {
+ if (proxy->windowShell()->initContextIfNeeded()) {
+ // initContextIfNeeded may have created a wrapper for the object, retry from the start.
+ return ${className}::wrap(impl);
+ }
+ }
}
END
}
- if ($domMapFunction) {
- push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
- if (IsNodeSubType($dataNode)) {
- push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
- } else {
- push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
- }
- push(@implContent, <<END);
- if (!wrapper.IsEmpty())
- return wrapper;
-END
- push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
- }
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
@@ -2433,28 +2499,6 @@ END
return wrapper;
}
END
-
- if (IsRefPtrType($interfaceName)) {
- push(@implContent, <<END);
-
-v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
-{
- return toV8(impl.get()${forceNewObjectCall});
-}
-END
- }
-
- if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
- push(@implContent, <<END);
-
-v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
-{
- if (!impl)
- return v8::Null();
- return ${className}::wrap(impl${forceNewObjectCall});
-}
-END
- }
}
sub HasCustomToV8Implementation {
@@ -2558,6 +2602,10 @@ sub GenerateFunctionCallString()
$functionString = "result.${name}(";
}
+ if ($function->signature->extendedAttributes->{"ClassMethod"}) {
+ $functionString = "${implClassName}::${name}(";
+ }
+
my $returnsListItemPodType = 0;
# SVG lists functions that return POD types require special handling
if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
diff --git a/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.cpp b/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.cpp
index 882e633..9cceb3c 100644
--- a/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.cpp
+++ b/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.cpp
@@ -749,6 +749,22 @@ void WebDOMTestObj::methodWithNonOptionalArgAndTwoOptionalArgs(int nonOpt, int o
impl()->methodWithNonOptionalArgAndTwoOptionalArgs(nonOpt, opt1, opt2);
}
+void WebDOMTestObj::classMethod()
+{
+ if (!impl())
+ return;
+
+ impl()->classMethod();
+}
+
+int WebDOMTestObj::classMethodWithOptional(int arg)
+{
+ if (!impl())
+ return 0;
+
+ return impl()->classMethodWithOptional(arg);
+}
+
WebCore::TestObj* toWebCore(const WebDOMTestObj& wrapper)
{
return wrapper.impl();
diff --git a/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.h b/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.h
index 770ce51..037a1d3 100644
--- a/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.h
+++ b/WebCore/bindings/scripts/test/CPP/WebDOMTestObj.h
@@ -150,6 +150,8 @@ public:
void methodWithOptionalArg(int opt);
void methodWithNonOptionalArgAndOptionalArg(int nonOpt, int opt);
void methodWithNonOptionalArgAndTwoOptionalArgs(int nonOpt, int opt1, int opt2);
+ void classMethod();
+ int classMethodWithOptional(int arg);
WebCore::TestObj* impl() const;
diff --git a/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.cpp b/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.cpp
index 3c27b81..c9c10d7 100644
--- a/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.cpp
+++ b/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.cpp
@@ -364,6 +364,25 @@ webkit_dom_test_obj_method_with_non_optional_arg_and_two_optional_args(WebKitDOM
item->methodWithNonOptionalArgAndTwoOptionalArgs(non_opt, opt1, opt2);
}
+void
+webkit_dom_test_obj_class_method(WebKitDOMTestObj* self)
+{
+ WebCore::JSMainThreadNullState state;
+ g_return_if_fail(self);
+ WebCore::TestObj * item = WebKit::core(self);
+ item->classMethod();
+}
+
+glong
+webkit_dom_test_obj_class_method_with_optional(WebKitDOMTestObj* self, glong arg)
+{
+ WebCore::JSMainThreadNullState state;
+ g_return_val_if_fail(self, 0);
+ WebCore::TestObj * item = WebKit::core(self);
+ glong res = item->classMethodWithOptional(arg);
+ return res;
+}
+
glong
webkit_dom_test_obj_get_read_only_int_attr(WebKitDOMTestObj* self)
{
diff --git a/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.h b/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.h
index 4cc796d..8ee8f04 100644
--- a/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.h
+++ b/WebCore/bindings/scripts/test/GObject/WebKitDOMTestObj.h
@@ -124,6 +124,12 @@ webkit_dom_test_obj_method_with_non_optional_arg_and_optional_arg(WebKitDOMTestO
WEBKIT_API void
webkit_dom_test_obj_method_with_non_optional_arg_and_two_optional_args(WebKitDOMTestObj* self, glong non_opt, glong opt1, glong opt2);
+WEBKIT_API void
+webkit_dom_test_obj_class_method(WebKitDOMTestObj* self);
+
+WEBKIT_API glong
+webkit_dom_test_obj_class_method_with_optional(WebKitDOMTestObj* self, glong arg);
+
WEBKIT_API glong
webkit_dom_test_obj_get_read_only_int_attr(WebKitDOMTestObj* self);
diff --git a/WebCore/bindings/scripts/test/JS/JSTestObj.cpp b/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
index 2a39ac4..63bc368 100644
--- a/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
+++ b/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
@@ -177,7 +177,7 @@ bool JSTestObjConstructor::getOwnPropertyDescriptor(ExecState* exec, const Ident
#define THUNK_GENERATOR(generator)
#endif
-static const HashTableValue JSTestObjPrototypeTableValues[45] =
+static const HashTableValue JSTestObjPrototypeTableValues[47] =
{
{ "CONST_VALUE_0", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCONST_VALUE_0), (intptr_t)0 THUNK_GENERATOR(0) },
{ "CONST_VALUE_1", DontDelete | ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCONST_VALUE_1), (intptr_t)0 THUNK_GENERATOR(0) },
@@ -223,6 +223,8 @@ static const HashTableValue JSTestObjPrototypeTableValues[45] =
{ "methodWithNonCallbackArgAndCallbackArg", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithNonCallbackArgAndCallbackArg), (intptr_t)2 THUNK_GENERATOR(0) },
{ "methodWithCallbackAndOptionalArg", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithCallbackAndOptionalArg), (intptr_t)1 THUNK_GENERATOR(0) },
{ "overloadedMethod", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionOverloadedMethod), (intptr_t)2 THUNK_GENERATOR(0) },
+ { "classMethod", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionClassMethod), (intptr_t)0 THUNK_GENERATOR(0) },
+ { "classMethodWithOptional", DontDelete | Function, (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionClassMethodWithOptional), (intptr_t)1 THUNK_GENERATOR(0) },
{ 0, 0, 0, 0 THUNK_GENERATOR(0) }
};
@@ -1415,6 +1417,23 @@ static EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod4(
return JSValue::encode(jsUndefined());
}
+static EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod5(ExecState* exec)
+{
+ JSValue thisValue = exec->hostThisValue();
+ if (!thisValue.inherits(&JSTestObj::s_info))
+ return throwVMTypeError(exec);
+ JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
+ TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+ if (exec->argumentCount() <= 0 || !exec->argument(0).isObject()) {
+ setDOMException(exec, TYPE_MISMATCH_ERR);
+ return JSValue::encode(jsUndefined());
+ }
+ RefPtr<TestCallback> callback = JSTestCallback::create(asObject(exec->argument(0)), castedThis->globalObject());
+
+ imp->overloadedMethod(callback);
+ return JSValue::encode(jsUndefined());
+}
+
EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(ExecState* exec)
{
if ((exec->argumentCount() == 2 && (exec->argument(0).isNull() || (exec->argument(0).isObject() && asObject(exec->argument(0))->inherits(&JSTestObj::s_info))) && (exec->argument(1).isNull() || exec->argument(1).isUndefined() || exec->argument(1).isString() || exec->argument(1).isObject())))
@@ -1425,9 +1444,47 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(ExecStat
return jsTestObjPrototypeFunctionOverloadedMethod3(exec);
if (exec->argumentCount() == 1)
return jsTestObjPrototypeFunctionOverloadedMethod4(exec);
+ if ((exec->argumentCount() == 1 && (exec->argument(0).isNull() || exec->argument(0).isObject())))
+ return jsTestObjPrototypeFunctionOverloadedMethod5(exec);
return throwVMTypeError(exec);
}
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionClassMethod(ExecState* exec)
+{
+ JSValue thisValue = exec->hostThisValue();
+ if (!thisValue.inherits(&JSTestObj::s_info))
+ return throwVMTypeError(exec);
+ JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
+ TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+
+ imp->classMethod();
+ return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionClassMethodWithOptional(ExecState* exec)
+{
+ JSValue thisValue = exec->hostThisValue();
+ if (!thisValue.inherits(&JSTestObj::s_info))
+ return throwVMTypeError(exec);
+ JSTestObj* castedThis = static_cast<JSTestObj*>(asObject(thisValue));
+ TestObj* imp = static_cast<TestObj*>(castedThis->impl());
+
+ int argsCount = exec->argumentCount();
+ if (argsCount <= 0) {
+
+ JSC::JSValue result = jsNumber(exec, imp->classMethodWithOptional());
+ return JSValue::encode(result);
+ }
+
+ int arg = exec->argument(0).toInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+
+ JSC::JSValue result = jsNumber(exec, imp->classMethodWithOptional(arg));
+ return JSValue::encode(result);
+}
+
// Constant getters
JSValue jsTestObjCONST_VALUE_0(ExecState* exec, JSValue, const Identifier&)
diff --git a/WebCore/bindings/scripts/test/JS/JSTestObj.h b/WebCore/bindings/scripts/test/JS/JSTestObj.h
index 993df8c..2168b3f 100644
--- a/WebCore/bindings/scripts/test/JS/JSTestObj.h
+++ b/WebCore/bindings/scripts/test/JS/JSTestObj.h
@@ -119,6 +119,8 @@ JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackAr
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNonCallbackArgAndCallbackArg(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackAndOptionalArg(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionClassMethod(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionClassMethodWithOptional(JSC::ExecState*);
// Attributes
JSC::JSValue jsTestObjReadOnlyIntAttr(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&);
diff --git a/WebCore/bindings/scripts/test/ObjC/DOMTestObj.h b/WebCore/bindings/scripts/test/ObjC/DOMTestObj.h
index 4a0f065..132b215 100644
--- a/WebCore/bindings/scripts/test/ObjC/DOMTestObj.h
+++ b/WebCore/bindings/scripts/test/ObjC/DOMTestObj.h
@@ -142,6 +142,8 @@ enum {
- (void)methodWithOptionalArg:(int)opt;
- (void)methodWithNonOptionalArgAndOptionalArg:(int)nonOpt opt:(int)opt;
- (void)methodWithNonOptionalArgAndTwoOptionalArgs:(int)nonOpt opt1:(int)opt1 opt2:(int)opt2;
+- (void)classMethod;
+- (int)classMethodWithOptional:(int)arg;
@end
#endif
diff --git a/WebCore/bindings/scripts/test/ObjC/DOMTestObj.mm b/WebCore/bindings/scripts/test/ObjC/DOMTestObj.mm
index 01fcf34..9725b24 100644
--- a/WebCore/bindings/scripts/test/ObjC/DOMTestObj.mm
+++ b/WebCore/bindings/scripts/test/ObjC/DOMTestObj.mm
@@ -634,6 +634,18 @@
IMPL->methodWithNonOptionalArgAndTwoOptionalArgs(nonOpt, opt1, opt2);
}
+- (void)classMethod
+{
+ WebCore::JSMainThreadNullState state;
+ IMPL->classMethod();
+}
+
+- (int)classMethodWithOptional:(int)arg
+{
+ WebCore::JSMainThreadNullState state;
+ return IMPL->classMethodWithOptional(arg);
+}
+
@end
WebCore::TestObj* core(DOMTestObj *wrapper)
diff --git a/WebCore/bindings/scripts/test/TestObj.idl b/WebCore/bindings/scripts/test/TestObj.idl
index 94f734b..89dfdf7 100644
--- a/WebCore/bindings/scripts/test/TestObj.idl
+++ b/WebCore/bindings/scripts/test/TestObj.idl
@@ -135,8 +135,13 @@ module test {
void overloadedMethod(in TestObj objArg, in [Optional] long intArg);
void overloadedMethod(in DOMString strArg);
void overloadedMethod(in long intArg);
+ void overloadedMethod(in [Callback] TestCallback callback);
#endif
+ // Class methods within JavaScript (like what's used for IDBKeyRange).
+ [ClassMethod] void classMethod();
+ [ClassMethod] long classMethodWithOptional(in [Optional] long arg);
+
// ObjectiveC reserved words.
readonly attribute long description;
attribute long id;
diff --git a/WebCore/bindings/scripts/test/V8/V8TestObj.cpp b/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
index 7428c93..8f824d9 100644
--- a/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
+++ b/WebCore/bindings/scripts/test/V8/V8TestObj.cpp
@@ -135,7 +135,7 @@ static void stringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value
{
INC_STATS("DOM.TestObj.stringAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<>, v, value);
imp->setStringAttr(v);
return;
}
@@ -199,7 +199,7 @@ static void reflectedStringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<
{
INC_STATS("DOM.TestObj.reflectedStringAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<WithNullCheck> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<WithNullCheck>, v, value);
imp->setAttribute(WebCore::HTMLNames::reflectedstringattrAttr, v);
return;
}
@@ -247,7 +247,7 @@ static void reflectedURLAttrAttrSetter(v8::Local<v8::String> name, v8::Local<v8:
{
INC_STATS("DOM.TestObj.reflectedURLAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<WithNullCheck> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<WithNullCheck>, v, value);
imp->setAttribute(WebCore::HTMLNames::reflectedurlattrAttr, v);
return;
}
@@ -263,7 +263,7 @@ static void reflectedNonEmptyURLAttrAttrSetter(v8::Local<v8::String> name, v8::L
{
INC_STATS("DOM.TestObj.reflectedNonEmptyURLAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<WithNullCheck> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<WithNullCheck>, v, value);
imp->setAttribute(WebCore::HTMLNames::reflectednonemptyurlattrAttr, v);
return;
}
@@ -279,7 +279,7 @@ static void reflectedStringAttrAttrSetter(v8::Local<v8::String> name, v8::Local<
{
INC_STATS("DOM.TestObj.reflectedStringAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<WithNullCheck> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<WithNullCheck>, v, value);
imp->setAttribute(WebCore::HTMLNames::customContentStringAttrAttr, v);
return;
}
@@ -327,7 +327,7 @@ static void reflectedCustomURLAttrAttrSetter(v8::Local<v8::String> name, v8::Loc
{
INC_STATS("DOM.TestObj.reflectedCustomURLAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<WithNullCheck> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<WithNullCheck>, v, value);
imp->setAttribute(WebCore::HTMLNames::customContentURLAttrAttr, v);
return;
}
@@ -343,7 +343,7 @@ static void reflectedCustomNonEmptyURLAttrAttrSetter(v8::Local<v8::String> name,
{
INC_STATS("DOM.TestObj.reflectedCustomNonEmptyURLAttr._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<WithNullCheck> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<WithNullCheck>, v, value);
imp->setAttribute(WebCore::HTMLNames::customContentNonEmptyURLAttrAttr, v);
return;
}
@@ -409,7 +409,7 @@ static void stringAttrWithGetterExceptionAttrSetter(v8::Local<v8::String> name,
{
INC_STATS("DOM.TestObj.stringAttrWithGetterException._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<>, v, value);
ExceptionCode ec = 0;
imp->setStringAttrWithGetterException(v, ec);
if (UNLIKELY(ec))
@@ -428,7 +428,7 @@ static void stringAttrWithSetterExceptionAttrSetter(v8::Local<v8::String> name,
{
INC_STATS("DOM.TestObj.stringAttrWithSetterException._set");
TestObj* imp = V8TestObj::toNative(info.Holder());
- V8Parameter<> v = value;
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(V8Parameter<>, v, value);
ExceptionCode ec = 0;
imp->setStringAttrWithSetterException(v, ec);
if (UNLIKELY(ec))
@@ -975,6 +975,17 @@ static v8::Handle<v8::Value> overloadedMethod4Callback(const v8::Arguments& args
return v8::Handle<v8::Value>();
}
+static v8::Handle<v8::Value> overloadedMethod5Callback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.overloadedMethod5");
+ TestObj* imp = V8TestObj::toNative(args.Holder());
+ if (args.Length() <= 0 || !args[0]->IsObject())
+ return throwError(TYPE_MISMATCH_ERR);
+ RefPtr<TestCallback> callback = V8TestCallback::create(args[0], getScriptExecutionContext());
+ imp->overloadedMethod(callback);
+ return v8::Handle<v8::Value>();
+}
+
static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
{
INC_STATS("DOM.TestObj.overloadedMethod");
@@ -986,10 +997,29 @@ static v8::Handle<v8::Value> overloadedMethodCallback(const v8::Arguments& args)
return overloadedMethod3Callback(args);
if (args.Length() == 1)
return overloadedMethod4Callback(args);
+ if ((args.Length() == 1 && (args[0]->IsNull() || args[0]->IsObject())))
+ return overloadedMethod5Callback(args);
V8Proxy::throwTypeError();
return notHandledByInterceptor();
}
+static v8::Handle<v8::Value> classMethodCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.classMethod");
+ TestObj::classMethod();
+ return v8::Handle<v8::Value>();
+}
+
+static v8::Handle<v8::Value> classMethodWithOptionalCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.TestObj.classMethodWithOptional");
+ if (args.Length() <= 0) {
+ return v8::Integer::New(TestObj::classMethodWithOptional());
+ }
+ EXCEPTION_BLOCK(int, arg, toInt32(args[0]));
+ return v8::Integer::New(TestObj::classMethodWithOptional(arg));
+}
+
} // namespace TestObjInternal
static const BatchedAttribute TestObjAttrs[] = {
@@ -1163,6 +1193,8 @@ static v8::Persistent<v8::FunctionTemplate> ConfigureV8TestObjTemplate(v8::Persi
v8::Handle<v8::FunctionTemplate> customArgsAndExceptionArgv[customArgsAndExceptionArgc] = { V8log::GetRawTemplate() };
v8::Handle<v8::Signature> customArgsAndExceptionSignature = v8::Signature::New(desc, customArgsAndExceptionArgc, customArgsAndExceptionArgv);
proto->Set(v8::String::New("customArgsAndException"), v8::FunctionTemplate::New(TestObjInternal::customArgsAndExceptionCallback, v8::Handle<v8::Value>(), customArgsAndExceptionSignature));
+ desc->Set(v8::String::New("classMethod"), v8::FunctionTemplate::New(TestObjInternal::classMethodCallback, v8::Handle<v8::Value>(), v8::Local<v8::Signature>()));
+ desc->Set(v8::String::New("classMethodWithOptional"), v8::FunctionTemplate::New(TestObjInternal::classMethodWithOptionalCallback, v8::Handle<v8::Value>(), v8::Local<v8::Signature>()));
batchConfigureConstants(desc, proto, TestObjConsts, sizeof(TestObjConsts) / sizeof(*TestObjConsts));
// Custom toString template
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index 58989ed..566e8ac 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -31,6 +31,8 @@
#ifndef V8Binding_h
#define V8Binding_h
+#include "BindingFrame.h"
+#include "BindingLocation.h"
#include "BindingSecurity.h"
#include "MathExtras.h"
#include "PlatformString.h"
@@ -50,16 +52,18 @@ namespace WebCore {
public:
typedef v8::Handle<v8::Value> Value;
typedef V8BindingDOMWindow DOMWindow;
+ typedef BindingFrame<V8Binding> Frame;
+ typedef BindingLocation<V8Binding> Location;
static Value emptyScriptValue() { return v8::Local<v8::Value>(); }
};
typedef BindingSecurity<V8Binding> V8BindingSecurity;
-
+
enum ExternalMode {
Externalize,
DoNotExternalize
};
-
+
template <typename StringType>
StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external);
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.cpp b/WebCore/bindings/v8/V8DOMWindowShell.cpp
index 435876c..a69eab4 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.cpp
+++ b/WebCore/bindings/v8/V8DOMWindowShell.cpp
@@ -89,7 +89,7 @@ static void reportFatalErrorInV8(const char* location, const char* message)
// FIXME: clean up V8Proxy and disable JavaScript.
int memoryUsageMB = -1;
#if PLATFORM(CHROMIUM)
- memoryUsageMB = ChromiumBridge::memoryUsageMB();
+ memoryUsageMB = ChromiumBridge::actualMemoryUsageMB();
#endif
printf("V8 error: %s (%s). Current memory usage: %d MB\n", message, location, memoryUsageMB);
handleFatalErrorInV8();
@@ -246,11 +246,11 @@ void V8DOMWindowShell::clearForNavigation()
// the frame. However, a new inner window is created for the new page.
// If there are JS code holds a closure to the old inner window,
// it won't be able to reach the outer window via its global object.
-void V8DOMWindowShell::initContextIfNeeded()
+bool V8DOMWindowShell::initContextIfNeeded()
{
// Bail out if the context has already been initialized.
if (!m_context.IsEmpty())
- return;
+ return false;
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::JavaScriptInitTimeCounter);
@@ -281,7 +281,7 @@ void V8DOMWindowShell::initContextIfNeeded()
m_context = createNewContext(m_global, 0);
if (m_context.IsEmpty())
- return;
+ return false;
v8::Local<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context);
v8::Context::Scope contextScope(v8Context);
@@ -292,7 +292,7 @@ void V8DOMWindowShell::initContextIfNeeded()
// Bail out if allocation of the first global objects fails.
if (m_global.IsEmpty()) {
disposeContextHandles();
- return;
+ return false;
}
#ifndef NDEBUG
V8GCController::registerGlobalHandle(PROXY, this, m_global);
@@ -301,12 +301,12 @@ void V8DOMWindowShell::initContextIfNeeded()
if (!installHiddenObjectPrototype(v8Context)) {
disposeContextHandles();
- return;
+ return false;
}
if (!installDOMWindow(v8Context, m_frame->domWindow())) {
disposeContextHandles();
- return;
+ return false;
}
updateDocument();
@@ -319,9 +319,13 @@ void V8DOMWindowShell::initContextIfNeeded()
// we do isolated worlds the WebCore way.
m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
+<<<<<<< HEAD
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::record(android::TimeCounter::JavaScriptInitTimeCounter, __FUNCTION__);
#endif
+=======
+ return true;
+>>>>>>> webkit.org at r67178
}
v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Object> global, int extensionGroup)
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.h b/WebCore/bindings/v8/V8DOMWindowShell.h
index 7958bf1..76c27af 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.h
+++ b/WebCore/bindings/v8/V8DOMWindowShell.h
@@ -69,7 +69,7 @@ public:
void setContext(v8::Handle<v8::Context>);
static bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow*);
- void initContextIfNeeded();
+ bool initContextIfNeeded();
void updateDocumentWrapper(v8::Handle<v8::Object> wrapper);
void clearForNavigation();
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index 921f957..7d7efe5 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -329,9 +329,8 @@ bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, WrapperTypeInfo*
return typeInfo == type;
}
-v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
+v8::Handle<v8::Object> V8DOMWrapper::getWrapperSlow(Node* node)
{
- ASSERT(WTF::isMainThread());
V8IsolatedContext* context = V8IsolatedContext::getEntered();
if (LIKELY(!context)) {
v8::Persistent<v8::Object>* wrapper = node->wrapper();
@@ -339,7 +338,6 @@ v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
return v8::Handle<v8::Object>();
return *wrapper;
}
-
DOMNodeMapping& domNodeMap = context->world()->domDataStore()->domNodeMap();
return domNodeMap.get(node);
}
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index 943cb8a..ed02743 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -33,6 +33,7 @@
#include "Document.h"
#include "Event.h"
+#include "IsolatedWorld.h"
#include "Node.h"
#include "NodeFilter.h"
#include "PlatformString.h"
@@ -130,7 +131,19 @@ namespace WebCore {
static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo*, void* impl);
- static v8::Handle<v8::Object> getWrapper(Node*);
+ static v8::Handle<v8::Object> getWrapper(Node* node)
+ {
+ ASSERT(WTF::isMainThread());
+ if (LIKELY(!IsolatedWorld::count())) {
+ v8::Persistent<v8::Object>* wrapper = node->wrapper();
+ if (wrapper)
+ return *wrapper;
+ }
+ return getWrapperSlow(node);
+ }
+
+ private:
+ static v8::Handle<v8::Object> getWrapperSlow(Node*);
};
}
diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp
index c27e1d5..36beece 100644
--- a/WebCore/bindings/v8/V8GCController.cpp
+++ b/WebCore/bindings/v8/V8GCController.cpp
@@ -406,6 +406,15 @@ int getMemoryUsageInMB()
#endif
}
+int getActualMemoryUsageInMB()
+{
+#if PLATFORM(CHROMIUM)
+ return ChromiumBridge::actualMemoryUsageMB();
+#else
+ return 0;
+#endif
+}
+
} // anonymous namespace
void V8GCController::gcEpilogue()
@@ -417,7 +426,7 @@ void V8GCController::gcEpilogue()
GCEpilogueVisitor epilogueVisitor;
visitActiveDOMObjectsInCurrentThread(&epilogueVisitor);
- workingSetEstimateMB = getMemoryUsageInMB();
+ workingSetEstimateMB = getActualMemoryUsageInMB();
#ifndef NDEBUG
// Check all survivals are weak.
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index 2e5cf8b..e497071 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -38,7 +38,6 @@
#include "ScriptExecutionContext.h"
#include "ScriptState.h"
#include "V8Binding.h"
-#include "V8BindingDOMWindow.h" // FIXME: remove when completeURL moves
#include "V8BindingState.h"
#include "V8Proxy.h"
#include "WorkerContext.h"
@@ -112,16 +111,12 @@ bool shouldAllowNavigation(Frame* frame)
KURL completeURL(const String& relativeURL)
{
- return V8BindingDOMWindow::completeURL(V8BindingState::Only(), relativeURL);
+ return completeURL(V8BindingState::Only(), relativeURL);
}
void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
{
- Frame* callingOrEntered = callingOrEnteredFrame();
- if (!callingOrEntered)
- return;
- if (!protocolIsJavaScript(url) || ScriptController::isSafeScript(frame))
- frame->redirectScheduler()->scheduleLocationChange(url.string(), callingOrEntered->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
+ return V8Binding::Frame::navigateIfAllowed(V8BindingState::Only(), frame, url, lockHistory, lockBackForwardList);
}
ScriptExecutionContext* getScriptExecutionContext()
diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
index ac305c9..6068aa2 100644
--- a/WebCore/bindings/v8/custom/V8LocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
@@ -292,19 +292,7 @@ v8::Handle<v8::Value> V8Location::replaceCallback(const v8::Arguments& args)
INC_STATS("DOM.Location.replace");
v8::Handle<v8::Object> holder = args.Holder();
Location* imp = V8Location::toNative(holder);
-
- Frame* frame = imp->frame();
- if (!frame)
- return v8::Undefined();
-
- KURL url = completeURL(toWebCoreString(args[0]));
- if (url.isNull())
- return v8::Undefined();
-
- if (!shouldAllowNavigation(frame))
- return v8::Undefined();
-
- navigateIfAllowed(frame, url, true, true);
+ V8Binding::Location::replace(V8BindingState::Only(), imp, toWebCoreString(args[0]));
return v8::Undefined();
}
@@ -378,4 +366,3 @@ v8::Handle<v8::Value> toV8(Location* impl)
}
} // namespace WebCore
-
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index 1f0c79b..50b9899 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -130,7 +130,7 @@ v8::Handle<v8::Value> V8Node::appendChildCallback(const v8::Arguments& args)
return v8::Null();
}
-v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject)
+v8::Handle<v8::Value> toV8Slow(Node* impl, bool forceNewObject)
{
if (!impl)
return v8::Null();
diff --git a/WebCore/bindings/v8/specialization/V8BindingState.cpp b/WebCore/bindings/v8/specialization/V8BindingState.cpp
index ccdd7c8..2193c9f 100644
--- a/WebCore/bindings/v8/specialization/V8BindingState.cpp
+++ b/WebCore/bindings/v8/specialization/V8BindingState.cpp
@@ -84,4 +84,9 @@ bool State<V8Binding>::processingUserGesture()
return ScriptController::processingUserGesture();
}
+bool State<V8Binding>::allowsAccessFromFrame(Frame* frame)
+{
+ return ScriptController::isSafeScript(frame);
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/specialization/V8BindingState.h b/WebCore/bindings/v8/specialization/V8BindingState.h
index baba0c6..14305b8 100644
--- a/WebCore/bindings/v8/specialization/V8BindingState.h
+++ b/WebCore/bindings/v8/specialization/V8BindingState.h
@@ -60,6 +60,9 @@ public:
bool processingUserGesture();
+ // FIXME: This should be shared in BindingSecurity
+ bool allowsAccessFromFrame(Frame*);
+
private:
explicit State() {}
~State();
diff --git a/WebCore/bridge/qt/qt_instance.cpp b/WebCore/bridge/qt/qt_instance.cpp
index 3723ec0..1229919 100644
--- a/WebCore/bridge/qt/qt_instance.cpp
+++ b/WebCore/bridge/qt/qt_instance.cpp
@@ -192,34 +192,6 @@ void QtInstance::markAggregate(MarkStack& markStack)
if (val)
markStack.append(val);
}
- foreach (QtField* field, m_fields.values()) {
- bool mark = false;
- if (field->fieldType() == QtField::MetaProperty)
- mark = true;
- else if (field->fieldType() == QtField::DynamicProperty) {
- if (m_object && m_object->dynamicPropertyNames().indexOf(field->name()) >= 0)
- mark = true;
- } else if (m_object) {
- QList<QObject*> children = m_object->children();
- for (int index = 0; index < children.count(); ++index) {
- QObject* child = children.at(index);
- if (child->objectName().toLatin1() == field->name()) {
- mark = true;
- break;
- }
- }
- }
- if (mark) {
- if (RefPtr<RootObject> ro = rootObject()) {
- JSGlobalObject* globalobj = ro->globalObject();
- if (globalobj) {
- ExecState* exec = globalobj->globalExec();
- JSValue val = field->valueFromInstance(exec, this);
- markStack.append(val);
- }
- }
- }
- }
}
void QtInstance::begin()
diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp
index 630fd2f..ce4567a 100644
--- a/WebCore/bridge/qt/qt_runtime.cpp
+++ b/WebCore/bridge/qt/qt_runtime.cpp
@@ -1793,26 +1793,28 @@ void QtConnectionObject::execute(void **argv)
l.append(jsUndefined());
}
}
- CallData callData;
- CallType callType = m_funcObject->getCallData(callData);
// Stuff in the __qt_sender property, if we can
+ ScopeChain oldsc = ScopeChain(NoScopeChain());
+ JSFunction* fimp = 0;
if (m_funcObject->inherits(&JSFunction::info)) {
- JSFunction* fimp = static_cast<JSFunction*>(m_funcObject.get());
+ fimp = static_cast<JSFunction*>(m_funcObject.get());
JSObject* qt_sender = QtInstance::getQtInstance(sender(), ro, QScriptEngine::QtOwnership)->createRuntimeObject(exec);
JSObject* wrapper = new (exec) JSObject(JSObject::createStructure(jsNull()));
PutPropertySlot slot;
wrapper->put(exec, Identifier(exec, "__qt_sender__"), qt_sender, slot);
- ScopeChain oldsc = fimp->scope();
+ oldsc = fimp->scope();
ScopeChain sc = oldsc;
sc.push(wrapper);
fimp->setScope(sc);
+ }
+
+ CallData callData;
+ CallType callType = m_funcObject->getCallData(callData);
+ call(exec, m_funcObject, callType, callData, m_thisObject, l);
- call(exec, fimp, callType, callData, m_thisObject, l);
+ if (fimp)
fimp->setScope(oldsc);
- } else {
- call(exec, m_funcObject, callType, callData, m_thisObject, l);
- }
}
}
}
diff --git a/WebCore/css/CSSComputedStyleDeclaration.cpp b/WebCore/css/CSSComputedStyleDeclaration.cpp
index edb6987..d5330c6 100644
--- a/WebCore/css/CSSComputedStyleDeclaration.cpp
+++ b/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -521,13 +521,29 @@ static PassRefPtr<CSSValue> getTimingFunctionValue(const AnimationList* animList
RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
if (animList) {
for (size_t i = 0; i < animList->size(); ++i) {
- const TimingFunction& tf = animList->animation(i)->timingFunction();
- list->append(CSSTimingFunctionValue::create(tf.x1(), tf.y1(), tf.x2(), tf.y2()));
+ const TimingFunction* tf = animList->animation(i)->timingFunction().get();
+ if (tf->isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(tf);
+ list->append(CSSCubicBezierTimingFunctionValue::create(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2()));
+ } else if (tf->isStepsTimingFunction()) {
+ const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(tf);
+ list->append(CSSStepsTimingFunctionValue::create(stf->numberOfSteps(), stf->stepAtStart()));
+ } else {
+ list->append(CSSLinearTimingFunctionValue::create());
+ }
}
} else {
// Note that initialAnimationTimingFunction() is used for both transitions and animations
- const TimingFunction& tf = Animation::initialAnimationTimingFunction();
- list->append(CSSTimingFunctionValue::create(tf.x1(), tf.y1(), tf.x2(), tf.y2()));
+ const TimingFunction* tf = Animation::initialAnimationTimingFunction().get();
+ if (tf->isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(tf);
+ list->append(CSSCubicBezierTimingFunctionValue::create(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2()));
+ } else if (tf->isStepsTimingFunction()) {
+ const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(tf);
+ list->append(CSSStepsTimingFunctionValue::create(stf->numberOfSteps(), stf->stepAtStart()));
+ } else {
+ list->append(CSSLinearTimingFunctionValue::create());
+ }
}
return list.release();
}
@@ -575,13 +591,12 @@ static int cssIdentifierForFontSizeKeyword(int keywordSize)
PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
{
- Node* node = m_node.get();
- if (!node)
+ if (!m_node)
return 0;
- node->document()->updateLayoutIgnorePendingStylesheets();
+ m_node->document()->updateLayoutIgnorePendingStylesheets();
- RefPtr<RenderStyle> style = node->computedStyle(m_pseudoElementSpecifier);
+ RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
if (!style)
return 0;
@@ -591,6 +606,18 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringK
return CSSPrimitiveValue::create(style->fontDescription().computedPixelSize(), CSSPrimitiveValue::CSS_PX);
}
+bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
+{
+ if (!m_node)
+ return false;
+
+ RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
+ if (!style)
+ return false;
+
+ return style->fontDescription().useFixedDefaultSize();
+}
+
PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, int id) const
{
if (!shadow)
diff --git a/WebCore/css/CSSComputedStyleDeclaration.h b/WebCore/css/CSSComputedStyleDeclaration.h
index 816d15a..d4b7df2 100644
--- a/WebCore/css/CSSComputedStyleDeclaration.h
+++ b/WebCore/css/CSSComputedStyleDeclaration.h
@@ -58,6 +58,7 @@ public:
PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID, EUpdateLayout) const;
PassRefPtr<CSSValue> getFontSizeCSSValuePreferringKeyword() const;
+ bool useFixedFontDefaultSize() const;
#if ENABLE(SVG)
PassRefPtr<CSSValue> getSVGPropertyCSSValue(int propertyID, EUpdateLayout) const;
#endif
diff --git a/WebCore/css/CSSCursorImageValue.cpp b/WebCore/css/CSSCursorImageValue.cpp
index f2e5d95..2b09ab3 100644
--- a/WebCore/css/CSSCursorImageValue.cpp
+++ b/WebCore/css/CSSCursorImageValue.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "CSSCursorImageValue.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "PlatformString.h"
#include <wtf/MathExtras.h>
@@ -111,7 +111,7 @@ bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
return false;
}
-StyleCachedImage* CSSCursorImageValue::cachedImage(DocLoader* loader)
+StyleCachedImage* CSSCursorImageValue::cachedImage(CachedResourceLoader* loader)
{
String url = getStringValue();
diff --git a/WebCore/css/CSSCursorImageValue.h b/WebCore/css/CSSCursorImageValue.h
index 742138c..2a95c3a 100644
--- a/WebCore/css/CSSCursorImageValue.h
+++ b/WebCore/css/CSSCursorImageValue.h
@@ -42,7 +42,7 @@ public:
IntPoint hotSpot() const { return m_hotSpot; }
bool updateIfSVGCursorIsUsed(Element*);
- virtual StyleCachedImage* cachedImage(DocLoader*);
+ virtual StyleCachedImage* cachedImage(CachedResourceLoader*);
#if ENABLE(SVG)
void removeReferencedElement(SVGElement*);
diff --git a/WebCore/css/CSSFontFaceSource.cpp b/WebCore/css/CSSFontFaceSource.cpp
index 01b5569..ad9bebc 100644
--- a/WebCore/css/CSSFontFaceSource.cpp
+++ b/WebCore/css/CSSFontFaceSource.cpp
@@ -29,7 +29,7 @@
#include "CachedFont.h"
#include "CSSFontFace.h"
#include "CSSFontSelector.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "FontCache.h"
#include "FontDescription.h"
#include "GlyphPageTreeNode.h"
@@ -173,8 +173,8 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri
}
} else {
// Kick off the load now.
- if (DocLoader* docLoader = fontSelector->docLoader())
- m_font->beginLoadIfNeeded(docLoader);
+ if (CachedResourceLoader* cachedResourceLoader = fontSelector->cachedResourceLoader())
+ m_font->beginLoadIfNeeded(cachedResourceLoader);
// FIXME: m_string is a URL so it makes no sense to pass it as a family name.
SimpleFontData* tempData = fontCache()->getCachedFontData(fontDescription, m_string);
if (!tempData)
diff --git a/WebCore/css/CSSFontSelector.cpp b/WebCore/css/CSSFontSelector.cpp
index 50627d7..d97589d 100644
--- a/WebCore/css/CSSFontSelector.cpp
+++ b/WebCore/css/CSSFontSelector.cpp
@@ -39,7 +39,7 @@
#include "CSSUnicodeRangeValue.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "FontCache.h"
#include "FontFamilyValue.h"
@@ -80,9 +80,9 @@ bool CSSFontSelector::isEmpty() const
return m_fonts.isEmpty();
}
-DocLoader* CSSFontSelector::docLoader() const
+CachedResourceLoader* CSSFontSelector::cachedResourceLoader() const
{
- return m_document ? m_document->docLoader() : 0;
+ return m_document ? m_document->cachedResourceLoader() : 0;
}
void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
@@ -245,7 +245,7 @@ void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
Settings* settings = m_document ? m_document->frame() ? m_document->frame()->settings() : 0 : 0;
bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
if (allowDownloading && item->isSupportedFormat() && m_document) {
- CachedFont* cachedFont = m_document->docLoader()->requestFont(item->resource());
+ CachedFont* cachedFont = m_document->cachedResourceLoader()->requestFont(item->resource());
if (cachedFont) {
#if ENABLE(SVG_FONTS)
if (foundSVGFont)
diff --git a/WebCore/css/CSSFontSelector.h b/WebCore/css/CSSFontSelector.h
index abf82cd..93ee274 100644
--- a/WebCore/css/CSSFontSelector.h
+++ b/WebCore/css/CSSFontSelector.h
@@ -38,7 +38,7 @@ class CSSFontFace;
class CSSFontFaceRule;
class CSSSegmentedFontFace;
class Document;
-class DocLoader;
+class CachedResourceLoader;
class FontDescription;
class CSSFontSelector : public FontSelector {
@@ -60,7 +60,7 @@ public:
bool isEmpty() const;
- DocLoader* docLoader() const;
+ CachedResourceLoader* cachedResourceLoader() const;
private:
CSSFontSelector(Document*);
diff --git a/WebCore/css/CSSGrammar.y b/WebCore/css/CSSGrammar.y
index ec507be..86a2f7c 100644
--- a/WebCore/css/CSSGrammar.y
+++ b/WebCore/css/CSSGrammar.y
@@ -79,7 +79,7 @@ using namespace HTMLNames;
MediaQueryExp* mediaQueryExp;
CSSParserValue value;
CSSParserValueList* valueList;
- Vector<MediaQueryExp*>* mediaQueryExpList;
+ Vector<OwnPtr<MediaQueryExp> >* mediaQueryExpList;
WebKitCSSKeyframeRule* keyframeRule;
WebKitCSSKeyframesRule* keyframesRule;
float val;
@@ -627,11 +627,11 @@ media_query_exp_list:
media_query_exp {
CSSParser* p = static_cast<CSSParser*>(parser);
$$ = p->createFloatingMediaQueryExpList();
- $$->append(p->sinkFloatingMediaQueryExp($1).leakPtr());
+ $$->append(p->sinkFloatingMediaQueryExp($1));
}
| media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
$$ = $1;
- $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5).leakPtr());
+ $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($5));
}
;
diff --git a/WebCore/css/CSSImageValue.cpp b/WebCore/css/CSSImageValue.cpp
index dc2d700..e657fcc 100644
--- a/WebCore/css/CSSImageValue.cpp
+++ b/WebCore/css/CSSImageValue.cpp
@@ -24,7 +24,7 @@
#include "CSSValueKeywords.h"
#include "Cache.h"
#include "CachedImage.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "StyleCachedImage.h"
#include "StylePendingImage.h"
@@ -59,12 +59,12 @@ StyleImage* CSSImageValue::cachedOrPendingImage()
return m_image.get();
}
-StyleCachedImage* CSSImageValue::cachedImage(DocLoader* loader)
+StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader)
{
return cachedImage(loader, getStringValue());
}
-StyleCachedImage* CSSImageValue::cachedImage(DocLoader* loader, const String& url)
+StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const String& url)
{
if (!m_accessedImage) {
m_accessedImage = true;
diff --git a/WebCore/css/CSSImageValue.h b/WebCore/css/CSSImageValue.h
index 4205c4f..a9c8c9b 100644
--- a/WebCore/css/CSSImageValue.h
+++ b/WebCore/css/CSSImageValue.h
@@ -27,7 +27,7 @@
namespace WebCore {
-class DocLoader;
+class CachedResourceLoader;
class StyleCachedImage;
class StyleImage;
@@ -37,7 +37,7 @@ public:
static PassRefPtr<CSSImageValue> create(const String& url) { return adoptRef(new CSSImageValue(url)); }
virtual ~CSSImageValue();
- virtual StyleCachedImage* cachedImage(DocLoader*);
+ virtual StyleCachedImage* cachedImage(CachedResourceLoader*);
// Returns a StyleCachedImage if the image is cached already, otherwise a StylePendingImage.
StyleImage* cachedOrPendingImage();
@@ -46,7 +46,7 @@ public:
protected:
CSSImageValue(const String& url);
- StyleCachedImage* cachedImage(DocLoader*, const String& url);
+ StyleCachedImage* cachedImage(CachedResourceLoader*, const String& url);
String cachedImageURL();
void clearCachedImage();
diff --git a/WebCore/css/CSSImportRule.cpp b/WebCore/css/CSSImportRule.cpp
index cc6083e..192f44e 100644
--- a/WebCore/css/CSSImportRule.cpp
+++ b/WebCore/css/CSSImportRule.cpp
@@ -23,7 +23,7 @@
#include "CSSImportRule.h"
#include "CachedCSSStyleSheet.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "SecurityOrigin.h"
#include "Settings.h"
@@ -115,8 +115,8 @@ void CSSImportRule::insertedIntoParent()
if (!parentSheet)
return;
- DocLoader* docLoader = parentSheet->document()->docLoader();
- if (!docLoader)
+ CachedResourceLoader* cachedResourceLoader = parentSheet->document()->cachedResourceLoader();
+ if (!cachedResourceLoader)
return;
String absHref = m_strHref;
@@ -135,9 +135,9 @@ void CSSImportRule::insertedIntoParent()
}
if (parentSheet->isUserStyleSheet())
- m_cachedSheet = docLoader->requestUserCSSStyleSheet(absHref, parentSheet->charset());
+ m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(absHref, parentSheet->charset());
else
- m_cachedSheet = docLoader->requestCSSStyleSheet(absHref, parentSheet->charset());
+ m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(absHref, parentSheet->charset());
if (m_cachedSheet) {
// if the import rule is issued dynamically, the sheet may be
// removed from the pending sheet count, so let the doc know
diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp
index 5455eed..8398bd0 100644
--- a/WebCore/css/CSSParser.cpp
+++ b/WebCore/css/CSSParser.cpp
@@ -176,8 +176,6 @@ CSSParser::~CSSParser()
fastFree(m_data);
- if (m_floatingMediaQueryExpList)
- deleteAllValues(*m_floatingMediaQueryExpList);
fastDeleteAllValues(m_floatingSelectors);
deleteAllValues(m_floatingValueLists);
deleteAllValues(m_floatingFunctions);
@@ -2877,7 +2875,7 @@ void CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<C
m_valueList->next();
}
-bool CSSParser::parseTimingFunctionValue(CSSParserValueList*& args, double& result)
+bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result)
{
CSSParserValue* v = args->current();
if (!validUnit(v, FNumber, m_strict))
@@ -2898,31 +2896,67 @@ bool CSSParser::parseTimingFunctionValue(CSSParserValueList*& args, double& resu
PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction()
{
CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut || value->id == CSSValueEaseInOut)
+ if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
+ || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd)
return CSSPrimitiveValue::createIdentifier(value->id);
// We must be a function.
if (value->unit != CSSParserValue::Function)
return 0;
- // The only timing function we accept for now is a cubic bezier function. 4 points must be specified.
CSSParserValueList* args = value->function->args.get();
- if (!equalIgnoringCase(value->function->name, "cubic-bezier(") || !args || args->size() != 7)
- return 0;
- // There are two points specified. The values must be between 0 and 1.
- double x1, y1, x2, y2;
+ if (equalIgnoringCase(value->function->name, "steps(")) {
+ // For steps, 1 or 2 params must be specified (comma-separated)
+ if (!args || (args->size() != 1 && args->size() != 3))
+ return 0;
- if (!parseTimingFunctionValue(args, x1))
- return 0;
- if (!parseTimingFunctionValue(args, y1))
- return 0;
- if (!parseTimingFunctionValue(args, x2))
- return 0;
- if (!parseTimingFunctionValue(args, y2))
- return 0;
+ // There are two values.
+ int numSteps;
+ bool stepAtStart = false;
- return CSSTimingFunctionValue::create(x1, y1, x2, y2);
+ CSSParserValue* v = args->current();
+ if (!validUnit(v, FInteger, m_strict))
+ return 0;
+ numSteps = (int) min(v->fValue, (double)INT_MAX);
+ if (numSteps < 1)
+ return 0;
+ v = args->next();
+
+ if (v) {
+ // There is a comma so we need to parse the second value
+ if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+ return 0;
+ v = args->next();
+ if (v->id != CSSValueStart && v->id != CSSValueEnd)
+ return 0;
+ stepAtStart = v->id == CSSValueStart;
+ }
+
+ return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart);
+ }
+
+ if (equalIgnoringCase(value->function->name, "cubic-bezier(")) {
+ // For cubic bezier, 4 values must be specified.
+ if (!args || args->size() != 7)
+ return 0;
+
+ // There are two points specified. The values must be between 0 and 1.
+ double x1, y1, x2, y2;
+
+ if (!parseCubicBezierTimingFunctionValue(args, x1))
+ return 0;
+ if (!parseCubicBezierTimingFunctionValue(args, y1))
+ return 0;
+ if (!parseCubicBezierTimingFunctionValue(args, x2))
+ return 0;
+ if (!parseCubicBezierTimingFunctionValue(args, y2))
+ return 0;
+
+ return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
+ }
+
+ return 0;
}
bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result)
@@ -5364,7 +5398,7 @@ CSSParserValue& CSSParser::sinkFloatingValue(CSSParserValue& value)
MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values)
{
- m_floatingMediaQueryExp = adoptPtr(new MediaQueryExp(mediaFeature, values));
+ m_floatingMediaQueryExp = MediaQueryExp::create(mediaFeature, values);
return m_floatingMediaQueryExp.get();
}
@@ -5374,27 +5408,25 @@ PassOwnPtr<MediaQueryExp> CSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* ex
return m_floatingMediaQueryExp.release();
}
-Vector<MediaQueryExp*>* CSSParser::createFloatingMediaQueryExpList()
+Vector<OwnPtr<MediaQueryExp> >* CSSParser::createFloatingMediaQueryExpList()
{
- if (m_floatingMediaQueryExpList)
- deleteAllValues(*m_floatingMediaQueryExpList);
- m_floatingMediaQueryExpList = adoptPtr(new Vector<MediaQueryExp*>);
+ m_floatingMediaQueryExpList = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
return m_floatingMediaQueryExpList.get();
}
-PassOwnPtr<Vector<MediaQueryExp*> > CSSParser::sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>* list)
+PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > CSSParser::sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >* list)
{
ASSERT_UNUSED(list, list == m_floatingMediaQueryExpList);
return m_floatingMediaQueryExpList.release();
}
-MediaQuery* CSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const String& mediaType, PassOwnPtr<Vector<MediaQueryExp*> > expressions)
+MediaQuery* CSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const String& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
{
m_floatingMediaQuery = adoptPtr(new MediaQuery(restrictor, mediaType, expressions));
return m_floatingMediaQuery.get();
}
-MediaQuery* CSSParser::createFloatingMediaQuery(PassOwnPtr<Vector<MediaQueryExp*> > expressions)
+MediaQuery* CSSParser::createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
{
return createFloatingMediaQuery(MediaQuery::None, "all", expressions);
}
diff --git a/WebCore/css/CSSParser.h b/WebCore/css/CSSParser.h
index 6211e62..47f0bed 100644
--- a/WebCore/css/CSSParser.h
+++ b/WebCore/css/CSSParser.h
@@ -108,7 +108,7 @@ namespace WebCore {
PassRefPtr<CSSValue> parseAnimationTimingFunction();
void parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- bool parseTimingFunctionValue(CSSParserValueList*& args, double& result);
+ bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
bool parseAnimationProperty(int propId, RefPtr<CSSValue>&);
bool parseTransitionShorthand(bool important);
bool parseAnimationShorthand(bool important);
@@ -195,10 +195,10 @@ namespace WebCore {
MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
PassOwnPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
- Vector<MediaQueryExp*>* createFloatingMediaQueryExpList();
- PassOwnPtr<Vector<MediaQueryExp*> > sinkFloatingMediaQueryExpList(Vector<MediaQueryExp*>*);
- MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const String&, PassOwnPtr<Vector<MediaQueryExp*> >);
- MediaQuery* createFloatingMediaQuery(PassOwnPtr<Vector<MediaQueryExp*> >);
+ Vector<OwnPtr<MediaQueryExp> >* createFloatingMediaQueryExpList();
+ PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >*);
+ MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const String&, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
+ MediaQuery* createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
void addNamespace(const AtomicString& prefix, const AtomicString& uri);
@@ -303,7 +303,7 @@ namespace WebCore {
OwnPtr<MediaQuery> m_floatingMediaQuery;
OwnPtr<MediaQueryExp> m_floatingMediaQueryExp;
- OwnPtr<Vector<MediaQueryExp*> > m_floatingMediaQueryExpList;
+ OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_floatingMediaQueryExpList;
Vector<CSSSelector*> m_reusableSelectorVector;
diff --git a/WebCore/css/CSSPrimitiveValue.cpp b/WebCore/css/CSSPrimitiveValue.cpp
index b4478b4..5c83e7c 100644
--- a/WebCore/css/CSSPrimitiveValue.cpp
+++ b/WebCore/css/CSSPrimitiveValue.cpp
@@ -305,82 +305,34 @@ void CSSPrimitiveValue::cleanup()
int CSSPrimitiveValue::computeLengthInt(RenderStyle* style, RenderStyle* rootStyle)
{
- double result = computeLengthDouble(style, rootStyle);
-
- // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
- // need to go ahead and round if we're really close to the next integer value.
- result += result < 0 ? -0.01 : +0.01;
-
- if (result > INT_MAX || result < INT_MIN)
- return 0;
- return static_cast<int>(result);
+ return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(computeLengthDouble(style, rootStyle));
}
int CSSPrimitiveValue::computeLengthInt(RenderStyle* style, RenderStyle* rootStyle, double multiplier)
{
- double result = computeLengthDouble(style, rootStyle, multiplier);
-
- // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
- // need to go ahead and round if we're really close to the next integer value.
- result += result < 0 ? -0.01 : +0.01;
-
- if (result > INT_MAX || result < INT_MIN)
- return 0;
- return static_cast<int>(result);
+ return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(computeLengthDouble(style, rootStyle, multiplier));
}
-// Lengths expect an int that is only 28-bits, so we have to check for a different overflow.
+// Lengths expect an int that is only 28-bits, so we have to check for a
+// different overflow.
int CSSPrimitiveValue::computeLengthIntForLength(RenderStyle* style, RenderStyle* rootStyle)
{
- double result = computeLengthDouble(style, rootStyle);
-
- // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
- // need to go ahead and round if we're really close to the next integer value.
- result += result < 0 ? -0.01 : +0.01;
-
- if (result > intMaxForLength || result < intMinForLength)
- return 0;
- return static_cast<int>(result);
+ return roundForImpreciseConversion<int, intMaxForLength, intMinForLength>(computeLengthDouble(style, rootStyle));
}
-// Lengths expect an int that is only 28-bits, so we have to check for a different overflow.
int CSSPrimitiveValue::computeLengthIntForLength(RenderStyle* style, RenderStyle* rootStyle, double multiplier)
{
- double result = computeLengthDouble(style, rootStyle, multiplier);
-
- // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
- // need to go ahead and round if we're really close to the next integer value.
- result += result < 0 ? -0.01 : +0.01;
-
- if (result > intMaxForLength || result < intMinForLength)
- return 0;
- return static_cast<int>(result);
+ return roundForImpreciseConversion<int, intMaxForLength, intMinForLength>(computeLengthDouble(style, rootStyle, multiplier));
}
short CSSPrimitiveValue::computeLengthShort(RenderStyle* style, RenderStyle* rootStyle)
{
- double result = computeLengthDouble(style, rootStyle);
-
- // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
- // need to go ahead and round if we're really close to the next integer value.
- result += result < 0 ? -0.01 : +0.01;
-
- if (result > SHRT_MAX || result < SHRT_MIN)
- return 0;
- return static_cast<short>(result);
+ return roundForImpreciseConversion<short, SHRT_MAX, SHRT_MIN>(computeLengthDouble(style, rootStyle));
}
short CSSPrimitiveValue::computeLengthShort(RenderStyle* style, RenderStyle* rootStyle, double multiplier)
{
- double result = computeLengthDouble(style, rootStyle, multiplier);
-
- // This conversion is imprecise, often resulting in values of, e.g., 44.99998. We
- // need to go ahead and round if we're really close to the next integer value.
- result += result < 0 ? -0.01 : +0.01;
-
- if (result > SHRT_MAX || result < SHRT_MIN)
- return 0;
- return static_cast<short>(result);
+ return roundForImpreciseConversion<short, SHRT_MAX, SHRT_MIN>(computeLengthDouble(style, rootStyle, multiplier));
}
float CSSPrimitiveValue::computeLengthFloat(RenderStyle* style, RenderStyle* rootStyle, bool computingFontSize)
diff --git a/WebCore/css/CSSPrimitiveValue.h b/WebCore/css/CSSPrimitiveValue.h
index b11c7f0..bb3ea70 100644
--- a/WebCore/css/CSSPrimitiveValue.h
+++ b/WebCore/css/CSSPrimitiveValue.h
@@ -38,6 +38,15 @@ class RenderStyle;
struct Length;
+template<typename T, T max, T min> inline T roundForImpreciseConversion(double value)
+{
+ // Dimension calculations are imprecise, often resulting in values of e.g.
+ // 44.99998. We need to go ahead and round if we're really close to the
+ // next integer value.
+ value += (value < 0) ? -0.01 : +0.01;
+ return ((value > max) || (value < min)) ? 0 : static_cast<T>(value);
+}
+
class CSSPrimitiveValue : public CSSValue {
public:
enum UnitTypes {
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index a75dede..60dfb84 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -2576,7 +2576,7 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
if (!e)
return false;
e->document()->setContainsValidityStyleRules();
- return e->willValidate() && !e->isValidFormControlElement();
+ return (e->willValidate() && !e->isValidFormControlElement()) || e->hasUnacceptableValue();
} case CSSSelector::PseudoChecked: {
if (!e || !e->isFormControlElement())
break;
@@ -6203,19 +6203,25 @@ void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
switch (primitiveValue->getIdent()) {
case CSSValueLinear:
- animation->setTimingFunction(TimingFunction(LinearTimingFunction, 0.0, 0.0, 1.0, 1.0));
+ animation->setTimingFunction(LinearTimingFunction::create());
break;
case CSSValueEase:
- animation->setTimingFunction(TimingFunction());
+ animation->setTimingFunction(CubicBezierTimingFunction::create());
break;
case CSSValueEaseIn:
- animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.42, 0.0, 1.0, 1.0));
+ animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0));
break;
case CSSValueEaseOut:
- animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.0, 0.0, 0.58, 1.0));
+ animation->setTimingFunction(CubicBezierTimingFunction::create(0.0, 0.0, 0.58, 1.0));
break;
case CSSValueEaseInOut:
- animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.42, 0.0, 0.58, 1.0));
+ animation->setTimingFunction(CubicBezierTimingFunction::create(0.42, 0.0, 0.58, 1.0));
+ break;
+ case CSSValueStepStart:
+ animation->setTimingFunction(StepsTimingFunction::create(1, true));
+ break;
+ case CSSValueStepEnd:
+ animation->setTimingFunction(StepsTimingFunction::create(1, false));
break;
}
return;
@@ -6223,7 +6229,14 @@ void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue
if (value->isTimingFunctionValue()) {
CSSTimingFunctionValue* timingFunction = static_cast<CSSTimingFunctionValue*>(value);
- animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, timingFunction->x1(), timingFunction->y1(), timingFunction->x2(), timingFunction->y2()));
+ if (timingFunction->isCubicBezierTimingFunctionValue()) {
+ CSSCubicBezierTimingFunctionValue* cubicTimingFunction = static_cast<CSSCubicBezierTimingFunctionValue*>(value);
+ animation->setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2()));
+ } else if (timingFunction->isStepsTimingFunctionValue()) {
+ CSSStepsTimingFunctionValue* stepsTimingFunction = static_cast<CSSStepsTimingFunctionValue*>(value);
+ animation->setTimingFunction(StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart()));
+ } else
+ animation->setTimingFunction(LinearTimingFunction::create());
}
}
@@ -6442,14 +6455,14 @@ static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][to
// factors for each keyword value.
static const float fontSizeFactors[totalKeywords] = { 0.60f, 0.75f, 0.89f, 1.0f, 1.2f, 1.5f, 2.0f, 3.0f };
-float CSSStyleSelector::fontSizeForKeyword(Document* document, int keyword, bool fixed)
+float CSSStyleSelector::fontSizeForKeyword(Document* document, int keyword, bool shouldUseFixedDefaultSize)
{
Settings* settings = document->settings();
if (!settings)
return 1.0f;
bool quirksMode = document->inQuirksMode();
- int mediumSize = fixed ? settings->defaultFixedFontSize() : settings->defaultFontSize();
+ int mediumSize = shouldUseFixedDefaultSize ? settings->defaultFixedFontSize() : settings->defaultFontSize();
if (mediumSize >= fontSizeTableMin && mediumSize <= fontSizeTableMax) {
// Look up the entry in the table.
int row = mediumSize - fontSizeTableMin;
@@ -6462,6 +6475,33 @@ float CSSStyleSelector::fontSizeForKeyword(Document* document, int keyword, bool
return max(fontSizeFactors[keyword - CSSValueXxSmall]*mediumSize, minLogicalSize);
}
+template<typename T>
+static int findNearestLegacyFontSize(int pixelFontSize, const T* table, int multiplier)
+{
+ // Ignore table[0] because xx-small does not correspond to any legacy font size.
+ for (int i = 1; i < totalKeywords - 1; i++) {
+ if (pixelFontSize * 2 < (table[i] + table[i + 1]) * multiplier)
+ return i;
+ }
+ return totalKeywords - 1;
+}
+
+int CSSStyleSelector::legacyFontSize(Document* document, int pixelFontSize, bool shouldUseFixedDefaultSize)
+{
+ Settings* settings = document->settings();
+ if (!settings)
+ return 1;
+
+ bool quirksMode = document->inQuirksMode();
+ int mediumSize = shouldUseFixedDefaultSize ? settings->defaultFixedFontSize() : settings->defaultFontSize();
+ if (mediumSize >= fontSizeTableMin && mediumSize <= fontSizeTableMax) {
+ int row = mediumSize - fontSizeTableMin;
+ return findNearestLegacyFontSize<int>(pixelFontSize, quirksMode ? quirksFontSizeTable[row] : strictFontSizeTable[row], 1);
+ }
+
+ return findNearestLegacyFontSize<float>(pixelFontSize, fontSizeFactors, mediumSize);
+}
+
float CSSStyleSelector::largerFontSize(float size, bool) const
{
// FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale up to
@@ -6855,14 +6895,14 @@ void CSSStyleSelector::loadPendingImages()
for (HashSet<int>::const_iterator it = m_pendingImageProperties.begin(); it != end; ++it) {
CSSPropertyID currentProperty = static_cast<CSSPropertyID>(*it);
- DocLoader* docLoader = m_element->document()->docLoader();
+ CachedResourceLoader* cachedResourceLoader = m_element->document()->cachedResourceLoader();
switch (currentProperty) {
case CSSPropertyBackgroundImage: {
for (FillLayer* backgroundLayer = m_style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(backgroundLayer->image())->cssImageValue();
- backgroundLayer->setImage(imageValue->cachedImage(docLoader));
+ backgroundLayer->setImage(imageValue->cachedImage(cachedResourceLoader));
}
}
break;
@@ -6872,7 +6912,7 @@ void CSSStyleSelector::loadPendingImages()
for (ContentData* contentData = const_cast<ContentData*>(m_style->contentData()); contentData; contentData = contentData->next()) {
if (contentData->isImage() && contentData->image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(contentData->image())->cssImageValue();
- contentData->setImage(imageValue->cachedImage(docLoader));
+ contentData->setImage(imageValue->cachedImage(cachedResourceLoader));
}
}
break;
@@ -6884,7 +6924,7 @@ void CSSStyleSelector::loadPendingImages()
CursorData& currentCursor = (*cursorList)[i];
if (currentCursor.image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(currentCursor.image())->cssImageValue();
- currentCursor.setImage(imageValue->cachedImage(docLoader));
+ currentCursor.setImage(imageValue->cachedImage(cachedResourceLoader));
}
}
}
@@ -6894,7 +6934,7 @@ void CSSStyleSelector::loadPendingImages()
case CSSPropertyListStyleImage: {
if (m_style->listStyleImage() && m_style->listStyleImage()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(m_style->listStyleImage())->cssImageValue();
- m_style->setListStyleImage(imageValue->cachedImage(docLoader));
+ m_style->setListStyleImage(imageValue->cachedImage(cachedResourceLoader));
}
break;
}
@@ -6903,7 +6943,7 @@ void CSSStyleSelector::loadPendingImages()
const NinePieceImage& borderImage = m_style->borderImage();
if (borderImage.image() && borderImage.image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(borderImage.image())->cssImageValue();
- m_style->setBorderImage(NinePieceImage(imageValue->cachedImage(docLoader), borderImage.slices(), borderImage.horizontalRule(), borderImage.verticalRule()));
+ m_style->setBorderImage(NinePieceImage(imageValue->cachedImage(cachedResourceLoader), borderImage.slices(), borderImage.horizontalRule(), borderImage.verticalRule()));
}
break;
}
@@ -6912,7 +6952,7 @@ void CSSStyleSelector::loadPendingImages()
const NinePieceImage& maskImage = m_style->boxReflect()->mask();
if (maskImage.image() && maskImage.image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskImage.image())->cssImageValue();
- m_style->boxReflect()->setMask(NinePieceImage(imageValue->cachedImage(docLoader), maskImage.slices(), maskImage.horizontalRule(), maskImage.verticalRule()));
+ m_style->boxReflect()->setMask(NinePieceImage(imageValue->cachedImage(cachedResourceLoader), maskImage.slices(), maskImage.horizontalRule(), maskImage.verticalRule()));
}
break;
}
@@ -6921,7 +6961,7 @@ void CSSStyleSelector::loadPendingImages()
const NinePieceImage& maskBoxImage = m_style->maskBoxImage();
if (maskBoxImage.image() && maskBoxImage.image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskBoxImage.image())->cssImageValue();
- m_style->setMaskBoxImage(NinePieceImage(imageValue->cachedImage(docLoader), maskBoxImage.slices(), maskBoxImage.horizontalRule(), maskBoxImage.verticalRule()));
+ m_style->setMaskBoxImage(NinePieceImage(imageValue->cachedImage(cachedResourceLoader), maskBoxImage.slices(), maskBoxImage.horizontalRule(), maskBoxImage.verticalRule()));
}
break;
}
@@ -6930,7 +6970,7 @@ void CSSStyleSelector::loadPendingImages()
for (FillLayer* maskLayer = m_style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
if (maskLayer->image() && maskLayer->image()->isPendingImage()) {
CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskLayer->image())->cssImageValue();
- maskLayer->setImage(imageValue->cachedImage(docLoader));
+ maskLayer->setImage(imageValue->cachedImage(cachedResourceLoader));
}
}
break;
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
index 28d4488..4a4565d 100644
--- a/WebCore/css/CSSStyleSelector.h
+++ b/WebCore/css/CSSStyleSelector.h
@@ -122,10 +122,14 @@ public:
PassRefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly);
PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, bool authorOnly);
- private:
// Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
// the correct font size scaled relative to the user's default (medium).
- static float fontSizeForKeyword(Document*, int keyword, bool monospace);
+ static float fontSizeForKeyword(Document*, int keyword, bool shouldUseFixedDefaultSize);
+
+ // Given a font size in pixel, this function will return legacy font size between 1 and 7.
+ static int legacyFontSize(Document*, int pixelFontSize, bool shouldUseFixedDefaultSize);
+
+ private:
// When the CSS keyword "larger" is used, this function will attempt to match within the keyword
// table, and failing that, will simply multiply by 1.2.
diff --git a/WebCore/css/CSSStyleSheet.h b/WebCore/css/CSSStyleSheet.h
index 3b18522..725518f 100644
--- a/WebCore/css/CSSStyleSheet.h
+++ b/WebCore/css/CSSStyleSheet.h
@@ -29,7 +29,7 @@ namespace WebCore {
struct CSSNamespace;
class CSSParser;
class CSSRule;
-class DocLoader;
+class CachedResourceLoader;
class Document;
typedef int ExceptionCode;
diff --git a/WebCore/css/CSSTimingFunctionValue.cpp b/WebCore/css/CSSTimingFunctionValue.cpp
index e576d36..9eecb2c 100644
--- a/WebCore/css/CSSTimingFunctionValue.cpp
+++ b/WebCore/css/CSSTimingFunctionValue.cpp
@@ -30,7 +30,12 @@
namespace WebCore {
-String CSSTimingFunctionValue::cssText() const
+String CSSLinearTimingFunctionValue::cssText() const
+{
+ return "linear";
+}
+
+String CSSCubicBezierTimingFunctionValue::cssText() const
{
String text("cubic-bezier(");
text += String::number(m_x1);
@@ -44,4 +49,14 @@ String CSSTimingFunctionValue::cssText() const
return text;
}
+String CSSStepsTimingFunctionValue::cssText() const
+{
+ String text("steps(");
+ text += String::number(m_steps);
+ text += ", ";
+ text += m_stepAtStart ? "start" : "end";
+ text += ")";
+ return text;
+}
+
} // namespace WebCore
diff --git a/WebCore/css/CSSTimingFunctionValue.h b/WebCore/css/CSSTimingFunctionValue.h
index e465993..27e899b 100644
--- a/WebCore/css/CSSTimingFunctionValue.h
+++ b/WebCore/css/CSSTimingFunctionValue.h
@@ -33,20 +33,51 @@ namespace WebCore {
class CSSTimingFunctionValue : public CSSValue {
public:
- static PassRefPtr<CSSTimingFunctionValue> create(double x1, double y1, double x2, double y2)
+ virtual String cssText() const = 0;
+
+ virtual bool isLinearTimingFunctionValue() const { return false; }
+ virtual bool isCubicBezierTimingFunctionValue() const { return false; }
+ virtual bool isStepsTimingFunctionValue() const { return false; }
+
+protected:
+ CSSTimingFunctionValue()
+ {
+ }
+
+ virtual bool isTimingFunctionValue() const { return true; }
+};
+
+class CSSLinearTimingFunctionValue : public CSSTimingFunctionValue {
+public:
+ static PassRefPtr<CSSLinearTimingFunctionValue> create()
+ {
+ return adoptRef(new CSSLinearTimingFunctionValue);
+ }
+
+private:
+ CSSLinearTimingFunctionValue()
{
- return adoptRef(new CSSTimingFunctionValue(x1, y1, x2, y2));
}
virtual String cssText() const;
+ virtual bool isLinearTimingFunctionValue() const { return true; }
+};
+
+class CSSCubicBezierTimingFunctionValue : public CSSTimingFunctionValue {
+public:
+ static PassRefPtr<CSSCubicBezierTimingFunctionValue> create(double x1, double y1, double x2, double y2)
+ {
+ return adoptRef(new CSSCubicBezierTimingFunctionValue(x1, y1, x2, y2));
+ }
+
double x1() const { return m_x1; }
double y1() const { return m_y1; }
double x2() const { return m_x2; }
double y2() const { return m_y2; }
private:
- CSSTimingFunctionValue(double x1, double y1, double x2, double y2)
+ CSSCubicBezierTimingFunctionValue(double x1, double y1, double x2, double y2)
: m_x1(x1)
, m_y1(y1)
, m_x2(x2)
@@ -54,14 +85,41 @@ private:
{
}
- virtual bool isTimingFunctionValue() const { return true; }
-
+ virtual String cssText() const;
+
+ virtual bool isCubicBezierTimingFunctionValue() const { return true; }
+
double m_x1;
double m_y1;
double m_x2;
double m_y2;
};
+class CSSStepsTimingFunctionValue : public CSSTimingFunctionValue {
+public:
+ static PassRefPtr<CSSStepsTimingFunctionValue> create(int steps, bool stepAtStart)
+ {
+ return adoptRef(new CSSStepsTimingFunctionValue(steps, stepAtStart));
+ }
+
+ int numberOfSteps() const { return m_steps; }
+ bool stepAtStart() const { return m_stepAtStart; }
+
+private:
+ CSSStepsTimingFunctionValue(int steps, bool stepAtStart)
+ : m_steps(steps)
+ , m_stepAtStart(stepAtStart)
+ {
+ }
+
+ virtual String cssText() const;
+
+ virtual bool isStepsTimingFunctionValue() const { return true; }
+
+ int m_steps;
+ bool m_stepAtStart;
+};
+
} // namespace
#endif
diff --git a/WebCore/css/CSSValueKeywords.in b/WebCore/css/CSSValueKeywords.in
index 7a9b9c7..1e7c2b5 100644
--- a/WebCore/css/CSSValueKeywords.in
+++ b/WebCore/css/CSSValueKeywords.in
@@ -691,6 +691,8 @@ linear
ease-in
ease-out
ease-in-out
+step-start
+step-end
#
# CSS_PROP_ZOOM
diff --git a/WebCore/css/MediaList.cpp b/WebCore/css/MediaList.cpp
index e67c9c7..81f8712 100644
--- a/WebCore/css/MediaList.cpp
+++ b/WebCore/css/MediaList.cpp
@@ -25,6 +25,7 @@
#include "CSSStyleSheet.h"
#include "ExceptionCode.h"
#include "MediaQuery.h"
+#include "MediaQueryExp.h"
namespace WebCore {
diff --git a/WebCore/css/MediaQuery.cpp b/WebCore/css/MediaQuery.cpp
index b71706c..77a79ad 100644
--- a/WebCore/css/MediaQuery.cpp
+++ b/WebCore/css/MediaQuery.cpp
@@ -31,8 +31,7 @@
#include "MediaQueryExp.h"
#include "StringBuilder.h"
-
-#include <algorithm>
+#include <wtf/NonCopyingSort.h>
namespace WebCore {
@@ -70,23 +69,24 @@ String MediaQuery::serialize() const
return result.toString();
}
-static bool expressionCompare(const MediaQueryExp* a, const MediaQueryExp* b)
+static bool expressionCompare(const OwnPtr<MediaQueryExp>& a, const OwnPtr<MediaQueryExp>& b)
{
return codePointCompare(a->serialize(), b->serialize()) < 0;
}
-MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtr<Vector<MediaQueryExp*> > exprs)
+
+MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > exprs)
: m_restrictor(r)
, m_mediaType(mediaType.lower())
, m_expressions(exprs)
, m_ignored(false)
{
if (!m_expressions) {
- m_expressions = new Vector<MediaQueryExp*>;
+ m_expressions = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
return;
}
- std::sort(m_expressions->begin(), m_expressions->end(), expressionCompare);
+ nonCopyingSort(m_expressions->begin(), m_expressions->end(), expressionCompare);
// remove all duplicated expressions
String key;
@@ -95,19 +95,16 @@ MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtr<Vector<
// if not all of the expressions is valid the media query must be ignored.
if (!m_ignored)
m_ignored = !m_expressions->at(i)->isValid();
-
- if (m_expressions->at(i)->serialize() == key) {
- MediaQueryExp* item = m_expressions->at(i);
+
+ if (m_expressions->at(i)->serialize() == key)
m_expressions->remove(i);
- delete item;
- } else
+ else
key = m_expressions->at(i)->serialize();
}
}
MediaQuery::~MediaQuery()
{
- deleteAllValues(*m_expressions);
}
// http://dev.w3.org/csswg/cssom/#compare-media-queries
diff --git a/WebCore/css/MediaQuery.h b/WebCore/css/MediaQuery.h
index 3eea3b2..281009b 100644
--- a/WebCore/css/MediaQuery.h
+++ b/WebCore/css/MediaQuery.h
@@ -43,11 +43,11 @@ public:
Only, Not, None
};
- MediaQuery(Restrictor, const String& mediaType, PassOwnPtr<Vector<MediaQueryExp*> > exprs);
+ MediaQuery(Restrictor, const String& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > exprs);
~MediaQuery();
Restrictor restrictor() const { return m_restrictor; }
- const Vector<MediaQueryExp*>* expressions() const { return m_expressions.get(); }
+ const Vector<OwnPtr<MediaQueryExp> >* expressions() const { return m_expressions.get(); }
String mediaType() const { return m_mediaType; }
bool operator==(const MediaQuery& other) const;
String cssText() const;
@@ -56,7 +56,7 @@ public:
private:
Restrictor m_restrictor;
String m_mediaType;
- OwnPtr<Vector<MediaQueryExp*> > m_expressions;
+ OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_expressions;
bool m_ignored;
String m_serializationCache;
diff --git a/WebCore/css/MediaQueryEvaluator.cpp b/WebCore/css/MediaQueryEvaluator.cpp
index 0b5507e..c757d51 100644
--- a/WebCore/css/MediaQueryEvaluator.cpp
+++ b/WebCore/css/MediaQueryEvaluator.cpp
@@ -148,14 +148,14 @@ bool MediaQueryEvaluator::eval(const MediaList* mediaList, CSSStyleSelector* sty
continue;
if (mediaTypeMatch(query->mediaType())) {
- const Vector<MediaQueryExp*>* exps = query->expressions();
+ const Vector<OwnPtr<MediaQueryExp> >* exps = query->expressions();
// iterate through expressions, stop if any of them eval to false
// (AND semantics)
size_t j = 0;
for (; j < exps->size(); ++j) {
- bool exprResult = eval(exps->at(j));
+ bool exprResult = eval(exps->at(j).get());
if (styleSelector && exps->at(j)->isViewportDependent())
- styleSelector->addViewportDependentMediaQueryResult(exps->at(j), exprResult);
+ styleSelector->addViewportDependentMediaQueryResult(exps->at(j).get(), exprResult);
if (!exprResult)
break;
}
diff --git a/WebCore/css/MediaQueryExp.cpp b/WebCore/css/MediaQueryExp.cpp
index a93ddcc..36a155e 100644
--- a/WebCore/css/MediaQueryExp.cpp
+++ b/WebCore/css/MediaQueryExp.cpp
@@ -36,7 +36,7 @@
namespace WebCore {
-MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList)
+inline MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList)
: m_mediaFeature(mediaFeature)
, m_value(0)
, m_isValid(true)
@@ -80,6 +80,12 @@ MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueLis
}
}
+
+PassOwnPtr<MediaQueryExp> MediaQueryExp::create(const AtomicString& mediaFeature, CSSParserValueList* values)
+{
+ return adoptPtr(new MediaQueryExp(mediaFeature, values));
+}
+
MediaQueryExp::~MediaQueryExp()
{
}
diff --git a/WebCore/css/MediaQueryExp.h b/WebCore/css/MediaQueryExp.h
index 4b42611..72d3fff 100644
--- a/WebCore/css/MediaQueryExp.h
+++ b/WebCore/css/MediaQueryExp.h
@@ -31,6 +31,7 @@
#include "CSSValue.h"
#include "MediaFeatureNames.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/text/AtomicString.h>
@@ -39,7 +40,7 @@ class CSSParserValueList;
class MediaQueryExp : public FastAllocBase {
public:
- MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values);
+ static PassOwnPtr<MediaQueryExp> create(const AtomicString& mediaFeature, CSSParserValueList* values);
~MediaQueryExp();
AtomicString mediaFeature() const { return m_mediaFeature; }
@@ -69,6 +70,8 @@ public:
String serialize() const;
private:
+ MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values);
+
AtomicString m_mediaFeature;
RefPtr<CSSValue> m_value;
bool m_isValid;
diff --git a/WebCore/css/mathml.css b/WebCore/css/mathml.css
index a5df17c..7cf9866 100644
--- a/WebCore/css/mathml.css
+++ b/WebCore/css/mathml.css
@@ -16,6 +16,9 @@ math[display="block"] {
display: block;
page-break-inside: avoid;
margin-bottom: 1em;
+ text-align: center;
+ margin-left: auto;
+ margin-right: auto;
}
math > * {
diff --git a/WebCore/css/tokenizer.flex b/WebCore/css/tokenizer.flex
index 290c590..4d226d9 100644
--- a/WebCore/css/tokenizer.flex
+++ b/WebCore/css/tokenizer.flex
@@ -13,7 +13,6 @@ nmstart [_a-zA-Z]|{nonascii}|{escape}
nmchar [_a-zA-Z0-9-]|{nonascii}|{escape}
string1 \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\"
string2 \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\'
-hexcolor {h}{3}|{h}{6}
ident -?{nmstart}{nmchar}*
name {nmchar}+
@@ -48,8 +47,8 @@ nth [\+-]?{intnum}*n([\+-]{intnum})?
{ident} {yyTok = IDENT; return yyTok;}
{nth} {yyTok = NTH; return yyTok;}
-"#"{hexcolor} {yyTok = HEX; return yyTok;}
"#"{ident} {yyTok = IDSEL; return yyTok;}
+"#"{name} {yyTok = HEX; return yyTok;}
"@import" {BEGIN(mediaquery); yyTok = IMPORT_SYM; return yyTok;}
"@page" {yyTok = PAGE_SYM; return yyTok;}
diff --git a/WebCore/dom/AsyncScriptRunner.cpp b/WebCore/dom/AsyncScriptRunner.cpp
index 96036a1..86251b8 100644
--- a/WebCore/dom/AsyncScriptRunner.cpp
+++ b/WebCore/dom/AsyncScriptRunner.cpp
@@ -27,20 +27,25 @@
#include "AsyncScriptRunner.h"
#include "CachedScript.h"
+#include "Document.h"
#include "Element.h"
#include "ScriptElement.h"
namespace WebCore {
-AsyncScriptRunner::AsyncScriptRunner()
- : m_timer(this, &AsyncScriptRunner::timerFired)
+AsyncScriptRunner::AsyncScriptRunner(Document* document)
+ : m_document(document)
+ , m_timer(this, &AsyncScriptRunner::timerFired)
{
+ ASSERT(document);
}
AsyncScriptRunner::~AsyncScriptRunner()
{
- for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i)
- m_scriptsToExecuteSoon[i].first->element()->deref(); // Balances ref() in executeScriptSoon().
+ for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i) {
+ m_scriptsToExecuteSoon[i].first->element()->deref(); // Balances ref() in executeScriptSoon().
+ m_document->decrementLoadEventDelayCount();
+ }
}
void AsyncScriptRunner::executeScriptSoon(ScriptElementData* data, CachedResourceHandle<CachedScript> cachedScript)
@@ -51,6 +56,7 @@ void AsyncScriptRunner::executeScriptSoon(ScriptElementData* data, CachedResourc
ASSERT(element);
ASSERT(element->inDocument());
+ m_document->incrementLoadEventDelayCount();
m_scriptsToExecuteSoon.append(make_pair(data, cachedScript));
element->ref(); // Balanced by deref()s in timerFired() and dtor.
if (!m_timer.isActive())
@@ -78,6 +84,7 @@ void AsyncScriptRunner::timerFired(Timer<AsyncScriptRunner>* timer)
for (size_t i = 0; i < size; ++i) {
scripts[i].first->execute(scripts[i].second.get());
scripts[i].first->element()->deref(); // Balances ref() in executeScriptSoon().
+ m_document->decrementLoadEventDelayCount();
}
}
diff --git a/WebCore/dom/AsyncScriptRunner.h b/WebCore/dom/AsyncScriptRunner.h
index 8b75e06..57bee84 100644
--- a/WebCore/dom/AsyncScriptRunner.h
+++ b/WebCore/dom/AsyncScriptRunner.h
@@ -35,11 +35,12 @@
namespace WebCore {
class CachedScript;
+class Document;
class ScriptElementData;
class AsyncScriptRunner : public Noncopyable {
public:
- static PassOwnPtr<AsyncScriptRunner> create() { return new AsyncScriptRunner(); }
+ static PassOwnPtr<AsyncScriptRunner> create(Document* document) { return new AsyncScriptRunner(document); }
~AsyncScriptRunner();
void executeScriptSoon(ScriptElementData*, CachedResourceHandle<CachedScript>);
@@ -48,10 +49,11 @@ public:
void resume();
private:
- AsyncScriptRunner();
+ AsyncScriptRunner(Document*);
void timerFired(Timer<AsyncScriptRunner>*);
+ Document* m_document;
Vector<std::pair<ScriptElementData*, CachedResourceHandle<CachedScript> > > m_scriptsToExecuteSoon;
Timer<AsyncScriptRunner> m_timer;
};
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 064d4e5..46de749 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -151,6 +151,8 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
if (child->parentNode())
break;
+ InspectorController::willInsertDOMNode(child, this);
+
insertBeforeCommon(next.get(), child);
// Send notification about the children change.
@@ -218,6 +220,8 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChil
for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); ++it) {
Node* child = it->get();
+ InspectorController::willInsertDOMNode(child, this);
+
insertBeforeCommon(next.get(), child);
childrenChanged(true, nextChildPreviousSibling.get(), nextChild, 1);
@@ -291,6 +295,8 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
ASSERT(!child->nextSibling());
ASSERT(!child->previousSibling());
+ InspectorController::willInsertDOMNode(child.get(), this);
+
// Add child after "prev".
forbidEventDispatch();
Node* next;
@@ -572,6 +578,8 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
break;
}
+ InspectorController::willInsertDOMNode(child, this);
+
// Append child to the end of the list
forbidEventDispatch();
child->setParent(this);
@@ -610,6 +618,8 @@ void ContainerNode::parserAddChild(PassRefPtr<Node> newChild)
ASSERT(newChild);
ASSERT(!newChild->parent()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
+ InspectorController::willInsertDOMNode(newChild.get(), this);
+
forbidEventDispatch();
Node* last = m_lastChild;
// FIXME: This method should take a PassRefPtr.
@@ -981,12 +991,7 @@ static void notifyChildInserted(Node* child)
{
ASSERT(!eventDispatchForbidden());
-#if ENABLE(INSPECTOR)
- if (Page* page = child->document()->page()) {
- if (InspectorController* inspectorController = page->inspectorController())
- inspectorController->didInsertDOMNode(child);
- }
-#endif
+ InspectorController::didInsertDOMNode(child);
RefPtr<Node> c = child;
RefPtr<Document> document = child->document();
@@ -1020,12 +1025,7 @@ static void dispatchChildRemovalEvents(Node* child)
{
ASSERT(!eventDispatchForbidden());
-#if ENABLE(INSPECTOR)
- if (Page* page = child->document()->page()) {
- if (InspectorController* inspectorController = page->inspectorController())
- inspectorController->didRemoveDOMNode(child);
- }
-#endif
+ InspectorController::willRemoveDOMNode(child);
RefPtr<Node> c = child;
RefPtr<Document> document = child->document();
diff --git a/WebCore/dom/DecodedDataDocumentParser.cpp b/WebCore/dom/DecodedDataDocumentParser.cpp
index 39bf8e4..975b1b5 100644
--- a/WebCore/dom/DecodedDataDocumentParser.cpp
+++ b/WebCore/dom/DecodedDataDocumentParser.cpp
@@ -32,9 +32,8 @@
namespace WebCore {
-DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document, bool viewSourceMode)
+DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document)
: DocumentParser(document)
- , m_inViewSourceMode(viewSourceMode)
{
}
diff --git a/WebCore/dom/DecodedDataDocumentParser.h b/WebCore/dom/DecodedDataDocumentParser.h
index f45bb68..40f3f19 100644
--- a/WebCore/dom/DecodedDataDocumentParser.h
+++ b/WebCore/dom/DecodedDataDocumentParser.h
@@ -36,11 +36,8 @@ public:
// XMLHttpRequest if the responseXML was well formed.
virtual bool wellFormed() const { return true; }
- bool inViewSourceMode() const { return m_inViewSourceMode; }
- void setInViewSourceMode(bool mode) { m_inViewSourceMode = mode; }
-
protected:
- DecodedDataDocumentParser(Document*, bool viewSourceMode = false);
+ explicit DecodedDataDocumentParser(Document*);
private:
// append is used by DocumentWriter::replaceDocument
@@ -48,8 +45,6 @@ private:
// appendBytes is used by DocumentWriter (the loader)
virtual void appendBytes(DocumentWriter*, const char* bytes, int length, bool flush);
-
- bool m_inViewSourceMode;
};
}
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 7fb8c34..a92c5ab 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -47,7 +47,7 @@
#include "DOMWindow.h"
#include "DeviceMotionEvent.h"
#include "DeviceOrientationEvent.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "DocumentFragment.h"
#include "DocumentLoader.h"
#include "DocumentType.h"
@@ -375,6 +375,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_compatibilityModeLocked(false)
, m_domTreeVersion(0)
, m_styleSheets(StyleSheetList::create(this))
+ , m_readyState(Complete)
, m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
, m_pendingStyleRecalcShouldForce(false)
, m_frameElementsShouldIgnoreScrolling(false)
@@ -388,7 +389,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
, m_startTime(currentTime())
, m_overMinimumLayoutThreshold(false)
, m_extraLayoutDelay(0)
- , m_asyncScriptRunner(AsyncScriptRunner::create())
+ , m_asyncScriptRunner(AsyncScriptRunner::create(this))
, m_xmlVersion("1.0")
, m_xmlStandalone(false)
, m_savedRenderer(0)
@@ -444,7 +445,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
m_markers = new DocumentMarkerController();
- m_docLoader = new DocLoader(this);
+ m_cachedResourceLoader = new CachedResourceLoader(this);
m_visuallyOrdered = false;
m_bParsing = false;
@@ -561,7 +562,7 @@ Document::~Document()
ASSERT(!m_parser || m_parser->refCount() == 1);
detachParser();
m_document = 0;
- m_docLoader.clear();
+ m_cachedResourceLoader.clear();
m_renderArena.clear();
@@ -982,18 +983,29 @@ Element* Document::getElementById(const AtomicString& elementId) const
String Document::readyState() const
{
- if (Frame* f = frame()) {
- if (f->loader()->isComplete())
- return "complete";
- if (parsing())
- return "loading";
- return "loaded";
- // FIXME: What does "interactive" mean?
- // FIXME: Missing support for "uninitialized".
+ DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
+ DEFINE_STATIC_LOCAL(const String, interactive, ("interactive"));
+ DEFINE_STATIC_LOCAL(const String, complete, ("complete"));
+
+ switch (m_readyState) {
+ case Loading:
+ return loading;
+ case Interactive:
+ return interactive;
+ case Complete:
+ return complete;
}
+
+ ASSERT_NOT_REACHED();
return String();
}
+void Document::setReadyState(ReadyState readyState)
+{
+ // FIXME: Fire the readystatechange event on this Document.
+ m_readyState = readyState;
+}
+
String Document::encoding() const
{
if (TextResourceDecoder* d = decoder())
@@ -1869,7 +1881,7 @@ void Document::open(Document* ownerDocument)
if (m_frame) {
ScriptableDocumentParser* parser = scriptableDocumentParser();
- if (m_frame->loader()->isLoadingMainResource() || (parser && parser->isExecutingScript()))
+ if (m_frame->loader()->isLoadingMainResource() || (parser && parser->isParsing() && parser->isExecutingScript()))
return;
if (m_frame->loader()->state() == FrameStateProvisional)
@@ -1915,6 +1927,7 @@ void Document::implicitOpen()
m_parser = createParser();
setParsing(true);
+ setReadyState(Loading);
ScriptableDocumentParser* parser = scriptableDocumentParser();
if (m_frame && parser)
@@ -2031,7 +2044,7 @@ void Document::implicitClose()
detachParser();
// Parser should have picked up all preloads by now
- m_docLoader->clearPreloads();
+ m_cachedResourceLoader->clearPreloads();
// Create a head and a body if we don't have those yet (e.g. for about:blank).
if (!this->body() && isHTMLDocument()) {
@@ -4162,6 +4175,8 @@ CollectionCache* Document::nameCollectionInfo(CollectionType type, const AtomicS
void Document::finishedParsing()
{
+ ASSERT(!scriptableDocumentParser() || !m_parser->isParsing());
+ ASSERT(!scriptableDocumentParser() || m_readyState != Loading);
setParsing(false);
dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index ac0c2a2..a8e3562 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -64,7 +64,7 @@ class DOMImplementation;
class DOMSelection;
class DOMWindow;
class DatabaseThread;
-class DocLoader;
+class CachedResourceLoader;
class DocumentFragment;
class DocumentType;
class DocumentWeakReference;
@@ -509,7 +509,7 @@ public:
void pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft);
static void updateStyleForAllDocuments(); // FIXME: Try to reduce the # of calls to this function.
- DocLoader* docLoader() { return m_docLoader.get(); }
+ CachedResourceLoader* cachedResourceLoader() { return m_cachedResourceLoader.get(); }
virtual void attach();
virtual void detach();
@@ -582,7 +582,13 @@ public:
bool inQuirksMode() const { return m_compatibilityMode == QuirksMode; }
bool inLimitedQuirksMode() const { return m_compatibilityMode == LimitedQuirksMode; }
bool inNoQuirksMode() const { return m_compatibilityMode == NoQuirksMode; }
-
+
+ enum ReadyState {
+ Loading,
+ Interactive,
+ Complete
+ };
+ void setReadyState(ReadyState);
void setParsing(bool);
bool parsing() const { return m_bParsing; }
int minimumLayoutDelay();
@@ -1075,7 +1081,7 @@ private:
bool m_didCalculateStyleSelector;
Frame* m_frame;
- OwnPtr<DocLoader> m_docLoader;
+ OwnPtr<CachedResourceLoader> m_cachedResourceLoader;
RefPtr<DocumentParser> m_parser;
bool m_wellFormed;
@@ -1163,6 +1169,7 @@ private:
bool m_loadingSheet;
bool m_visuallyOrdered;
+ ReadyState m_readyState;
bool m_bParsing;
Timer<Document> m_styleRecalcTimer;
diff --git a/WebCore/dom/DocumentParser.cpp b/WebCore/dom/DocumentParser.cpp
index cc4c61b..efb96b0 100644
--- a/WebCore/dom/DocumentParser.cpp
+++ b/WebCore/dom/DocumentParser.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
DocumentParser::DocumentParser(Document* document)
- : m_parserStopped(false)
+ : m_state(ParsingState)
, m_document(document)
{
ASSERT(document);
@@ -45,8 +45,25 @@ DocumentParser::~DocumentParser()
ASSERT(!m_document);
}
+void DocumentParser::startParsing()
+{
+ m_state = ParsingState;
+}
+
+void DocumentParser::prepareToStopParsing()
+{
+ ASSERT(m_state == ParsingState);
+ m_state = StoppingState;
+}
+
+void DocumentParser::stopParsing()
+{
+ m_state = StoppedState;
+}
+
void DocumentParser::detach()
{
+ m_state = DetachedState;
m_document = 0;
}
diff --git a/WebCore/dom/DocumentParser.h b/WebCore/dom/DocumentParser.h
index 3c28856..7cc9e7b 100644
--- a/WebCore/dom/DocumentParser.h
+++ b/WebCore/dom/DocumentParser.h
@@ -57,12 +57,29 @@ public:
// FIXME: processingData() is only used by DocumentLoader::isLoadingInAPISense
// and is very unclear as to what it actually means. The LegacyHTMLDocumentParser
- // used to implements it.
+ // used to implement it.
virtual bool processingData() const { return false; }
// document() will return 0 after detach() is called.
Document* document() const { ASSERT(m_document); return m_document; }
- bool isDetached() const { return !m_document; }
+
+ bool isParsing() const { return m_state == ParsingState; }
+ bool isStopping() const { return m_state == StoppingState; }
+ bool isStopped() const { return m_state >= StoppedState; }
+ bool isDetached() const { return m_state == DetachedState; }
+
+ // FIXME: Is this necessary? Does XMLDocumentParserLibxml2 really need to set this?
+ virtual void startParsing();
+
+ // prepareToStop() is used when the EOF token is encountered and parsing is to be
+ // stopped normally.
+ virtual void prepareToStopParsing();
+
+ // stopParsing() is used when a load is canceled/stopped.
+ // stopParsing() is currently different from detach(), but shouldn't be.
+ // It should NOT be ok to call any methods on DocumentParser after either
+ // detach() or stopParsing() but right now only detach() will ASSERT.
+ virtual void stopParsing();
// Document is expected to detach the parser before releasing its ref.
// After detach, m_document is cleared. The parser will unwind its
@@ -71,22 +88,18 @@ public:
// detach is called.
virtual void detach();
- // stopParsing() is used when a load is canceled/stopped.
- // stopParsing() is currently different from detach(), but shouldn't be.
- // It should NOT be ok to call any methods on DocumentParser after either
- // detach() or stopParsing() but right now only detach() will ASSERT.
- virtual void stopParsing() { m_parserStopped = true; }
-
protected:
DocumentParser(Document*);
- // The parser has buffers, so parsing may continue even after
- // it stops receiving data. We use m_parserStopped to stop the parser
- // even when it has buffered data.
- // FIXME: m_document = 0 could be changed to mean "parser stopped".
- bool m_parserStopped;
-
private:
+ enum ParserState {
+ ParsingState,
+ StoppingState,
+ StoppedState,
+ DetachedState
+ };
+ ParserState m_state;
+
// Every DocumentParser needs a pointer back to the document.
// m_document will be 0 after the parser is stopped.
Document* m_document;
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 1855101..6ff47e0 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -540,6 +540,11 @@ void Element::setAttribute(const AtomicString& name, const AtomicString& value,
return;
}
+#if ENABLE(INSPECTOR)
+ if (!isSynchronizingStyleAttribute())
+ InspectorController::willModifyDOMAttr(this);
+#endif
+
const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
// Allocate attribute map if necessary.
@@ -563,17 +568,18 @@ void Element::setAttribute(const AtomicString& name, const AtomicString& value,
}
#if ENABLE(INSPECTOR)
- if (Page* page = document()->page()) {
- if (InspectorController* inspectorController = page->inspectorController()) {
- if (!isSynchronizingStyleAttribute())
- inspectorController->didModifyDOMAttr(this);
- }
- }
+ if (!isSynchronizingStyleAttribute())
+ InspectorController::didModifyDOMAttr(this);
#endif
}
void Element::setAttribute(const QualifiedName& name, const AtomicString& value, ExceptionCode&)
{
+#if ENABLE(INSPECTOR)
+ if (!isSynchronizingStyleAttribute())
+ InspectorController::willModifyDOMAttr(this);
+#endif
+
document()->incDOMTreeVersion();
// Allocate attribute map if necessary.
@@ -592,12 +598,8 @@ void Element::setAttribute(const QualifiedName& name, const AtomicString& value,
}
#if ENABLE(INSPECTOR)
- if (Page* page = document()->page()) {
- if (InspectorController* inspectorController = page->inspectorController()) {
- if (!isSynchronizingStyleAttribute())
- inspectorController->didModifyDOMAttr(this);
- }
- }
+ if (!isSynchronizingStyleAttribute())
+ InspectorController::didModifyDOMAttr(this);
#endif
}
@@ -693,9 +695,12 @@ void Element::setAttributeMap(PassRefPtr<NamedNodeMap> list, FragmentScriptingPe
i++;
}
}
- unsigned len = m_attributeMap->length();
- for (unsigned i = 0; i < len; i++)
- attributeChanged(m_attributeMap->m_attributes[i].get());
+ // Store the set of attributes that changed on the stack in case
+ // attributeChanged mutates m_attributeMap.
+ Vector<RefPtr<Attribute> > attributes;
+ m_attributeMap->copyAttributesToVector(attributes);
+ for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+ attributeChanged(iter->get());
// FIXME: What about attributes that were in the old map that are not in the new map?
}
}
@@ -1228,6 +1233,8 @@ void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
void Element::removeAttribute(const String& name, ExceptionCode& ec)
{
+ InspectorController::willModifyDOMAttr(this);
+
String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
if (m_attributeMap) {
@@ -1236,13 +1243,7 @@ void Element::removeAttribute(const String& name, ExceptionCode& ec)
ec = 0;
}
-#if ENABLE(INSPECTOR)
- if (Page* page = document()->page()) {
- if (InspectorController* inspectorController = page->inspectorController())
- inspectorController->didModifyDOMAttr(this);
- }
-#endif
-
+ InspectorController::didModifyDOMAttr(this);
}
void Element::removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
@@ -1557,6 +1558,13 @@ DOMStringMap* Element::dataset()
return data->m_datasetDOMStringMap.get();
}
+DOMStringMap* Element::optionalDataset() const
+{
+ if (!hasRareData())
+ return 0;
+ return rareData()->m_datasetDOMStringMap.get();
+}
+
KURL Element::getURLAttribute(const QualifiedName& name) const
{
#if !ASSERT_DISABLED
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index 5bbddc2..d9a5085 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -270,6 +270,7 @@ public:
bool webkitMatchesSelector(const String& selectors, ExceptionCode&);
DOMStringMap* dataset();
+ DOMStringMap* optionalDataset() const;
virtual bool isFormControlElement() const { return false; }
virtual bool isEnabledFormControl() const { return true; }
@@ -281,6 +282,7 @@ public:
virtual bool isDefaultButtonForForm() const { return false; }
virtual bool willValidate() const { return false; }
virtual bool isValidFormControlElement() { return false; }
+ virtual bool hasUnacceptableValue() const { return false; }
virtual bool formControlValueMatchesRenderer() const { return false; }
virtual void setFormControlValueMatchesRenderer(bool) { }
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index 2a53b77..f0284d8 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -84,7 +84,7 @@ void InputElement::dispatchBlurEvent(InputElement* inputElement, Element* elemen
if (inputElement->isPasswordField())
document->setUseSecureKeyboardEntryWhenActive(false);
- frame->textFieldDidEndEditing(element);
+ frame->editor()->textFieldDidEndEditing(element);
}
void InputElement::updateFocusAppearance(InputElementData& data, InputElement* inputElement, Element* element, bool restorePreviousSelection)
@@ -123,7 +123,7 @@ void InputElement::aboutToUnload(InputElement* inputElement, Element* element)
if (!frame)
return;
- frame->textFieldDidEndEditing(element);
+ frame->editor()->textFieldDidEndEditing(element);
}
void InputElement::setValueFromRenderer(InputElementData& data, InputElement* inputElement, Element* element, const String& value)
diff --git a/WebCore/dom/InputElement.h b/WebCore/dom/InputElement.h
index 56fc99d..d5ce212 100644
--- a/WebCore/dom/InputElement.h
+++ b/WebCore/dom/InputElement.h
@@ -60,6 +60,8 @@ public:
virtual void setValue(const String&, bool sendChangeEvent = false) = 0;
virtual void setValueForUser(const String&) = 0;
+ // Returns true if the specified string can be set as the value of InputElement.
+ virtual bool isAcceptableValue(const String&) const = 0;
virtual String sanitizeValue(const String&) const = 0;
virtual void setValueFromRenderer(const String&) = 0;
diff --git a/WebCore/dom/MessagePortChannel.cpp b/WebCore/dom/MessagePortChannel.cpp
index e1a3ac6..cb431a1 100644
--- a/WebCore/dom/MessagePortChannel.cpp
+++ b/WebCore/dom/MessagePortChannel.cpp
@@ -39,7 +39,7 @@ PassOwnPtr<MessagePortChannel::EventData> MessagePortChannel::EventData::create(
}
MessagePortChannel::EventData::EventData(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
- : m_message(message->release())
+ : m_message(message)
, m_channels(channels)
{
}
diff --git a/WebCore/dom/ProcessingInstruction.cpp b/WebCore/dom/ProcessingInstruction.cpp
index 8f4a0ce..38a49a0 100644
--- a/WebCore/dom/ProcessingInstruction.cpp
+++ b/WebCore/dom/ProcessingInstruction.cpp
@@ -25,7 +25,7 @@
#include "CachedCSSStyleSheet.h"
#include "CachedXSLStyleSheet.h"
#include "Document.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -159,7 +159,7 @@ void ProcessingInstruction::checkStyleSheet()
#if ENABLE(XSLT)
if (m_isXSL)
- m_cachedSheet = document()->docLoader()->requestXSLStyleSheet(url);
+ m_cachedSheet = document()->cachedResourceLoader()->requestXSLStyleSheet(url);
else
#endif
{
@@ -167,7 +167,7 @@ void ProcessingInstruction::checkStyleSheet()
if (charset.isEmpty())
charset = document()->frame()->loader()->writer()->encoding();
- m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(url, charset);
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(url, charset);
}
if (m_cachedSheet)
m_cachedSheet->addClient(this);
diff --git a/WebCore/dom/RawDataDocumentParser.h b/WebCore/dom/RawDataDocumentParser.h
index 093ddaf..9ca36f4 100644
--- a/WebCore/dom/RawDataDocumentParser.h
+++ b/WebCore/dom/RawDataDocumentParser.h
@@ -39,7 +39,7 @@ protected:
virtual void finish()
{
- if (!m_parserStopped && !isDetached())
+ if (!isStopped())
document()->finishedParsing();
}
diff --git a/WebCore/dom/ScriptElement.cpp b/WebCore/dom/ScriptElement.cpp
index 8626bb4..bb46f0a 100644
--- a/WebCore/dom/ScriptElement.cpp
+++ b/WebCore/dom/ScriptElement.cpp
@@ -26,7 +26,7 @@
#include "AsyncScriptRunner.h"
#include "CachedScript.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentParser.h"
#include "Frame.h"
@@ -52,7 +52,7 @@ namespace WebCore {
void ScriptElement::insertedIntoDocument(ScriptElementData& data, const String& sourceUrl)
{
- if (data.createdByParser())
+ if (data.createdByParser() && !data.isAsynchronous())
return;
// http://www.whatwg.org/specs/web-apps/current-work/#script
@@ -170,7 +170,7 @@ void ScriptElementData::requestScript(const String& sourceUrl)
return;
ASSERT(!m_cachedScript);
- m_cachedScript = document->docLoader()->requestScript(sourceUrl, scriptCharset());
+ m_cachedScript = document->cachedResourceLoader()->requestScript(sourceUrl, scriptCharset());
m_requested = true;
// m_createdByParser is never reset - always resied at the initial value set while parsing.
diff --git a/WebCore/dom/ScriptableDocumentParser.cpp b/WebCore/dom/ScriptableDocumentParser.cpp
index 43b3417..0712a15 100644
--- a/WebCore/dom/ScriptableDocumentParser.cpp
+++ b/WebCore/dom/ScriptableDocumentParser.cpp
@@ -28,8 +28,8 @@
namespace WebCore {
-ScriptableDocumentParser::ScriptableDocumentParser(Document* document, bool viewSourceMode)
- : DecodedDataDocumentParser(document, viewSourceMode)
+ScriptableDocumentParser::ScriptableDocumentParser(Document* document)
+ : DecodedDataDocumentParser(document)
, m_xssAuditor(0)
{
}
diff --git a/WebCore/dom/ScriptableDocumentParser.h b/WebCore/dom/ScriptableDocumentParser.h
index e2b3f09..8b16304 100644
--- a/WebCore/dom/ScriptableDocumentParser.h
+++ b/WebCore/dom/ScriptableDocumentParser.h
@@ -53,7 +53,7 @@ public:
void setXSSAuditor(XSSAuditor* auditor) { m_xssAuditor = auditor; }
protected:
- ScriptableDocumentParser(Document*, bool viewSourceMode = false);
+ explicit ScriptableDocumentParser(Document*);
private:
virtual ScriptableDocumentParser* asScriptableDocumentParser() { return this; }
diff --git a/WebCore/dom/SelectElement.h b/WebCore/dom/SelectElement.h
index f00bb67..73e2620 100644
--- a/WebCore/dom/SelectElement.h
+++ b/WebCore/dom/SelectElement.h
@@ -59,7 +59,7 @@ public:
virtual int selectedIndex() const = 0;
virtual void setSelectedIndex(int index, bool deselect = true) = 0;
- virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false) = 0;
+ virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false) = 0;
virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true) = 0;
diff --git a/WebCore/dom/XMLDocumentParser.cpp b/WebCore/dom/XMLDocumentParser.cpp
index 4b76472..4ae18a1 100644
--- a/WebCore/dom/XMLDocumentParser.cpp
+++ b/WebCore/dom/XMLDocumentParser.cpp
@@ -29,7 +29,7 @@
#include "CDATASection.h"
#include "CachedScript.h"
#include "Comment.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentType.h"
@@ -132,7 +132,7 @@ void XMLDocumentParser::append(const SegmentedString& s)
if (m_sawXSLTransform || !m_sawFirstElement)
m_originalSourceForTransform += parseString;
- if (isDetached() || m_parserStopped || m_sawXSLTransform)
+ if (isStopped() || m_sawXSLTransform)
return;
if (m_parserPaused) {
@@ -190,7 +190,7 @@ static inline String toString(const xmlChar* str, unsigned len)
void XMLDocumentParser::exitText()
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (!m_currentNode || !m_currentNode->isTextNode())
@@ -234,6 +234,9 @@ void XMLDocumentParser::end()
document()->styleSelectorChanged(RecalcStyleImmediately);
}
+ if (isParsing())
+ prepareToStopParsing();
+ document()->setReadyState(Document::Interactive);
clearCurrentNodeStack();
document()->finishedParsing();
}
diff --git a/WebCore/dom/XMLDocumentParser.h b/WebCore/dom/XMLDocumentParser.h
index 4211e4e..47e65c6 100644
--- a/WebCore/dom/XMLDocumentParser.h
+++ b/WebCore/dom/XMLDocumentParser.h
@@ -154,7 +154,7 @@ namespace WebCore {
class Node;
class CachedScript;
- class DocLoader;
+ class CachedResourceLoader;
class DocumentFragment;
class Document;
class Element;
@@ -329,7 +329,7 @@ public:
};
#if ENABLE(XSLT)
-void* xmlDocPtrForString(DocLoader*, const String& source, const String& url);
+void* xmlDocPtrForString(CachedResourceLoader*, const String& source, const String& url);
#endif
HashMap<String, String> parseAttributes(const String&, bool& attrsOK);
diff --git a/WebCore/dom/XMLDocumentParserLibxml2.cpp b/WebCore/dom/XMLDocumentParserLibxml2.cpp
index db94c50..927fbbe 100644
--- a/WebCore/dom/XMLDocumentParserLibxml2.cpp
+++ b/WebCore/dom/XMLDocumentParserLibxml2.cpp
@@ -29,7 +29,7 @@
#include "CDATASection.h"
#include "CachedScript.h"
#include "Comment.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentType.h"
@@ -338,7 +338,7 @@ static int matchFunc(const char*)
{
// Only match loads initiated due to uses of libxml2 from within XMLDocumentParser to avoid
// interfering with client applications that also use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
- return XMLDocumentParserScope::currentDocLoader && currentThread() == libxmlLoaderThread;
+ return XMLDocumentParserScope::currentCachedResourceLoader && currentThread() == libxmlLoaderThread;
}
class OffsetBuffer {
@@ -400,8 +400,8 @@ static bool shouldAllowExternalLoad(const KURL& url)
// retrieved content. If we had more context, we could potentially allow
// the parser to load a DTD. As things stand, we take the conservative
// route and allow same-origin requests only.
- if (!XMLDocumentParserScope::currentDocLoader->doc()->securityOrigin()->canRequest(url)) {
- XMLDocumentParserScope::currentDocLoader->printAccessDeniedMessage(url);
+ if (!XMLDocumentParserScope::currentCachedResourceLoader->doc()->securityOrigin()->canRequest(url)) {
+ XMLDocumentParserScope::currentCachedResourceLoader->printAccessDeniedMessage(url);
return false;
}
@@ -410,7 +410,7 @@ static bool shouldAllowExternalLoad(const KURL& url)
static void* openFunc(const char* uri)
{
- ASSERT(XMLDocumentParserScope::currentDocLoader);
+ ASSERT(XMLDocumentParserScope::currentCachedResourceLoader);
ASSERT(currentThread() == libxmlLoaderThread);
KURL url(KURL(), uri);
@@ -424,12 +424,12 @@ static void* openFunc(const char* uri)
{
- DocLoader* docLoader = XMLDocumentParserScope::currentDocLoader;
+ CachedResourceLoader* cachedResourceLoader = XMLDocumentParserScope::currentCachedResourceLoader;
XMLDocumentParserScope scope(0);
// FIXME: We should restore the original global error handler as well.
- if (docLoader->frame())
- docLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
+ if (cachedResourceLoader->frame())
+ cachedResourceLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
}
// We have to check the URL again after the load to catch redirects.
@@ -655,12 +655,12 @@ void XMLDocumentParser::doWrite(const String& parseString)
RefPtr<XMLDocumentParser> protect(this);
switchToUTF16(context->context());
- XMLDocumentParserScope scope(document()->docLoader());
+ XMLDocumentParserScope scope(document()->cachedResourceLoader());
xmlParseChunk(context->context(), reinterpret_cast<const char*>(parseString.characters()), sizeof(UChar) * parseString.length(), 0);
// JavaScript (which may be run under the xmlParseChunk callstack) may
// cause the parser to be stopped or detached.
- if (isDetached() || m_parserStopped)
+ if (isStopped())
return;
}
@@ -733,7 +733,7 @@ static inline void handleElementAttributes(Element* newElement, const xmlChar**
void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int nb_namespaces,
const xmlChar** libxmlNamespaces, int nb_attributes, int nb_defaulted, const xmlChar** libxmlAttributes)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -822,7 +822,7 @@ void XMLDocumentParser::startElementNs(const xmlChar* xmlLocalName, const xmlCha
void XMLDocumentParser::endElementNs()
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -884,7 +884,7 @@ void XMLDocumentParser::endElementNs()
// we have a src attribute
String scriptCharset = scriptElement->scriptCharset();
if (element->dispatchBeforeLoadEvent(scriptHref) &&
- (m_pendingScript = document()->docLoader()->requestScript(scriptHref, scriptCharset))) {
+ (m_pendingScript = document()->cachedResourceLoader()->requestScript(scriptHref, scriptCharset))) {
m_scriptElement = element;
m_pendingScript->addClient(this);
@@ -906,7 +906,7 @@ void XMLDocumentParser::endElementNs()
void XMLDocumentParser::characters(const xmlChar* s, int len)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -921,7 +921,7 @@ void XMLDocumentParser::characters(const xmlChar* s, int len)
void XMLDocumentParser::error(ErrorType type, const char* message, va_list args)
{
- if (m_parserStopped)
+ if (isStopped())
return;
#if COMPILER(MSVC) || COMPILER(RVCT)
@@ -945,7 +945,7 @@ void XMLDocumentParser::error(ErrorType type, const char* message, va_list args)
void XMLDocumentParser::processingInstruction(const xmlChar* target, const xmlChar* data)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -979,7 +979,7 @@ void XMLDocumentParser::processingInstruction(const xmlChar* target, const xmlCh
void XMLDocumentParser::cdataBlock(const xmlChar* s, int len)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -997,7 +997,7 @@ void XMLDocumentParser::cdataBlock(const xmlChar* s, int len)
void XMLDocumentParser::comment(const xmlChar* s)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -1034,7 +1034,7 @@ void XMLDocumentParser::endDocument()
void XMLDocumentParser::internalSubset(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID)
{
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_parserPaused) {
@@ -1294,12 +1294,12 @@ void XMLDocumentParser::initializeParserContext(const char* chunk)
sax.ignorableWhitespace = ignorableWhitespaceHandler;
sax.entityDecl = xmlSAX2EntityDecl;
sax.initialized = XML_SAX2_MAGIC;
- m_parserStopped = false;
+ DocumentParser::startParsing();
m_sawError = false;
m_sawXSLTransform = false;
m_sawFirstElement = false;
- XMLDocumentParserScope scope(document()->docLoader());
+ XMLDocumentParserScope scope(document()->cachedResourceLoader());
if (m_parsingFragment)
m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
else {
@@ -1312,23 +1312,23 @@ void XMLDocumentParser::doEnd()
{
#if ENABLE(XSLT)
if (m_sawXSLTransform) {
- void* doc = xmlDocPtrForString(document()->docLoader(), m_originalSourceForTransform, document()->url().string());
+ void* doc = xmlDocPtrForString(document()->cachedResourceLoader(), m_originalSourceForTransform, document()->url().string());
document()->setTransformSource(new TransformSource(doc));
document()->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
document()->styleSelectorChanged(RecalcStyleImmediately);
document()->setParsing(true);
- m_parserStopped = true;
+ DocumentParser::stopParsing();
}
#endif
- if (m_parserStopped)
+ if (isStopped())
return;
if (m_context) {
// Tell libxml we're done.
{
- XMLDocumentParserScope scope(document()->docLoader());
+ XMLDocumentParserScope scope(document()->cachedResourceLoader());
xmlParseChunk(context(), 0, 0, 1);
}
@@ -1337,7 +1337,7 @@ void XMLDocumentParser::doEnd()
}
#if ENABLE(XSLT)
-void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const String& url)
+void* xmlDocPtrForString(CachedResourceLoader* cachedResourceLoader, const String& source, const String& url)
{
if (source.isEmpty())
return 0;
@@ -1348,7 +1348,7 @@ void* xmlDocPtrForString(DocLoader* docLoader, const String& source, const Strin
const UChar BOM = 0xFEFF;
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
- XMLDocumentParserScope scope(docLoader, errorFunc, 0);
+ XMLDocumentParserScope scope(cachedResourceLoader, errorFunc, 0);
xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char*>(source.characters()),
source.length() * sizeof(UChar),
url.latin1().data(),
diff --git a/WebCore/dom/XMLDocumentParserQt.cpp b/WebCore/dom/XMLDocumentParserQt.cpp
index dfd6fb1..75a20be 100644
--- a/WebCore/dom/XMLDocumentParserQt.cpp
+++ b/WebCore/dom/XMLDocumentParserQt.cpp
@@ -29,7 +29,7 @@
#include "CDATASection.h"
#include "CachedScript.h"
#include "Comment.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentType.h"
@@ -199,7 +199,7 @@ void XMLDocumentParser::doWrite(const String& parseString)
void XMLDocumentParser::initializeParserContext(const char*)
{
- m_parserStopped = false;
+ DocumentParser::startParsing();
m_sawError = false;
m_sawXSLTransform = false;
m_sawFirstElement = false;
@@ -213,7 +213,7 @@ void XMLDocumentParser::doEnd()
document()->setParsing(false); // Make the doc think it's done, so it will apply xsl sheets.
document()->styleSelectorChanged(RecalcStyleImmediately);
document()->setParsing(true);
- m_parserStopped = true;
+ DocumentParser::stopParsing();
}
#endif
@@ -350,7 +350,7 @@ static inline void handleElementAttributes(Element* newElement, const QXmlStream
void XMLDocumentParser::parse()
{
- while (!m_parserStopped && !m_parserPaused && !m_stream.atEnd()) {
+ while (!isStopped() && !m_parserPaused && !m_stream.atEnd()) {
m_stream.readNext();
switch (m_stream.tokenType()) {
case QXmlStreamReader::StartDocument: {
@@ -578,7 +578,7 @@ void XMLDocumentParser::parseEndElement()
// we have a src attribute
String scriptCharset = scriptElement->scriptCharset();
if (element->dispatchBeforeLoadEvent(scriptHref) &&
- (m_pendingScript = document()->docLoader()->requestScript(scriptHref, scriptCharset))) {
+ (m_pendingScript = document()->cachedResourceLoader()->requestScript(scriptHref, scriptCharset))) {
m_scriptElement = element;
m_pendingScript->addClient(this);
diff --git a/WebCore/dom/XMLDocumentParserScope.cpp b/WebCore/dom/XMLDocumentParserScope.cpp
index 8afe49d..0a473ed 100644
--- a/WebCore/dom/XMLDocumentParserScope.cpp
+++ b/WebCore/dom/XMLDocumentParserScope.cpp
@@ -28,27 +28,27 @@
namespace WebCore {
-DocLoader* XMLDocumentParserScope::currentDocLoader = 0;
+CachedResourceLoader* XMLDocumentParserScope::currentCachedResourceLoader = 0;
-XMLDocumentParserScope::XMLDocumentParserScope(DocLoader* docLoader)
- : m_oldDocLoader(currentDocLoader)
+XMLDocumentParserScope::XMLDocumentParserScope(CachedResourceLoader* cachedResourceLoader)
+ : m_oldCachedResourceLoader(currentCachedResourceLoader)
#if ENABLE(XSLT)
, m_oldGenericErrorFunc(xmlGenericError)
, m_oldStructuredErrorFunc(xmlStructuredError)
, m_oldErrorContext(xmlGenericErrorContext)
#endif
{
- currentDocLoader = docLoader;
+ currentCachedResourceLoader = cachedResourceLoader;
}
#if ENABLE(XSLT)
-XMLDocumentParserScope::XMLDocumentParserScope(DocLoader* docLoader, xmlGenericErrorFunc genericErrorFunc, xmlStructuredErrorFunc structuredErrorFunc, void* errorContext)
- : m_oldDocLoader(currentDocLoader)
+XMLDocumentParserScope::XMLDocumentParserScope(CachedResourceLoader* cachedResourceLoader, xmlGenericErrorFunc genericErrorFunc, xmlStructuredErrorFunc structuredErrorFunc, void* errorContext)
+ : m_oldCachedResourceLoader(currentCachedResourceLoader)
, m_oldGenericErrorFunc(xmlGenericError)
, m_oldStructuredErrorFunc(xmlStructuredError)
, m_oldErrorContext(xmlGenericErrorContext)
{
- currentDocLoader = docLoader;
+ currentCachedResourceLoader = cachedResourceLoader;
if (genericErrorFunc)
xmlSetGenericErrorFunc(errorContext, genericErrorFunc);
if (structuredErrorFunc)
@@ -58,7 +58,7 @@ XMLDocumentParserScope::XMLDocumentParserScope(DocLoader* docLoader, xmlGenericE
XMLDocumentParserScope::~XMLDocumentParserScope()
{
- currentDocLoader = m_oldDocLoader;
+ currentCachedResourceLoader = m_oldCachedResourceLoader;
#if ENABLE(XSLT)
xmlSetGenericErrorFunc(m_oldErrorContext, m_oldGenericErrorFunc);
xmlSetStructuredErrorFunc(m_oldErrorContext, m_oldStructuredErrorFunc);
diff --git a/WebCore/dom/XMLDocumentParserScope.h b/WebCore/dom/XMLDocumentParserScope.h
index bdf629d..58e8a6b 100644
--- a/WebCore/dom/XMLDocumentParserScope.h
+++ b/WebCore/dom/XMLDocumentParserScope.h
@@ -34,21 +34,21 @@
namespace WebCore {
- class DocLoader;
+ class CachedResourceLoader;
class XMLDocumentParserScope : public Noncopyable {
public:
- XMLDocumentParserScope(DocLoader* docLoader);
+ XMLDocumentParserScope(CachedResourceLoader* cachedResourceLoader);
~XMLDocumentParserScope();
- static DocLoader* currentDocLoader;
+ static CachedResourceLoader* currentCachedResourceLoader;
#if ENABLE(XSLT)
- XMLDocumentParserScope(DocLoader* docLoader, xmlGenericErrorFunc genericErrorFunc, xmlStructuredErrorFunc structuredErrorFunc = 0, void* errorContext = 0);
+ XMLDocumentParserScope(CachedResourceLoader* cachedResourceLoader, xmlGenericErrorFunc genericErrorFunc, xmlStructuredErrorFunc structuredErrorFunc = 0, void* errorContext = 0);
#endif
private:
- DocLoader* m_oldDocLoader;
+ CachedResourceLoader* m_oldCachedResourceLoader;
#if ENABLE(XSLT)
xmlGenericErrorFunc m_oldGenericErrorFunc;
diff --git a/WebCore/editing/ApplyStyleCommand.cpp b/WebCore/editing/ApplyStyleCommand.cpp
index 4385a16..d104cbe 100644
--- a/WebCore/editing/ApplyStyleCommand.cpp
+++ b/WebCore/editing/ApplyStyleCommand.cpp
@@ -31,11 +31,13 @@
#include "CSSParser.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
#include "CSSValueKeywords.h"
#include "Document.h"
#include "Editor.h"
#include "Frame.h"
#include "HTMLElement.h"
+#include "HTMLFontElement.h"
#include "HTMLInterchange.h"
#include "HTMLNames.h"
#include "NodeList.h"
@@ -110,7 +112,7 @@ public:
private:
void init(PassRefPtr<CSSStyleDeclaration>, const Position&);
void reconcileTextDecorationProperties(CSSMutableStyleDeclaration*);
- void extractTextStyles(CSSMutableStyleDeclaration*);
+ void extractTextStyles(Document*, CSSMutableStyleDeclaration*, bool shouldUseFixedFontDefautlSize);
String m_cssStyle;
bool m_applyBold;
@@ -147,7 +149,7 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position& po
reconcileTextDecorationProperties(mutableStyle.get());
if (!document->frame()->editor()->shouldStyleWithCSS())
- extractTextStyles(mutableStyle.get());
+ extractTextStyles(document, mutableStyle.get(), computedStyle->useFixedFontDefaultSize());
// Changing the whitespace style in a tab span would collapse the tab into a space.
if (isTabSpanTextNode(position.node()) || isTabSpanNode((position.node())))
@@ -202,7 +204,7 @@ static void setTextDecorationProperty(CSSMutableStyleDeclaration* style, const C
}
}
-void StyleChange::extractTextStyles(CSSMutableStyleDeclaration* style)
+void StyleChange::extractTextStyles(Document* document, CSSMutableStyleDeclaration* style, bool shouldUseFixedFontDefautlSize)
{
ASSERT(style);
@@ -259,28 +261,18 @@ void StyleChange::extractTextStyles(CSSMutableStyleDeclaration* style)
style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size.
else {
CSSPrimitiveValue* value = static_cast<CSSPrimitiveValue*>(fontSize.get());
-
- // Only accept absolute scale
if (value->primitiveType() >= CSSPrimitiveValue::CSS_PX && value->primitiveType() <= CSSPrimitiveValue::CSS_PC) {
- float number = value->getFloatValue(CSSPrimitiveValue::CSS_PX);
- if (number <= 9)
- m_applyFontSize = "1";
- else if (number <= 10)
- m_applyFontSize = "2";
- else if (number <= 13)
- m_applyFontSize = "3";
- else if (number <= 16)
- m_applyFontSize = "4";
- else if (number <= 18)
- m_applyFontSize = "5";
- else if (number <= 24)
- m_applyFontSize = "6";
- else
- m_applyFontSize = "7";
+ int pixelFontSize = value->getFloatValue(CSSPrimitiveValue::CSS_PX);
+ int legacyFontSize = CSSStyleSelector::legacyFontSize(document, pixelFontSize, shouldUseFixedFontDefautlSize);
+ // Use legacy font size only if pixel value matches exactly to that of legacy font size.
+ if (CSSStyleSelector::fontSizeForKeyword(document, legacyFontSize - 1 + CSSValueXSmall, shouldUseFixedFontDefautlSize) == pixelFontSize) {
+ m_applyFontSize = String::number(legacyFontSize);
+ style->removeProperty(CSSPropertyFontSize);
+ }
+ } else if (CSSValueXSmall <= value->getIdent() && value->getIdent() <= CSSValueWebkitXxxLarge) {
+ m_applyFontSize = String::number(value->getIdent() - CSSValueXSmall + 1);
+ style->removeProperty(CSSPropertyFontSize);
}
- // Huge quirk in Microsoft Entourage is that they understand CSS font-size, but also write
- // out legacy 1-7 values in font tags (I guess for mailers that are not CSS-savvy at all,
- // like Eudora). Yes, they write out *both*. We need to write out both as well.
}
}
}
@@ -1037,7 +1029,7 @@ void ApplyStyleCommand::applyInlineStyle(CSSMutableStyleDeclaration *style)
RefPtr<CSSMutableStyleDeclaration> embeddingStyle = CSSMutableStyleDeclaration::create();
embeddingStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
embeddingStyle->setProperty(CSSPropertyDirection, direction);
- applyInlineStyleToRange(embeddingStyle.get(), embeddingApplyStart, embeddingApplyEnd);
+ fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStart, embeddingApplyEnd);
if (styleWithoutEmbedding)
styleToApply = styleWithoutEmbedding;
@@ -1049,7 +1041,7 @@ void ApplyStyleCommand::applyInlineStyle(CSSMutableStyleDeclaration *style)
}
}
- applyInlineStyleToRange(styleToApply.get(), start, end);
+ fixRangeAndApplyInlineStyle(styleToApply.get(), start, end);
// Remove dummy style spans created by splitting text elements.
cleanupUnstyledAppleStyleSpans(startDummySpanAncestor);
@@ -1057,78 +1049,71 @@ void ApplyStyleCommand::applyInlineStyle(CSSMutableStyleDeclaration *style)
cleanupUnstyledAppleStyleSpans(endDummySpanAncestor);
}
-void ApplyStyleCommand::applyInlineStyleToRange(CSSMutableStyleDeclaration* style, const Position& start, const Position& rangeEnd)
+void ApplyStyleCommand::fixRangeAndApplyInlineStyle(CSSMutableStyleDeclaration* style, const Position& start, const Position& end)
{
- Node* node = start.node();
- Position end = rangeEnd;
-
- bool rangeIsEmpty = false;
+ Node* startNode = start.node();
if (start.deprecatedEditingOffset() >= caretMaxOffset(start.node())) {
- node = node->traverseNextNode();
- Position newStart = Position(node, 0);
- if (!node || comparePositions(end, newStart) < 0)
- rangeIsEmpty = true;
- }
-
- if (!rangeIsEmpty) {
- // pastEndNode is the node after the last fully selected node.
- Node* pastEndNode = end.node();
- if (end.deprecatedEditingOffset() >= caretMaxOffset(end.node()))
- pastEndNode = end.node()->traverseNextSibling();
- // FIXME: Callers should perform this operation on a Range that includes the br
- // if they want style applied to the empty line.
- if (start == end && start.node()->hasTagName(brTag))
- pastEndNode = start.node()->traverseNextNode();
- // Add the style to selected inline runs.
- for (Node* next; node && node != pastEndNode; node = next) {
-
- next = node->traverseNextNode();
-
- if (!node->renderer() || !node->isContentEditable())
- continue;
-
- if (!node->isContentRichlyEditable() && node->isHTMLElement()) {
- // This is a plaintext-only region. Only proceed if it's fully selected.
- // pastEndNode is the node after the last fully selected node, so if it's inside node then
- // node isn't fully selected.
- if (pastEndNode && pastEndNode->isDescendantOf(node))
- break;
- // Add to this element's inline style and skip over its contents.
- HTMLElement* element = static_cast<HTMLElement*>(node);
- RefPtr<CSSMutableStyleDeclaration> inlineStyle = element->getInlineStyleDecl()->copy();
- inlineStyle->merge(style);
- setNodeAttribute(element, styleAttr, inlineStyle->cssText());
- next = node->traverseNextSibling();
- continue;
- }
+ startNode = startNode->traverseNextNode();
+ if (!startNode || comparePositions(end, Position(startNode, 0)) < 0)
+ return;
+ }
+
+ Node* pastEndNode = end.node();
+ if (end.deprecatedEditingOffset() >= caretMaxOffset(end.node()))
+ pastEndNode = end.node()->traverseNextSibling();
+
+ // FIXME: Callers should perform this operation on a Range that includes the br
+ // if they want style applied to the empty line.
+ if (start == end && start.node()->hasTagName(brTag))
+ pastEndNode = start.node()->traverseNextNode();
+
+ applyInlineStyleToNodeRange(style, startNode, pastEndNode);
+}
+
+void ApplyStyleCommand::applyInlineStyleToNodeRange(CSSMutableStyleDeclaration* style, Node* node, Node* pastEndNode)
+{
+ for (Node* next; node && node != pastEndNode; node = next) {
+ next = node->traverseNextNode();
- if (isBlock(node))
- continue;
-
- if (node->childNodeCount()) {
- if (editingIgnoresContent(node)) {
- next = node->traverseNextSibling();
- continue;
- }
- continue;
- }
-
- Node* runStart = node;
- // Find the end of the run.
- Node* sibling = node->nextSibling();
- StyleChange startChange(style, Position(node, 0));
- while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNode)
- && (!isBlock(sibling) || sibling->hasTagName(brTag))
- && StyleChange(style, Position(sibling, 0)) == startChange) {
- node = sibling;
- sibling = node->nextSibling();
- }
- // Recompute next, since node has changed.
+ if (!node->renderer() || !node->isContentEditable())
+ continue;
+
+ if (!node->isContentRichlyEditable() && node->isHTMLElement()) {
+ // This is a plaintext-only region. Only proceed if it's fully selected.
+ // pastEndNode is the node after the last fully selected node, so if it's inside node then
+ // node isn't fully selected.
+ if (pastEndNode && pastEndNode->isDescendantOf(node))
+ break;
+ // Add to this element's inline style and skip over its contents.
+ HTMLElement* element = static_cast<HTMLElement*>(node);
+ RefPtr<CSSMutableStyleDeclaration> inlineStyle = element->getInlineStyleDecl()->copy();
+ inlineStyle->merge(style);
+ setNodeAttribute(element, styleAttr, inlineStyle->cssText());
next = node->traverseNextSibling();
- // Apply the style to the run.
- addInlineStyleIfNeeded(style, runStart, node, m_removeOnly ? DoNotAddStyledElement : AddStyledElement);
+ continue;
+ }
+
+ if (isBlock(node))
+ continue;
+
+ if (node->childNodeCount()) {
+ if (editingIgnoresContent(node))
+ next = node->traverseNextSibling();
+ continue;
}
+
+ Node* runEnd = node;
+ Node* sibling = node->nextSibling();
+ StyleChange startChange(style, Position(node, 0));
+ while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNode)
+ && (!isBlock(sibling) || sibling->hasTagName(brTag))
+ && StyleChange(style, Position(sibling, 0)) == startChange) {
+ runEnd = sibling;
+ sibling = runEnd->nextSibling();
+ }
+ next = runEnd->traverseNextSibling();
+ addInlineStyleIfNeeded(style, node, runEnd, m_removeOnly ? DoNotAddStyledElement : AddStyledElement);
}
}
@@ -1165,33 +1150,52 @@ struct HTMLEquivalent {
int primitiveId;
const QualifiedName* element;
const QualifiedName* attribute;
+ PassRefPtr<CSSValue> (*attributeToCSSValue)(int propertyID, const String&);
EPushDownType pushDownType;
};
+static PassRefPtr<CSSValue> stringToCSSValue(int propertyID, const String& value)
+{
+ RefPtr<CSSMutableStyleDeclaration> dummyStyle;
+ dummyStyle = CSSMutableStyleDeclaration::create();
+ dummyStyle->setProperty(propertyID, value);
+ return dummyStyle->getPropertyCSSValue(propertyID);
+}
+
+static PassRefPtr<CSSValue> fontSizeToCSSValue(int propertyID, const String& value)
+{
+ UNUSED_PARAM(propertyID);
+ ASSERT(propertyID == CSSPropertyFontSize);
+ int size;
+ if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
+ return 0;
+ return CSSPrimitiveValue::createIdentifier(size);
+}
+
static const HTMLEquivalent HTMLEquivalents[] = {
- { CSSPropertyFontWeight, false, CSSValueBold, &bTag, 0, ShouldBePushedDown },
- { CSSPropertyFontWeight, false, CSSValueBold, &strongTag, 0, ShouldBePushedDown },
- { CSSPropertyVerticalAlign, false, CSSValueSub, &subTag, 0, ShouldBePushedDown },
- { CSSPropertyVerticalAlign, false, CSSValueSuper, &supTag, 0, ShouldBePushedDown },
- { CSSPropertyFontStyle, false, CSSValueItalic, &iTag, 0, ShouldBePushedDown },
- { CSSPropertyFontStyle, false, CSSValueItalic, &emTag, 0, ShouldBePushedDown },
+ { CSSPropertyFontWeight, false, CSSValueBold, &bTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyFontWeight, false, CSSValueBold, &strongTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyVerticalAlign, false, CSSValueSub, &subTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyVerticalAlign, false, CSSValueSuper, &supTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyFontStyle, false, CSSValueItalic, &iTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyFontStyle, false, CSSValueItalic, &emTag, 0, 0, ShouldBePushedDown },
// text-decorations should be CSSValueList
- { CSSPropertyTextDecoration, true, CSSValueUnderline, &uTag, 0, ShouldBePushedDown },
- { CSSPropertyTextDecoration, true, CSSValueLineThrough, &sTag, 0, ShouldBePushedDown },
- { CSSPropertyTextDecoration, true, CSSValueLineThrough, &strikeTag, 0, ShouldBePushedDown },
- { CSSPropertyWebkitTextDecorationsInEffect, true, CSSValueUnderline, &uTag, 0, ShouldBePushedDown },
- { CSSPropertyWebkitTextDecorationsInEffect, true, CSSValueLineThrough, &sTag, 0, ShouldBePushedDown },
- { CSSPropertyWebkitTextDecorationsInEffect, true, CSSValueLineThrough, &strikeTag, 0, ShouldBePushedDown },
+ { CSSPropertyTextDecoration, true, CSSValueUnderline, &uTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyTextDecoration, true, CSSValueLineThrough, &sTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyTextDecoration, true, CSSValueLineThrough, &strikeTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyWebkitTextDecorationsInEffect, true, CSSValueUnderline, &uTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyWebkitTextDecorationsInEffect, true, CSSValueLineThrough, &sTag, 0, 0, ShouldBePushedDown },
+ { CSSPropertyWebkitTextDecorationsInEffect, true, CSSValueLineThrough, &strikeTag, 0, 0, ShouldBePushedDown },
// FIXME: font attributes should only be removed if values were different
- { CSSPropertyColor, false, CSSValueInvalid, &fontTag, &colorAttr, ShouldBePushedDown },
- { CSSPropertyFontFamily, false, CSSValueInvalid, &fontTag, &faceAttr, ShouldBePushedDown },
- { CSSPropertyFontSize, false, CSSValueInvalid, &fontTag, &sizeAttr, ShouldBePushedDown },
+ { CSSPropertyColor, false, CSSValueInvalid, &fontTag, &colorAttr, stringToCSSValue, ShouldBePushedDown },
+ { CSSPropertyFontFamily, false, CSSValueInvalid, &fontTag, &faceAttr, stringToCSSValue, ShouldBePushedDown },
+ { CSSPropertyFontSize, false, CSSValueInvalid, &fontTag, &sizeAttr, fontSizeToCSSValue, ShouldBePushedDown },
// unicode-bidi and direction are pushed down separately so don't push down with other styles.
- { CSSPropertyUnicodeBidi, false, CSSValueInvalid, 0, &dirAttr, ShouldNotBePushedDown },
- { CSSPropertyDirection, false, CSSValueInvalid, 0, &dirAttr, ShouldNotBePushedDown },
+ { CSSPropertyDirection, false, CSSValueInvalid, 0, &dirAttr, stringToCSSValue, ShouldNotBePushedDown },
+ { CSSPropertyUnicodeBidi, false, CSSValueInvalid, 0, &dirAttr, stringToCSSValue, ShouldNotBePushedDown },
};
bool ApplyStyleCommand::removeImplicitlyStyledElement(CSSMutableStyleDeclaration* style, HTMLElement* element, InlineStyleRemovalMode mode, CSSMutableStyleDeclaration* extractedStyle)
@@ -1210,19 +1214,19 @@ bool ApplyStyleCommand::removeImplicitlyStyledElement(CSSMutableStyleDeclaration
RefPtr<CSSValue> styleValue = style->getPropertyCSSValue(equivalent.propertyID);
if (!styleValue)
continue;
- RefPtr<CSSPrimitiveValue> mapValue = CSSPrimitiveValue::createIdentifier(equivalent.primitiveId);
+ RefPtr<CSSValue> mapValue;
+ if (equivalent.attribute)
+ mapValue = equivalent.attributeToCSSValue(equivalent.propertyID, element->getAttribute(*equivalent.attribute));
+ else
+ mapValue = CSSPrimitiveValue::createIdentifier(equivalent.primitiveId).get();
if (equivalent.isValueList && styleValue->isValueList() && static_cast<CSSValueList*>(styleValue.get())->hasValue(mapValue.get()))
continue; // If CSS value assumes CSSValueList, then only skip if the value was present in style to apply.
- else if (styleValue->cssText() == mapValue->cssText())
+ else if (mapValue && styleValue->cssText() == mapValue->cssText())
continue; // If CSS value is primitive, then skip if they are equal.
- if (extractedStyle) {
- if (equivalent.primitiveId == CSSValueInvalid)
- extractedStyle->setProperty(equivalent.propertyID, element->getAttribute(*equivalent.attribute));
- else
- extractedStyle->setProperty(equivalent.propertyID, mapValue->cssText());
- }
+ if (extractedStyle)
+ extractedStyle->setProperty(equivalent.propertyID, mapValue->cssText());
if (mode == RemoveNone)
return true;
diff --git a/WebCore/editing/ApplyStyleCommand.h b/WebCore/editing/ApplyStyleCommand.h
index 969384a..9f297e2 100644
--- a/WebCore/editing/ApplyStyleCommand.h
+++ b/WebCore/editing/ApplyStyleCommand.h
@@ -88,7 +88,8 @@ private:
void applyBlockStyle(CSSMutableStyleDeclaration*);
void applyRelativeFontStyleChange(CSSMutableStyleDeclaration*);
void applyInlineStyle(CSSMutableStyleDeclaration*);
- void applyInlineStyleToRange(CSSMutableStyleDeclaration*, const Position& start, const Position& end);
+ void fixRangeAndApplyInlineStyle(CSSMutableStyleDeclaration*, const Position& start, const Position& end);
+ void applyInlineStyleToNodeRange(CSSMutableStyleDeclaration*, Node* startNode, Node* pastEndNode);
void addBlockStyle(const StyleChange&, HTMLElement*);
void addInlineStyleIfNeeded(CSSMutableStyleDeclaration*, Node* start, Node* end, EAddStyledElement addStyledElement = AddStyledElement);
void splitTextAtStart(const Position& start, const Position& end);
diff --git a/WebCore/editing/CompositeEditCommand.cpp b/WebCore/editing/CompositeEditCommand.cpp
index aa37193..356a717 100644
--- a/WebCore/editing/CompositeEditCommand.cpp
+++ b/WebCore/editing/CompositeEditCommand.cpp
@@ -36,6 +36,7 @@
#include "Document.h"
#include "DocumentFragment.h"
#include "EditorInsertAction.h"
+#include "Frame.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "InlineTextBox.h"
@@ -939,6 +940,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
// FIXME (5098931): We should add a new insert action "WebViewInsertActionMoved" and call shouldInsertFragment here.
setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
+ document()->frame()->editor()->clearMisspellingsAndBadGrammar(endingSelection());
deleteSelection(false, false, false, false);
ASSERT(destination.deepEquivalent().node()->inDocument());
@@ -968,7 +970,9 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
setEndingSelection(destination);
ASSERT(endingSelection().isCaretOrRange());
applyCommandToComposite(ReplaceSelectionCommand::create(document(), fragment, true, false, !preserveStyle, false, true));
-
+
+ document()->frame()->editor()->markMisspellingsAndBadGrammar(endingSelection());
+
// If the selection is in an empty paragraph, restore styles from the old empty paragraph to the new empty paragraph.
bool selectionIsEmptyParagraph = endingSelection().isCaret() && isStartOfParagraph(endingSelection().visibleStart()) && isEndOfParagraph(endingSelection().visibleStart());
if (styleInEmptyParagraph && selectionIsEmptyParagraph)
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp
index e57895c..70f0e88 100644
--- a/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/WebCore/editing/DeleteSelectionCommand.cpp
@@ -746,7 +746,7 @@ void DeleteSelectionCommand::doApply()
if (ancestorNode && ancestorNode->hasTagName(inputTag)
&& static_cast<HTMLInputElement*>(ancestorNode)->isTextField()
&& ancestorNode->focused())
- document()->frame()->textWillBeDeletedInTextField(static_cast<Element*>(ancestorNode));
+ document()->frame()->editor()->textWillBeDeletedInTextField(static_cast<Element*>(ancestorNode));
}
// save this to later make the selection with
diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp
index 117292c..c515bfc 100644
--- a/WebCore/editing/Editor.cpp
+++ b/WebCore/editing/Editor.cpp
@@ -33,6 +33,7 @@
#include "CSSMutableStyleDeclaration.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
#include "CSSValueKeywords.h"
#include "CharacterNames.h"
#include "ClipboardEvent.h"
@@ -40,8 +41,9 @@
#include "CreateLinkCommand.h"
#include "DeleteButtonController.h"
#include "DeleteSelectionCommand.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "DocumentFragment.h"
+#include "EditingText.h"
#include "EditorClient.h"
#include "EventHandler.h"
#include "EventNames.h"
@@ -57,6 +59,7 @@
#include "KeyboardEvent.h"
#include "KillRing.h"
#include "ModifySelectionListLevel.h"
+#include "NodeList.h"
#include "Page.h"
#include "Pasteboard.h"
#include "RemoveFormatCommand.h"
@@ -469,7 +472,7 @@ const SimpleFontData* Editor::fontForSelection(bool& hasMultipleFonts) const
if (!m_frame->selection()->isRange()) {
Node* nodeToRemove;
- RenderStyle* style = m_frame->styleForSelectionStart(nodeToRemove); // sets nodeToRemove
+ RenderStyle* style = styleForSelectionStart(nodeToRemove); // sets nodeToRemove
const SimpleFontData* result = 0;
if (style)
@@ -520,9 +523,9 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe
if (m_frame->selection()->isNone())
return NaturalWritingDirection;
- Position pos = m_frame->selection()->selection().start().downstream();
+ Position position = m_frame->selection()->selection().start().downstream();
- Node* node = pos.node();
+ Node* node = position.node();
if (!node)
return NaturalWritingDirection;
@@ -530,7 +533,7 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe
if (m_frame->selection()->isRange()) {
end = m_frame->selection()->selection().end().upstream();
- Node* pastLast = Range::create(m_frame->document(), rangeCompliantEquivalent(pos), rangeCompliantEquivalent(end))->pastLastNode();
+ Node* pastLast = Range::create(m_frame->document(), rangeCompliantEquivalent(position), rangeCompliantEquivalent(end))->pastLastNode();
for (Node* n = node; n && n != pastLast; n = n->traverseNextNode()) {
if (!n->isStyledElement())
continue;
@@ -548,7 +551,7 @@ WritingDirection Editor::textDirectionForSelection(bool& hasNestedOrMultipleEmbe
}
if (m_frame->selection()->isCaret()) {
- if (CSSMutableStyleDeclaration *typingStyle = m_frame->typingStyle()) {
+ if (CSSMutableStyleDeclaration* typingStyle = m_frame->typingStyle()) {
RefPtr<CSSValue> unicodeBidi = typingStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
if (unicodeBidi) {
ASSERT(unicodeBidi->isPrimitiveValue());
@@ -795,7 +798,7 @@ void Editor::applyStyle(CSSStyleDeclaration* style, EditAction editingAction)
// do nothing
break;
case VisibleSelection::CaretSelection:
- m_frame->computeAndSetTypingStyle(style, editingAction);
+ computeAndSetTypingStyle(style, editingAction);
break;
case VisibleSelection::RangeSelection:
if (style)
@@ -872,7 +875,7 @@ static TriState triStateOfStyleInComputedStyle(CSSStyleDeclaration* desiredStyle
bool Editor::selectionStartHasStyle(CSSStyleDeclaration* style) const
{
Node* nodeToRemove;
- RefPtr<CSSComputedStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove);
+ RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
if (!selectionStyle)
return false;
TriState state = triStateOfStyleInComputedStyle(style, selectionStyle.get());
@@ -890,7 +893,7 @@ TriState Editor::selectionHasStyle(CSSStyleDeclaration* style) const
if (!m_frame->selection()->isRange()) {
Node* nodeToRemove;
- RefPtr<CSSComputedStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove);
+ RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
if (!selectionStyle)
return FalseTriState;
state = triStateOfStyleInComputedStyle(style, selectionStyle.get());
@@ -938,7 +941,7 @@ static bool hasTransparentBackgroundColor(CSSStyleDeclaration* style)
String Editor::selectionStartCSSPropertyValue(int propertyID)
{
Node* nodeToRemove;
- RefPtr<CSSStyleDeclaration> selectionStyle = m_frame->selectionComputedStyle(nodeToRemove);
+ RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
if (!selectionStyle)
return String();
@@ -965,6 +968,14 @@ String Editor::selectionStartCSSPropertyValue(int propertyID)
}
}
+ if (propertyID == CSSPropertyFontSize) {
+ RefPtr<CSSValue> value = selectionStyle->getPropertyCSSValue(CSSPropertyFontSize);
+ ASSERT(value->isPrimitiveValue());
+ int fontPixelSize = static_cast<CSSPrimitiveValue*>(value.get())->getIntValue(CSSPrimitiveValue::CSS_PX);
+ int size = CSSStyleSelector::legacyFontSize(m_frame->document(), fontPixelSize, selectionStyle->useFixedFontDefaultSize());
+ return String::number(size);
+ }
+
return value;
}
@@ -1054,6 +1065,7 @@ Editor::Editor(Frame* frame)
, m_shouldStyleWithCSS(false)
, m_killRing(adoptPtr(new KillRing))
, m_correctionPanelTimer(this, &Editor::correctionPanelTimerFired)
+ , m_areMarkedTextMatchesHighlighted(false)
{
}
@@ -1151,7 +1163,7 @@ void Editor::cut()
RefPtr<Range> selection = selectedRange();
if (shouldDeleteRange(selection.get())) {
if (isNodeInTextFormControl(m_frame->selection()->start().node()))
- Pasteboard::generalPasteboard()->writePlainText(m_frame->selectedText());
+ Pasteboard::generalPasteboard()->writePlainText(selectedText());
else
Pasteboard::generalPasteboard()->writeSelection(selection.get(), canSmartCopyOrDelete(), m_frame);
didWriteSelectionToPasteboard();
@@ -1169,7 +1181,7 @@ void Editor::copy()
}
if (isNodeInTextFormControl(m_frame->selection()->start().node()))
- Pasteboard::generalPasteboard()->writePlainText(m_frame->selectedText());
+ Pasteboard::generalPasteboard()->writePlainText(selectedText());
else {
Document* document = m_frame->document();
if (HTMLImageElement* imageElement = imageElementFromImageDocument(document))
@@ -1190,7 +1202,7 @@ void Editor::paste()
return; // DHTML did the whole operation
if (!canPaste())
return;
- DocLoader* loader = m_frame->document()->docLoader();
+ CachedResourceLoader* loader = m_frame->document()->cachedResourceLoader();
loader->setAllowStaleResources(true);
if (m_frame->selection()->isContentRichlyEditable())
pasteWithPasteboard(Pasteboard::generalPasteboard(), true);
@@ -1625,7 +1637,7 @@ void Editor::ignoreSpelling()
if (selectedRange)
frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
- String text = frame()->selectedText();
+ String text = selectedText();
ASSERT(text.length());
client()->ignoreWordInSpellDocument(text);
}
@@ -1638,7 +1650,7 @@ void Editor::learnSpelling()
// FIXME: We don't call this on the Mac, and it should remove misspelling markers around the
// learned word, see <rdar://problem/5396072>.
- String text = frame()->selectedText();
+ String text = selectedText();
ASSERT(text.length());
client()->learnWord(text);
}
@@ -2140,7 +2152,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
bool Editor::isSelectionMisspelled()
{
- String selectedString = frame()->selectedText();
+ String selectedString = selectedText();
int length = selectedString.length();
if (!length)
return false;
@@ -2236,7 +2248,7 @@ Vector<String> Editor::guessesForUngrammaticalSelection()
Vector<String> Editor::guessesForMisspelledSelection()
{
- String selectedString = frame()->selectedText();
+ String selectedString = selectedText();
ASSERT(selectedString.length());
Vector<String> guesses;
@@ -2353,6 +2365,29 @@ bool Editor::spellingPanelIsShowing()
return client()->spellingUIIsShowing();
}
+void Editor::clearMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
+{
+ RefPtr<Range> selectedRange = movingSelection.toNormalizedRange();
+ if (selectedRange) {
+ frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
+ frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Grammar);
+ }
+}
+
+void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
+{
+ bool markSpelling = isContinuousSpellCheckingEnabled();
+ bool markGrammar = markSpelling && isGrammarCheckingEnabled();
+
+ if (markSpelling) {
+ RefPtr<Range> unusedFirstMisspellingRange;
+ markMisspellings(movingSelection, unusedFirstMisspellingRange);
+ }
+
+ if (markGrammar)
+ markBadGrammar(movingSelection);
+}
+
void Editor::markMisspellingsAfterTypingToPosition(const VisiblePosition &p)
{
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
@@ -3104,4 +3139,456 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, b
client()->respondToChangedSelection();
}
+String Editor::selectedText() const
+{
+ return plainText(m_frame->selection()->toNormalizedRange().get());
+}
+
+IntRect Editor::firstRectForRange(Range* range) const
+{
+ int extraWidthToEndOfLine = 0;
+ ASSERT(range->startContainer());
+ ASSERT(range->endContainer());
+
+ InlineBox* startInlineBox;
+ int startCaretOffset;
+ Position startPosition = VisiblePosition(range->startPosition()).deepEquivalent();
+ if (startPosition.isNull())
+ return IntRect();
+ startPosition.getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
+
+ RenderObject* startRenderer = startPosition.node()->renderer();
+ ASSERT(startRenderer);
+ IntRect startCaretRect = startRenderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
+ if (startCaretRect != IntRect())
+ startCaretRect = startRenderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();
+
+ InlineBox* endInlineBox;
+ int endCaretOffset;
+ Position endPosition = VisiblePosition(range->endPosition()).deepEquivalent();
+ if (endPosition.isNull())
+ return IntRect();
+ endPosition.getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
+
+ RenderObject* endRenderer = endPosition.node()->renderer();
+ ASSERT(endRenderer);
+ IntRect endCaretRect = endRenderer->localCaretRect(endInlineBox, endCaretOffset);
+ if (endCaretRect != IntRect())
+ endCaretRect = endRenderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();
+
+ if (startCaretRect.y() == endCaretRect.y()) {
+ // start and end are on the same line
+ return IntRect(min(startCaretRect.x(), endCaretRect.x()),
+ startCaretRect.y(),
+ abs(endCaretRect.x() - startCaretRect.x()),
+ max(startCaretRect.height(), endCaretRect.height()));
+ }
+
+ // start and end aren't on the same line, so go from start to the end of its line
+ return IntRect(startCaretRect.x(),
+ startCaretRect.y(),
+ startCaretRect.width() + extraWidthToEndOfLine,
+ startCaretRect.height());
+}
+
+bool Editor::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
+{
+ return client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting);
+}
+
+void Editor::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
+{
+ if (!style || !style->length()) {
+ m_frame->clearTypingStyle();
+ return;
+ }
+
+ // Calculate the current typing style.
+ RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
+ if (m_frame->typingStyle()) {
+ m_frame->typingStyle()->merge(mutableStyle.get());
+ mutableStyle = m_frame->typingStyle();
+ }
+
+ RefPtr<CSSValue> unicodeBidi;
+ RefPtr<CSSValue> direction;
+ if (editingAction == EditActionSetWritingDirection) {
+ unicodeBidi = mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+ direction = mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
+ }
+
+ Node* node = m_frame->selection()->selection().visibleStart().deepEquivalent().node();
+ computedStyle(node)->diff(mutableStyle.get());
+
+ if (editingAction == EditActionSetWritingDirection && unicodeBidi) {
+ ASSERT(unicodeBidi->isPrimitiveValue());
+ mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
+ if (direction) {
+ ASSERT(direction->isPrimitiveValue());
+ mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
+ }
+ }
+
+ // Handle block styles, substracting these from the typing style.
+ RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
+ blockStyle->diff(mutableStyle.get());
+ if (blockStyle->length() > 0)
+ applyCommand(ApplyStyleCommand::create(m_frame->document(), blockStyle.get(), editingAction));
+
+ // Set the remaining style as the typing style.
+ m_frame->setTypingStyle(mutableStyle.get());
+}
+
+PassRefPtr<CSSComputedStyleDeclaration> Editor::selectionComputedStyle(Node*& nodeToRemove) const
+{
+ nodeToRemove = 0;
+
+ if (m_frame->selection()->isNone())
+ return 0;
+
+ RefPtr<Range> range(m_frame->selection()->toNormalizedRange());
+ Position position = range->editingStartPosition();
+
+ // If the pos is at the end of a text node, then this node is not fully selected.
+ // Move it to the next deep equivalent position to avoid removing the style from this node.
+ // e.g. if pos was at Position("hello", 5) in <b>hello<div>world</div></b>, we want Position("world", 0) instead.
+ // We only do this for range because caret at Position("hello", 5) in <b>hello</b>world should give you font-weight: bold.
+ Node* positionNode = position.containerNode();
+ if (m_frame->selection()->isRange() && positionNode && positionNode->isTextNode() && position.computeOffsetInContainerNode() == positionNode->maxCharacterOffset())
+ position = nextVisuallyDistinctCandidate(position);
+
+ Element* element = position.element();
+ if (!element)
+ return 0;
+
+ RefPtr<Element> styleElement = element;
+ ExceptionCode ec = 0;
+
+ if (m_frame->typingStyle()) {
+ styleElement = m_frame->document()->createElement(spanTag, false);
+
+ styleElement->setAttribute(styleAttr, m_frame->typingStyle()->cssText().impl(), ec);
+ ASSERT(!ec);
+
+ styleElement->appendChild(m_frame->document()->createEditingTextNode(""), ec);
+ ASSERT(!ec);
+
+ if (element->renderer() && element->renderer()->canHaveChildren())
+ element->appendChild(styleElement, ec);
+ else {
+ Node* parent = element->parent();
+ Node* next = element->nextSibling();
+
+ if (next)
+ parent->insertBefore(styleElement, next, ec);
+ else
+ parent->appendChild(styleElement, ec);
+ }
+ ASSERT(!ec);
+
+ nodeToRemove = styleElement.get();
+ }
+
+ return computedStyle(styleElement.release());
+}
+
+void Editor::textFieldDidBeginEditing(Element* e)
+{
+ if (client())
+ client()->textFieldDidBeginEditing(e);
+}
+
+void Editor::textFieldDidEndEditing(Element* e)
+{
+ if (client())
+ client()->textFieldDidEndEditing(e);
+}
+
+void Editor::textDidChangeInTextField(Element* e)
+{
+ if (client())
+ client()->textDidChangeInTextField(e);
+}
+
+bool Editor::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
+{
+ if (client())
+ return client()->doTextFieldCommandFromEvent(e, ke);
+
+ return false;
+}
+
+void Editor::textWillBeDeletedInTextField(Element* input)
+{
+ if (client())
+ client()->textWillBeDeletedInTextField(input);
+}
+
+void Editor::textDidChangeInTextArea(Element* e)
+{
+ if (client())
+ client()->textDidChangeInTextArea(e);
+}
+
+void Editor::applyEditingStyleToBodyElement() const
+{
+ RefPtr<NodeList> list = m_frame->document()->getElementsByTagName("body");
+ unsigned len = list->length();
+ for (unsigned i = 0; i < len; i++)
+ applyEditingStyleToElement(static_cast<Element*>(list->item(i)));
+}
+
+void Editor::applyEditingStyleToElement(Element* element) const
+{
+ if (!element)
+ return;
+
+ CSSStyleDeclaration* style = element->style();
+ ASSERT(style);
+
+ ExceptionCode ec = 0;
+ style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);
+ ASSERT(!ec);
+ style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);
+ ASSERT(!ec);
+ style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
+ ASSERT(!ec);
+}
+
+RenderStyle* Editor::styleForSelectionStart(Node *&nodeToRemove) const
+{
+ nodeToRemove = 0;
+
+ if (m_frame->selection()->isNone())
+ return 0;
+
+ Position position = m_frame->selection()->selection().visibleStart().deepEquivalent();
+ if (!position.isCandidate())
+ return 0;
+ if (!position.node())
+ return 0;
+
+ if (!m_frame->typingStyle())
+ return position.node()->renderer()->style();
+
+ RefPtr<Element> styleElement = m_frame->document()->createElement(spanTag, false);
+
+ ExceptionCode ec = 0;
+ String styleText = m_frame->typingStyle()->cssText() + " display: inline";
+ styleElement->setAttribute(styleAttr, styleText.impl(), ec);
+ ASSERT(!ec);
+
+ styleElement->appendChild(m_frame->document()->createEditingTextNode(""), ec);
+ ASSERT(!ec);
+
+ position.node()->parentNode()->appendChild(styleElement, ec);
+ ASSERT(!ec);
+
+ nodeToRemove = styleElement.get();
+ return styleElement->renderer() ? styleElement->renderer()->style() : 0;
+}
+
+// Searches from the beginning of the document if nothing is selected.
+bool Editor::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
+{
+ if (target.isEmpty())
+ return false;
+
+ if (m_frame->excludeFromTextSearch())
+ return false;
+
+ // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
+ // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
+ RefPtr<Range> searchRange(rangeOfContents(m_frame->document()));
+ VisibleSelection selection = m_frame->selection()->selection();
+
+ if (forward)
+ setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
+ else
+ setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
+
+ RefPtr<Node> shadowTreeRoot = selection.shadowTreeRootNode();
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
+ if (forward)
+ searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount(), ec);
+ else
+ searchRange->setStart(shadowTreeRoot.get(), 0, ec);
+ }
+
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
+ // If we started in the selection and the found range exactly matches the existing selection, find again.
+ // Build a selection with the found range to remove collapsed whitespace.
+ // Compare ranges instead of selection objects to ignore the way that the current selection was made.
+ if (startInSelection && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), selection.toNormalizedRange().get())) {
+ searchRange = rangeOfContents(m_frame->document());
+ if (forward)
+ setStart(searchRange.get(), selection.visibleEnd());
+ else
+ setEnd(searchRange.get(), selection.visibleStart());
+
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
+ if (forward)
+ searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount(), ec);
+ else
+ searchRange->setStart(shadowTreeRoot.get(), 0, ec);
+ }
+
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ }
+
+ ExceptionCode exception = 0;
+
+ // If nothing was found in the shadow tree, search in main content following the shadow tree.
+ if (resultRange->collapsed(exception) && shadowTreeRoot) {
+ searchRange = rangeOfContents(m_frame->document());
+ if (forward)
+ searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception);
+ else
+ searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
+
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ }
+
+ if (!insideVisibleArea(resultRange.get())) {
+ resultRange = nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
+ if (!resultRange)
+ return false;
+ }
+
+ // If we didn't find anything and we're wrapping, search again in the entire document (this will
+ // redundantly re-search the area already searched in some cases).
+ if (resultRange->collapsed(exception) && wrapFlag) {
+ searchRange = rangeOfContents(m_frame->document());
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ // We used to return false here if we ended up with the same range that we started with
+ // (e.g., the selection was already the only instance of this text). But we decided that
+ // this should be a success case instead, so we'll just fall through in that case.
+ }
+
+ if (resultRange->collapsed(exception))
+ return false;
+
+ m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
+ m_frame->revealSelection();
+ return true;
+}
+
+unsigned Editor::countMatchesForText(const String& target, bool caseFlag, unsigned limit, bool markMatches)
+{
+ if (target.isEmpty())
+ return 0;
+
+ RefPtr<Range> searchRange(rangeOfContents(m_frame->document()));
+
+ ExceptionCode exception = 0;
+ unsigned matchCount = 0;
+ do {
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
+ if (resultRange->collapsed(exception)) {
+ if (!resultRange->startContainer()->isInShadowTree())
+ break;
+
+ searchRange = rangeOfContents(m_frame->document());
+ searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception);
+ continue;
+ }
+
+ // Only treat the result as a match if it is visible
+ if (insideVisibleArea(resultRange.get())) {
+ ++matchCount;
+ if (markMatches)
+ m_frame->document()->markers()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ }
+
+ // Stop looking if we hit the specified limit. A limit of 0 means no limit.
+ if (limit > 0 && matchCount >= limit)
+ break;
+
+ // Set the new start for the search range to be the end of the previous
+ // result range. There is no need to use a VisiblePosition here,
+ // since findPlainText will use a TextIterator to go over the visible
+ // text nodes.
+ searchRange->setStart(resultRange->endContainer(exception), resultRange->endOffset(exception), exception);
+
+ Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
+ if (searchRange->collapsed(exception) && shadowTreeRoot)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
+ } while (true);
+
+ if (markMatches) {
+ // Do a "fake" paint in order to execute the code that computes the rendered rect for each text match.
+ if (m_frame->view() && m_frame->contentRenderer()) {
+ m_frame->document()->updateLayout(); // Ensure layout is up to date.
+ IntRect visibleRect = m_frame->view()->visibleContentRect();
+ if (!visibleRect.isEmpty()) {
+ GraphicsContext context((PlatformGraphicsContext*)0);
+ context.setPaintingDisabled(true);
+ m_frame->view()->paintContents(&context, visibleRect);
+ }
+ }
+ }
+
+ return matchCount;
+}
+
+void Editor::setMarkedTextMatchesAreHighlighted(bool flag)
+{
+ if (flag == m_areMarkedTextMatchesHighlighted)
+ return;
+
+ m_areMarkedTextMatchesHighlighted = flag;
+ m_frame->document()->markers()->repaintMarkers(DocumentMarker::TextMatch);
+}
+
+void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping)
+{
+ bool isContinuousSpellCheckingEnabled = this->isContinuousSpellCheckingEnabled();
+ bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && isGrammarCheckingEnabled();
+ if (isContinuousSpellCheckingEnabled) {
+ VisibleSelection newAdjacentWords;
+ VisibleSelection newSelectedSentence;
+ bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
+ if (m_frame->selection()->selection().isContentEditable() || caretBrowsing) {
+ VisiblePosition newStart(m_frame->selection()->selection().visibleStart());
+ newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
+ if (isContinuousGrammarCheckingEnabled)
+ newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
+ }
+
+ // When typing we check spelling elsewhere, so don't redo it here.
+ // If this is a change in selection resulting from a delete operation,
+ // oldSelection may no longer be in the document.
+ if (closeTyping && oldSelection.isContentEditable() && oldSelection.start().node() && oldSelection.start().node()->inDocument()) {
+ VisiblePosition oldStart(oldSelection.visibleStart());
+ VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
+ if (oldAdjacentWords != newAdjacentWords) {
+ if (isContinuousGrammarCheckingEnabled) {
+ VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
+ markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence);
+ } else
+ markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
+ }
+ }
+
+ // This only erases markers that are in the first unit (word or sentence) of the selection.
+ // Perhaps peculiar, but it matches AppKit.
+ if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange()) {
+ m_frame->document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
+ m_frame->document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Replacement);
+ }
+ if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
+ m_frame->document()->markers()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
+ }
+
+ // When continuous spell checking is off, existing markers disappear after the selection changes.
+ if (!isContinuousSpellCheckingEnabled)
+ m_frame->document()->markers()->removeMarkers(DocumentMarker::Spelling);
+ if (!isContinuousGrammarCheckingEnabled)
+ m_frame->document()->markers()->removeMarkers(DocumentMarker::Grammar);
+
+ respondToChangedSelection(oldSelection);
+}
+
} // namespace WebCore
diff --git a/WebCore/editing/Editor.h b/WebCore/editing/Editor.h
index 78e89b4..2c06cea 100644
--- a/WebCore/editing/Editor.h
+++ b/WebCore/editing/Editor.h
@@ -34,6 +34,11 @@
#include "EditorInsertAction.h"
#include "SelectionController.h"
+#if PLATFORM(MAC) && !defined(__OBJC__)
+class NSDictionary;
+typedef int NSWritingDirection;
+#endif
+
namespace WebCore {
class CSSStyleDeclaration;
@@ -314,14 +319,52 @@ public:
// This is only called on the mac where paste is implemented primarily at the WebKit level.
void pasteAsPlainTextBypassingDHTML();
+
+ void clearMisspellingsAndBadGrammar(const VisibleSelection&);
+ void markMisspellingsAndBadGrammar(const VisibleSelection&);
Node* findEventTargetFrom(const VisibleSelection& selection) const;
+
+ String selectedText() const;
+ bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
+
+ const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
+ void setMark(const VisibleSelection&);
+
+ void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
+ void applyEditingStyleToBodyElement() const;
+ void applyEditingStyleToElement(Element*) const;
+
+ IntRect firstRectForRange(Range*) const;
+
+ void respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping);
+ bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
+
+ RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
+
+ unsigned countMatchesForText(const String&, bool caseFlag, unsigned limit, bool markMatches);
+ bool markedTextMatchesAreHighlighted() const;
+ void setMarkedTextMatchesAreHighlighted(bool);
+
+ PassRefPtr<CSSComputedStyleDeclaration> selectionComputedStyle(Node*& nodeToRemove) const;
+
+ void textFieldDidBeginEditing(Element*);
+ void textFieldDidEndEditing(Element*);
+ void textDidChangeInTextField(Element*);
+ bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
+ void textWillBeDeletedInTextField(Element* input);
+ void textDidChangeInTextArea(Element*);
+
+#if PLATFORM(MAC)
+ NSDictionary* fontAttributesForSelectionStart() const;
+ NSWritingDirection baseWritingDirectionForSelectionStart() const;
+#endif
+
private:
Frame* m_frame;
OwnPtr<DeleteButtonController> m_deleteButtonController;
RefPtr<EditCommand> m_lastEditCommand;
RefPtr<Node> m_removedAnchor;
-
RefPtr<Text> m_compositionNode;
unsigned m_compositionStart;
unsigned m_compositionEnd;
@@ -333,6 +376,8 @@ private:
RefPtr<Range> m_rangeToBeReplacedByCorrection;
String m_stringToBeReplacedByCorrection;
Timer<Editor> m_correctionPanelTimer;
+ VisibleSelection m_mark;
+ bool m_areMarkedTextMatchesHighlighted;
bool canDeleteRange(Range*) const;
bool canSmartReplaceWithPasteboard(Pasteboard*);
@@ -361,6 +406,22 @@ inline void Editor::setStartNewKillRingSequence(bool flag)
m_shouldStartNewKillRingSequence = flag;
}
+inline const VisibleSelection& Editor::mark() const
+{
+ return m_mark;
+}
+
+inline void Editor::setMark(const VisibleSelection& selection)
+{
+ m_mark = selection;
+}
+
+inline bool Editor::markedTextMatchesAreHighlighted() const
+{
+ return m_areMarkedTextMatchesHighlighted;
+}
+
+
} // namespace WebCore
#endif // Editor_h
diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp
index 4b8da0e..4f53ae9 100644
--- a/WebCore/editing/EditorCommand.cpp
+++ b/WebCore/editing/EditorCommand.cpp
@@ -132,7 +132,10 @@ static bool executeToggleStyleInList(Frame* frame, EditorCommandSource source, E
{
ExceptionCode ec = 0;
Node* nodeToRemove = 0;
- RefPtr<CSSComputedStyleDeclaration> selectionStyle = frame->selectionComputedStyle(nodeToRemove);
+ RefPtr<CSSComputedStyleDeclaration> selectionStyle = frame->editor()->selectionComputedStyle(nodeToRemove);
+ if (!selectionStyle)
+ return false;
+
RefPtr<CSSValue> selectedCSSValue = selectionStyle->getPropertyCSSValue(propertyID);
String newStyle = "none";
if (selectedCSSValue->isValueList()) {
@@ -375,7 +378,7 @@ static bool executeDeleteToEndOfParagraph(Frame* frame, Event*, EditorCommandSou
static bool executeDeleteToMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<Range> mark = frame->mark().toNormalizedRange();
+ RefPtr<Range> mark = frame->editor()->mark().toNormalizedRange();
if (mark) {
SelectionController* selection = frame->selection();
bool selected = selection->setSelectedRange(unionDOMRanges(mark.get(), frame->editor()->selectedRange().get()).get(), DOWNSTREAM, true);
@@ -384,7 +387,7 @@ static bool executeDeleteToMark(Frame* frame, Event*, EditorCommandSource, const
return false;
}
frame->editor()->performDelete();
- frame->setMark(frame->selection()->selection());
+ frame->editor()->setMark(frame->selection()->selection());
return true;
}
@@ -402,7 +405,7 @@ static bool executeDeleteWordForward(Frame* frame, Event*, EditorCommandSource,
static bool executeFindString(Frame* frame, Event*, EditorCommandSource, const String& value)
{
- return frame->findString(value, true, false, true, false);
+ return frame->editor()->findString(value, true, false, true, false);
}
static bool executeFontName(Frame* frame, Event*, EditorCommandSource source, const String& value)
@@ -951,7 +954,7 @@ static bool executeSelectSentence(Frame* frame, Event*, EditorCommandSource, con
static bool executeSelectToMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<Range> mark = frame->mark().toNormalizedRange();
+ RefPtr<Range> mark = frame->editor()->mark().toNormalizedRange();
RefPtr<Range> selection = frame->editor()->selectedRange();
if (!mark || !selection) {
systemBeep();
@@ -968,7 +971,7 @@ static bool executeSelectWord(Frame* frame, Event*, EditorCommandSource, const S
static bool executeSetMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- frame->setMark(frame->selection()->selection());
+ frame->editor()->setMark(frame->selection()->selection());
return true;
}
@@ -999,14 +1002,14 @@ static bool executeSuperscript(Frame* frame, Event*, EditorCommandSource source,
static bool executeSwapWithMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- const VisibleSelection& mark = frame->mark();
+ const VisibleSelection& mark = frame->editor()->mark();
const VisibleSelection& selection = frame->selection()->selection();
if (mark.isNone() || selection.isNone()) {
systemBeep();
return false;
}
frame->selection()->setSelection(mark);
- frame->setMark(selection);
+ frame->editor()->setMark(selection);
return true;
}
@@ -1150,7 +1153,7 @@ static bool enabledVisibleSelectionAndMark(Frame* frame, Event* event, EditorCom
{
const VisibleSelection& selection = frame->editor()->selectionForCommand(event);
return ((selection.isCaret() && selection.isContentEditable()) || selection.isRange())
- && frame->mark().isCaretOrRange();
+ && frame->editor()->mark().isCaretOrRange();
}
static bool enableCaretInEditableText(Frame* frame, Event* event, EditorCommandSource)
diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp
index 97dde55..99b2224 100644
--- a/WebCore/editing/SelectionController.cpp
+++ b/WebCore/editing/SelectionController.cpp
@@ -163,7 +163,7 @@ void SelectionController::setSelection(const VisibleSelection& s, bool closeTypi
m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
selectFrameElementInParentIfFullySelected();
m_frame->notifyRendererOfSelectionChange(userTriggered);
- m_frame->respondToChangedSelection(oldSelection, closeTyping);
+ m_frame->editor()->respondToChangedSelection(oldSelection, closeTyping);
if (userTriggered) {
ScrollAlignment alignment;
diff --git a/WebCore/editing/mac/EditorMac.mm b/WebCore/editing/mac/EditorMac.mm
index 2c5a602..ac658c8 100644
--- a/WebCore/editing/mac/EditorMac.mm
+++ b/WebCore/editing/mac/EditorMac.mm
@@ -26,10 +26,12 @@
#import "config.h"
#import "Editor.h"
+#import "ColorMac.h"
#import "ClipboardMac.h"
-#import "DocLoader.h"
+#import "CachedResourceLoader.h"
#import "Frame.h"
#import "FrameView.h"
+#import "RenderBlock.h"
namespace WebCore {
@@ -63,10 +65,109 @@ void Editor::paste()
FrameView* view = m_frame->view();
if (!view)
return;
- DocLoader* loader = m_frame->document()->docLoader();
+ CachedResourceLoader* loader = m_frame->document()->cachedResourceLoader();
loader->setAllowStaleResources(true);
[view->documentView() tryToPerform:@selector(paste:) with:nil];
loader->setAllowStaleResources(false);
}
+NSDictionary* Editor::fontAttributesForSelectionStart() const
+{
+ Node* nodeToRemove;
+ RenderStyle* style = styleForSelectionStart(nodeToRemove);
+ if (!style)
+ return nil;
+
+ NSMutableDictionary* result = [NSMutableDictionary dictionary];
+
+ if (style->visitedDependentColor(CSSPropertyBackgroundColor).isValid() && style->visitedDependentColor(CSSPropertyBackgroundColor).alpha() != 0)
+ [result setObject:nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
+
+ if (style->font().primaryFont()->getNSFont())
+ [result setObject:style->font().primaryFont()->getNSFont() forKey:NSFontAttributeName];
+
+ if (style->visitedDependentColor(CSSPropertyColor).isValid() && style->visitedDependentColor(CSSPropertyColor) != Color::black)
+ [result setObject:nsColor(style->visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
+
+ const ShadowData* shadow = style->textShadow();
+ if (shadow) {
+ NSShadow* s = [[NSShadow alloc] init];
+ [s setShadowOffset:NSMakeSize(shadow->x(), shadow->y())];
+ [s setShadowBlurRadius:shadow->blur()];
+ [s setShadowColor:nsColor(shadow->color())];
+ [result setObject:s forKey:NSShadowAttributeName];
+ }
+
+ int decoration = style->textDecorationsInEffect();
+ if (decoration & LINE_THROUGH)
+ [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName];
+
+ int superscriptInt = 0;
+ switch (style->verticalAlign()) {
+ case BASELINE:
+ case BOTTOM:
+ case BASELINE_MIDDLE:
+ case LENGTH:
+ case MIDDLE:
+ case TEXT_BOTTOM:
+ case TEXT_TOP:
+ case TOP:
+ break;
+ case SUB:
+ superscriptInt = -1;
+ break;
+ case SUPER:
+ superscriptInt = 1;
+ break;
+ }
+ if (superscriptInt)
+ [result setObject:[NSNumber numberWithInt:superscriptInt] forKey:NSSuperscriptAttributeName];
+
+ if (decoration & UNDERLINE)
+ [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
+
+ if (nodeToRemove) {
+ ExceptionCode ec = 0;
+ nodeToRemove->remove(ec);
+ ASSERT(ec == 0);
+ }
+
+ return result;
+}
+
+NSWritingDirection Editor::baseWritingDirectionForSelectionStart() const
+{
+ NSWritingDirection result = NSWritingDirectionLeftToRight;
+
+ Position pos = m_frame->selection()->selection().visibleStart().deepEquivalent();
+ Node* node = pos.node();
+ if (!node)
+ return result;
+
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return result;
+
+ if (!renderer->isBlockFlow()) {
+ renderer = renderer->containingBlock();
+ if (!renderer)
+ return result;
+ }
+
+ RenderStyle* style = renderer->style();
+ if (!style)
+ return result;
+
+ switch (style->direction()) {
+ case LTR:
+ result = NSWritingDirectionLeftToRight;
+ break;
+ case RTL:
+ result = NSWritingDirectionRightToLeft;
+ break;
+ }
+
+ return result;
+}
+
} // namespace WebCore
diff --git a/WebCore/editing/markup.cpp b/WebCore/editing/markup.cpp
index 7bf85a4..d4996ea 100644
--- a/WebCore/editing/markup.cpp
+++ b/WebCore/editing/markup.cpp
@@ -147,51 +147,75 @@ typedef HashMap<AtomicStringImpl*, AtomicStringImpl*> Namespaces;
class MarkupAccumulator {
public:
- enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
-
- MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, const Range* range = 0)
+ MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, const Range* range = 0)
: m_nodes(nodes)
- , m_shouldResolveURLs(shouldResolveURLs)
- , m_shouldAnnotate(shouldAnnotate)
, m_range(range)
+ , m_shouldResolveURLs(shouldResolveURLs)
{
}
+ virtual ~MarkupAccumulator() {}
void appendString(const String&);
void appendStartTag(Node*, Namespaces* = 0);
void appendEndTag(Node*);
- void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
- void wrapWithStyleNode(CSSStyleDeclaration*, Document*, bool isBlock = false);
- String takeResults();
+ virtual String takeResults();
-private:
+protected:
void appendAttributeValue(Vector<UChar>& result, const String& attribute, bool documentIsHTML);
void appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString);
- String stringValueForRange(const Node*, const Range*);
void appendNodeValue(Vector<UChar>& out, const Node*, const Range*, EntityMask);
- String renderedText(const Node*, const Range*);
bool shouldAddNamespaceElement(const Element*);
- bool shouldAddNamespaceAttribute(const Attribute*, Namespaces&);
+ bool shouldAddNamespaceAttribute(const Attribute&, Namespaces&);
void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
- void appendText(Vector<UChar>& out, Text*);
+ EntityMask entityMaskForText(Text* text) const;
+ virtual void appendText(Vector<UChar>& out, Text*);
void appendComment(Vector<UChar>& out, const String& comment);
void appendDocumentType(Vector<UChar>& result, const DocumentType*);
void appendProcessingInstruction(Vector<UChar>& out, const String& target, const String& data);
- void removeExteriorStyles(CSSMutableStyleDeclaration*);
- void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, Namespaces*, RangeFullySelectsNode);
+ virtual void appendElement(Vector<UChar>& out, Element*, Namespaces*);
+ void appendOpenTag(Vector<UChar>& out, Element* element, Namespaces*);
+ void appendCloseTag(Vector<UChar>& out, Element* element);
+ void appendAttribute(Vector<UChar>& out, Element* element, const Attribute&, Namespaces*);
void appendCDATASection(Vector<UChar>& out, const String& section);
- void appendStartMarkup(Vector<UChar>& result, const Node*, bool convertBlocksToInlines, Namespaces*, RangeFullySelectsNode);
+ void appendStartMarkup(Vector<UChar>& result, const Node*, Namespaces*);
bool shouldSelfClose(const Node*);
void appendEndMarkup(Vector<UChar>& result, const Node*);
bool shouldResolveURLs() { return m_shouldResolveURLs == AbsoluteURLs; }
- bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
Vector<Node*>* const m_nodes;
- const bool m_shouldResolveURLs;
- const EAnnotateForInterchange m_shouldAnnotate;
const Range* const m_range;
- Vector<String> m_reversedPrecedingMarkup;
Vector<String> m_succeedingMarkup;
+
+private:
+ const bool m_shouldResolveURLs;
+};
+
+class StyledMarkupAccumulator : public MarkupAccumulator {
+public:
+ enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
+
+ StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, const Range* range)
+ : MarkupAccumulator(nodes, shouldResolveURLs, range)
+ , m_shouldAnnotate(shouldAnnotate)
+ {
+ }
+ void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
+ void wrapWithStyleNode(CSSStyleDeclaration*, Document*, bool isBlock = false);
+ String takeResults();
+
+protected:
+ virtual void appendText(Vector<UChar>& out, Text*);
+ String renderedText(const Node*, const Range*);
+ String stringValueForRange(const Node*, const Range*);
+ void removeExteriorStyles(CSSMutableStyleDeclaration*);
+ void appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode);
+ void appendElement(Vector<UChar>& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
+
+ bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
+
+private:
+ Vector<String> m_reversedPrecedingMarkup;
+ const EAnnotateForInterchange m_shouldAnnotate;
};
void MarkupAccumulator::appendString(const String& string)
@@ -202,7 +226,7 @@ void MarkupAccumulator::appendString(const String& string)
void MarkupAccumulator::appendStartTag(Node* node, Namespaces* namespaces)
{
Vector<UChar> markup;
- appendStartMarkup(markup, node, false, namespaces, DoesFullySelectNode);
+ appendStartMarkup(markup, node, namespaces);
m_succeedingMarkup.append(String::adopt(markup));
if (m_nodes)
m_nodes->append(node);
@@ -215,17 +239,20 @@ void MarkupAccumulator::appendEndTag(Node* node)
m_succeedingMarkup.append(String::adopt(markup));
}
-void MarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
+void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
{
Vector<UChar> markup;
- appendStartMarkup(markup, node, convertBlocksToInlines, 0, rangeFullySelectsNode);
+ if (node->isElementNode())
+ appendElement(markup, static_cast<Element*>(node), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode);
+ else
+ appendStartMarkup(markup, node, 0);
m_reversedPrecedingMarkup.append(String::adopt(markup));
appendEndTag(node);
if (m_nodes)
m_nodes->append(node);
}
-
-void MarkupAccumulator::wrapWithStyleNode(CSSStyleDeclaration* style, Document* document, bool isBlock)
+
+void StyledMarkupAccumulator::wrapWithStyleNode(CSSStyleDeclaration* style, Document* document, bool isBlock)
{
// All text-decoration-related elements should have been treated as special ancestors
// If we ever hit this ASSERT, we should export StyleChange in ApplyStyleCommand and use it here
@@ -250,6 +277,23 @@ String MarkupAccumulator::takeResults()
{
size_t length = 0;
+ size_t postCount = m_succeedingMarkup.size();
+ for (size_t i = 0; i < postCount; ++i)
+ length += m_succeedingMarkup[i].length();
+
+ Vector<UChar> result;
+ result.reserveInitialCapacity(length);
+
+ for (size_t i = 0; i < postCount; ++i)
+ append(result, m_succeedingMarkup[i]);
+
+ return String::adopt(result);
+}
+
+String StyledMarkupAccumulator::takeResults()
+{
+ size_t length = 0;
+
size_t preCount = m_reversedPrecedingMarkup.size();
for (size_t i = 0; i < preCount; ++i)
length += m_reversedPrecedingMarkup[i].length();
@@ -297,10 +341,10 @@ void MarkupAccumulator::appendQuotedURLAttributeValue(Vector<UChar>& result, con
// FIXME: This does not fully match other browsers. Firefox percent-escapes non-ASCII characters for innerHTML.
result.append(quoteChar);
appendAttributeValue(result, urlString, false);
- result.append(quoteChar);
+ result.append(quoteChar);
}
-String MarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
+String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
{
if (!range)
return node->nodeValue();
@@ -330,11 +374,11 @@ void MarkupAccumulator::appendNodeValue(Vector<UChar>& out, const Node* node, co
length -= start;
}
}
-
+
appendCharactersReplacingEntities(out, characters, length, entityMask);
}
-String MarkupAccumulator::renderedText(const Node* node, const Range* range)
+String StyledMarkupAccumulator::renderedText(const Node* node, const Range* range)
{
if (!node->isTextNode())
return String();
@@ -348,7 +392,7 @@ String MarkupAccumulator::renderedText(const Node* node, const Range* range)
startOffset = range->startOffset(ec);
if (range && node == range->endContainer(ec))
endOffset = range->endOffset(ec);
-
+
Position start(const_cast<Node*>(node), startOffset);
Position end(const_cast<Node*>(node), endOffset);
return plainText(Range::create(node->document(), start, end).get());
@@ -395,19 +439,19 @@ bool MarkupAccumulator::shouldAddNamespaceElement(const Element* element)
return !element->hasAttribute(attr);
}
-bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute* attribute, Namespaces& namespaces)
+bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute, Namespaces& namespaces)
{
namespaces.checkConsistency();
// Don't add namespace attributes twice
- if (attribute->name() == XMLNSNames::xmlnsAttr) {
- namespaces.set(emptyAtom.impl(), attribute->value().impl());
+ if (attribute.name() == XMLNSNames::xmlnsAttr) {
+ namespaces.set(emptyAtom.impl(), attribute.value().impl());
return false;
}
- QualifiedName xmlnsPrefixAttr(xmlnsAtom, attribute->localName(), XMLNSNames::xmlnsNamespaceURI);
- if (attribute->name() == xmlnsPrefixAttr) {
- namespaces.set(attribute->localName().impl(), attribute->value().impl());
+ QualifiedName xmlnsPrefixAttr(xmlnsAtom, attribute.localName(), XMLNSNames::xmlnsNamespaceURI);
+ if (attribute.name() == xmlnsPrefixAttr) {
+ namespaces.set(attribute.localName().impl(), attribute.value().impl());
return false;
}
@@ -439,19 +483,27 @@ void MarkupAccumulator::appendNamespace(Vector<UChar>& result, const AtomicStrin
}
}
-void MarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
+EntityMask MarkupAccumulator::entityMaskForText(Text* text) const
{
const QualifiedName* parentName = 0;
if (text->parentElement())
parentName = &static_cast<Element*>(text->parentElement())->tagQName();
+
+ if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag))
+ return EntityMaskInCDATA;
- if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag)) {
- appendNodeValue(out, text, m_range, EntityMaskInCDATA);
- return;
- }
+ return text->document()->isHTMLDocument() ? EntityMaskInHTMLPCDATA : EntityMaskInPCDATA;
+}
+
+void MarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
+{
+ appendNodeValue(out, text, m_range, entityMaskForText(text));
+}
- if (!shouldAnnotate() || (parentName && *parentName == textareaTag)) {
- appendNodeValue(out, text, m_range, text->document()->isHTMLDocument() ? EntityMaskInHTMLPCDATA : EntityMaskInPCDATA);
+void StyledMarkupAccumulator::appendText(Vector<UChar>& out, Text* text)
+{
+ if (!shouldAnnotate() || (text->parentElement() && text->parentElement()->tagQName() == textareaTag)) {
+ MarkupAccumulator::appendText(out, text);
return;
}
@@ -509,18 +561,27 @@ void MarkupAccumulator::appendProcessingInstruction(Vector<UChar>& out, const St
append(out, "?>");
}
-void MarkupAccumulator::removeExteriorStyles(CSSMutableStyleDeclaration* style)
+void StyledMarkupAccumulator::removeExteriorStyles(CSSMutableStyleDeclaration* style)
{
style->removeProperty(CSSPropertyFloat);
}
-void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, Namespaces* namespaces, RangeFullySelectsNode rangeFullySelectsNode)
+void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, Namespaces* namespaces)
+{
+ appendOpenTag(out, element, namespaces);
+
+ NamedNodeMap* attributes = element->attributes();
+ unsigned length = attributes->length();
+ for (unsigned int i = 0; i < length; i++)
+ appendAttribute(out, element, *attributes->attributeItem(i), namespaces);
+
+ appendCloseTag(out, element);
+}
+
+void StyledMarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
{
bool documentIsHTML = element->document()->isHTMLDocument();
- out.append('<');
- append(out, element->nodeNamePreservingCase());
- if (!documentIsHTML && namespaces && shouldAddNamespaceElement(element))
- appendNamespace(out, element->prefix(), element->namespaceURI(), *namespaces);
+ appendOpenTag(out, element, 0);
NamedNodeMap* attributes = element->attributes();
unsigned length = attributes->length();
@@ -529,30 +590,7 @@ void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool
// We'll handle the style attribute separately, below.
if (attribute->name() == styleAttr && element->isHTMLElement() && (shouldAnnotate() || addDisplayInline))
continue;
- out.append(' ');
-
- if (documentIsHTML)
- append(out, attribute->name().localName());
- else
- append(out, attribute->name().toString());
-
- out.append('=');
-
- if (element->isURLAttribute(attribute)) {
- // We don't want to complete file:/// URLs because it may contain sensitive information
- // about the user's system.
- if (shouldResolveURLs() && !element->document()->url().isLocalFile())
- appendQuotedURLAttributeValue(out, element->document()->completeURL(attribute->value()).string());
- else
- appendQuotedURLAttributeValue(out, attribute->value().string());
- } else {
- out.append('\"');
- appendAttributeValue(out, attribute->value(), documentIsHTML);
- out.append('\"');
- }
-
- if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
- appendNamespace(out, attribute->prefix(), attribute->namespaceURI(), *namespaces);
+ appendAttribute(out, element, *attribute, 0);
}
if (element->isHTMLElement() && (shouldAnnotate() || addDisplayInline)) {
@@ -597,6 +635,19 @@ void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool
}
}
+ appendCloseTag(out, element);
+}
+
+void MarkupAccumulator::appendOpenTag(Vector<UChar>& out, Element* element, Namespaces* namespaces)
+{
+ out.append('<');
+ append(out, element->nodeNamePreservingCase());
+ if (!element->document()->isHTMLDocument() && namespaces && shouldAddNamespaceElement(element))
+ appendNamespace(out, element->prefix(), element->namespaceURI(), *namespaces);
+}
+
+void MarkupAccumulator::appendCloseTag(Vector<UChar>& out, Element* element)
+{
if (shouldSelfClose(element)) {
if (element->isHTMLElement())
out.append(' '); // XHTML 1.0 <-> HTML compatibility.
@@ -605,6 +656,36 @@ void MarkupAccumulator::appendElement(Vector<UChar>& out, Element* element, bool
out.append('>');
}
+void MarkupAccumulator::appendAttribute(Vector<UChar>& out, Element* element, const Attribute& attribute, Namespaces* namespaces)
+{
+ bool documentIsHTML = element->document()->isHTMLDocument();
+
+ out.append(' ');
+
+ if (documentIsHTML)
+ append(out, attribute.name().localName());
+ else
+ append(out, attribute.name().toString());
+
+ out.append('=');
+
+ if (element->isURLAttribute(const_cast<Attribute*>(&attribute))) {
+ // We don't want to complete file:/// URLs because it may contain sensitive information
+ // about the user's system.
+ if (shouldResolveURLs() && !element->document()->url().isLocalFile())
+ appendQuotedURLAttributeValue(out, element->document()->completeURL(attribute.value()).string());
+ else
+ appendQuotedURLAttributeValue(out, attribute.value());
+ } else {
+ out.append('\"');
+ appendAttributeValue(out, attribute.value(), documentIsHTML);
+ out.append('\"');
+ }
+
+ if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
+ appendNamespace(out, attribute.prefix(), attribute.namespaceURI(), *namespaces);
+}
+
void MarkupAccumulator::appendCDATASection(Vector<UChar>& out, const String& section)
{
// FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".
@@ -613,7 +694,7 @@ void MarkupAccumulator::appendCDATASection(Vector<UChar>& out, const String& sec
append(out, "]]>");
}
-void MarkupAccumulator::appendStartMarkup(Vector<UChar>& result, const Node* node, bool convertBlocksToInlines, Namespaces* namespaces, RangeFullySelectsNode rangeFullySelectsNode)
+void MarkupAccumulator::appendStartMarkup(Vector<UChar>& result, const Node* node, Namespaces* namespaces)
{
if (namespaces)
namespaces->checkConsistency();
@@ -635,7 +716,7 @@ void MarkupAccumulator::appendStartMarkup(Vector<UChar>& result, const Node* nod
appendProcessingInstruction(result, static_cast<const ProcessingInstruction*>(node)->target(), static_cast<const ProcessingInstruction*>(node)->data());
break;
case Node::ELEMENT_NODE:
- appendElement(result, static_cast<Element*>(const_cast<Node*>(node)), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), namespaces, rangeFullySelectsNode);
+ appendElement(result, static_cast<Element*>(const_cast<Node*>(node)), namespaces);
break;
case Node::CDATA_SECTION_NODE:
appendCDATASection(result, static_cast<const CDATASection*>(node)->data());
@@ -737,56 +818,7 @@ static PassRefPtr<CSSMutableStyleDeclaration> styleFromMatchedRulesAndInlineDecl
return style.release();
}
-static bool propertyMissingOrEqualToNone(CSSStyleDeclaration* style, int propertyID)
-{
- if (!style)
- return false;
- RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
- if (!value)
- return true;
- if (!value->isPrimitiveValue())
- return false;
- return static_cast<CSSPrimitiveValue*>(value.get())->getIdent() == CSSValueNone;
-}
-
-static bool isElementPresentational(const Node* node)
-{
- if (node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName(strikeTag)
- || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag))
- return true;
- RefPtr<CSSMutableStyleDeclaration> style = styleFromMatchedRulesAndInlineDecl(node);
- if (!style)
- return false;
- return !propertyMissingOrEqualToNone(style.get(), CSSPropertyTextDecoration);
-}
-
-static bool isSpecialAncestorBlock(Node* node)
-{
- if (!node || !isBlock(node))
- return false;
-
- return node->hasTagName(listingTag)
- || node->hasTagName(olTag)
- || node->hasTagName(preTag)
- || node->hasTagName(tableTag)
- || node->hasTagName(ulTag)
- || node->hasTagName(xmpTag)
- || node->hasTagName(h1Tag)
- || node->hasTagName(h2Tag)
- || node->hasTagName(h3Tag)
- || node->hasTagName(h4Tag)
- || node->hasTagName(h5Tag);
-}
-
-static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot, CSSMutableStyleDeclaration* style)
-{
- if (fullySelectedRoot->isElementNode() && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
- return true;
-
- return style->getPropertyCSSValue(CSSPropertyBackgroundImage) || style->getPropertyCSSValue(CSSPropertyBackgroundColor);
-}
-
-static Node* serializeNodes(MarkupAccumulator& accumulator, Node* startNode, Node* pastEnd)
+static Node* serializeNodes(StyledMarkupAccumulator& accumulator, Node* startNode, Node* pastEnd)
{
Vector<Node*> ancestorsToClose;
Node* next;
@@ -860,6 +892,110 @@ static Node* serializeNodes(MarkupAccumulator& accumulator, Node* startNode, Nod
return lastClosed;
}
+static Node* ancestorToRetainStructureAndAppearance(Node* commonAncestor)
+{
+ Node* commonAncestorBlock = enclosingBlock(commonAncestor);
+
+ if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
+ Node* table = commonAncestorBlock->parentNode();
+ while (table && !table->hasTagName(tableTag))
+ table = table->parentNode();
+
+ return table;
+ }
+
+ if (commonAncestorBlock->hasTagName(listingTag)
+ || commonAncestorBlock->hasTagName(olTag)
+ || commonAncestorBlock->hasTagName(preTag)
+ || commonAncestorBlock->hasTagName(tableTag)
+ || commonAncestorBlock->hasTagName(ulTag)
+ || commonAncestorBlock->hasTagName(xmpTag)
+ || commonAncestorBlock->hasTagName(h1Tag)
+ || commonAncestorBlock->hasTagName(h2Tag)
+ || commonAncestorBlock->hasTagName(h3Tag)
+ || commonAncestorBlock->hasTagName(h4Tag)
+ || commonAncestorBlock->hasTagName(h5Tag))
+ return commonAncestorBlock;
+
+ return 0;
+}
+
+static bool propertyMissingOrEqualToNone(CSSStyleDeclaration* style, int propertyID)
+{
+ if (!style)
+ return false;
+ RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
+ if (!value)
+ return true;
+ if (!value->isPrimitiveValue())
+ return false;
+ return static_cast<CSSPrimitiveValue*>(value.get())->getIdent() == CSSValueNone;
+}
+
+static bool isElementPresentational(const Node* node)
+{
+ if (node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName(strikeTag)
+ || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName(bTag) || node->hasTagName(strongTag))
+ return true;
+ RefPtr<CSSMutableStyleDeclaration> style = styleFromMatchedRulesAndInlineDecl(node);
+ if (!style)
+ return false;
+ return !propertyMissingOrEqualToNone(style.get(), CSSPropertyTextDecoration);
+}
+
+static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot, CSSMutableStyleDeclaration* style)
+{
+ if (fullySelectedRoot->isElementNode() && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
+ return true;
+
+ return style->getPropertyCSSValue(CSSPropertyBackgroundImage) || style->getPropertyCSSValue(CSSPropertyBackgroundColor);
+}
+
+static Node* highestAncestorToWrapMarkup(const Range* range, Node* fullySelectedRoot, EAnnotateForInterchange shouldAnnotate)
+{
+ ExceptionCode ec;
+ Node* commonAncestor = range->commonAncestorContainer(ec);
+ ASSERT(commonAncestor);
+ Node* specialCommonAncestor = 0;
+ if (shouldAnnotate == AnnotateForInterchange) {
+ // Include ancestors that aren't completely inside the range but are required to retain
+ // the structure and appearance of the copied markup.
+ specialCommonAncestor = ancestorToRetainStructureAndAppearance(commonAncestor);
+
+ // Retain the Mail quote level by including all ancestor mail block quotes.
+ for (Node* ancestor = range->firstNode(); ancestor; ancestor = ancestor->parentNode()) {
+ if (isMailBlockquote(ancestor))
+ specialCommonAncestor = ancestor;
+ }
+ }
+
+ Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
+ if (checkAncestor->renderer()) {
+ Node* newSpecialCommonAncestor = highestEnclosingNodeOfType(Position(checkAncestor, 0), &isElementPresentational);
+ if (newSpecialCommonAncestor)
+ specialCommonAncestor = newSpecialCommonAncestor;
+ }
+
+ // If a single tab is selected, commonAncestor will be a text node inside a tab span.
+ // If two or more tabs are selected, commonAncestor will be the tab span.
+ // In either case, if there is a specialCommonAncestor already, it will necessarily be above
+ // any tab span that needs to be included.
+ if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor))
+ specialCommonAncestor = commonAncestor->parentNode();
+ if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
+ specialCommonAncestor = commonAncestor;
+
+ if (Node *enclosingAnchor = enclosingNodeWithTag(Position(specialCommonAncestor ? specialCommonAncestor : commonAncestor, 0), aTag))
+ specialCommonAncestor = enclosingAnchor;
+
+ if (shouldAnnotate == AnnotateForInterchange && fullySelectedRoot) {
+ RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
+ if (shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot, fullySelectedRootStyle.get()))
+ specialCommonAncestor = fullySelectedRoot;
+ }
+ return specialCommonAncestor;
+}
+
// FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange?
// FIXME: At least, annotation and style info should probably not be included in range.markupString()
String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
@@ -896,7 +1032,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
document->updateLayoutIgnorePendingStylesheets();
- MarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange.get());
+ StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange.get());
Node* pastEnd = updatedRange->pastLastNode();
Node* startNode = updatedRange->firstNode();
@@ -919,63 +1055,22 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
}
}
- Node* lastClosed = serializeNodes(accumulator, startNode, pastEnd);
-
- // Include ancestors that aren't completely inside the range but are required to retain
- // the structure and appearance of the copied markup.
- Node* specialCommonAncestor = 0;
- Node* commonAncestorBlock = commonAncestor ? enclosingBlock(commonAncestor) : 0;
- if (shouldAnnotate == AnnotateForInterchange && commonAncestorBlock) {
- if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
- Node* table = commonAncestorBlock->parentNode();
- while (table && !table->hasTagName(tableTag))
- table = table->parentNode();
- if (table)
- specialCommonAncestor = table;
- } else if (isSpecialAncestorBlock(commonAncestorBlock))
- specialCommonAncestor = commonAncestorBlock;
- }
-
- // Retain the Mail quote level by including all ancestor mail block quotes.
- if (lastClosed && shouldAnnotate == AnnotateForInterchange) {
- for (Node *ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode())
- if (isMailBlockquote(ancestor))
- specialCommonAncestor = ancestor;
- }
-
- Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
- if (checkAncestor->renderer()) {
- Node* newSpecialCommonAncestor = highestEnclosingNodeOfType(Position(checkAncestor, 0), &isElementPresentational);
- if (newSpecialCommonAncestor)
- specialCommonAncestor = newSpecialCommonAncestor;
- }
-
- // If a single tab is selected, commonAncestor will be a text node inside a tab span.
- // If two or more tabs are selected, commonAncestor will be the tab span.
- // In either case, if there is a specialCommonAncestor already, it will necessarily be above
- // any tab span that needs to be included.
- if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor))
- specialCommonAncestor = commonAncestor->parentNode();
- if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
- specialCommonAncestor = commonAncestor;
-
- if (Node *enclosingAnchor = enclosingNodeWithTag(Position(specialCommonAncestor ? specialCommonAncestor : commonAncestor, 0), aTag))
- specialCommonAncestor = enclosingAnchor;
-
Node* body = enclosingNodeWithTag(Position(commonAncestor, 0), bodyTag);
+ Node* fullySelectedRoot = 0;
// FIXME: Do this for all fully selected blocks, not just the body.
- Node* fullySelectedRoot = body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), updatedRange.get()) ? body : 0;
- RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = fullySelectedRoot ? styleFromMatchedRulesAndInlineDecl(fullySelectedRoot) : 0;
- if (shouldAnnotate == AnnotateForInterchange && fullySelectedRoot) {
- if (shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot, fullySelectedRootStyle.get()))
- specialCommonAncestor = fullySelectedRoot;
- }
-
+ if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), range))
+ fullySelectedRoot = body;
+
+ Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange.get(), fullySelectedRoot, shouldAnnotate);
+
+ Node* lastClosed = serializeNodes(accumulator, startNode, pastEnd);
+
if (specialCommonAncestor && lastClosed) {
// Also include all of the ancestors of lastClosed up to this special ancestor.
for (Node* ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
-
+ RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
+
// Bring the background attribute over, but not as an attribute because a background attribute on a div
// appears to have no effect.
if (!fullySelectedRootStyle->getPropertyCSSValue(CSSPropertyBackgroundImage) && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
@@ -994,7 +1089,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
} else {
// Since this node and all the other ancestors are not in the selection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
// so that styles that affect the exterior of the node are not included.
- accumulator.wrapWithNode(ancestor, convertBlocksToInlines, MarkupAccumulator::DoesNotFullySelectNode);
+ accumulator.wrapWithNode(ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
}
if (nodes)
nodes->append(ancestor);
@@ -1097,7 +1192,7 @@ String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>*
return "";
}
- MarkupAccumulator accumulator(nodes, shouldResolveURLs, DoNotAnnotateForInterchange);
+ MarkupAccumulator accumulator(nodes, shouldResolveURLs);
serializeNodesWithNamespaces(accumulator, const_cast<Node*>(node), deleteButtonContainerElement, childrenOnly, 0);
return accumulator.takeResults();
}
diff --git a/WebCore/fileapi/DOMFileSystem.cpp b/WebCore/fileapi/DOMFileSystem.cpp
index f1b9342..a8a7e6b 100644
--- a/WebCore/fileapi/DOMFileSystem.cpp
+++ b/WebCore/fileapi/DOMFileSystem.cpp
@@ -78,6 +78,7 @@ bool DOMFileSystem::hasPendingActivity() const
void DOMFileSystem::contextDestroyed()
{
m_asyncFileSystem->stop();
+ ActiveDOMObject::contextDestroyed();
}
void DOMFileSystem::getMetadata(const Entry* entry, PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
diff --git a/WebCore/fileapi/Entry.idl b/WebCore/fileapi/Entry.idl
index 7d4ffee..e2c1e12 100644
--- a/WebCore/fileapi/Entry.idl
+++ b/WebCore/fileapi/Entry.idl
@@ -38,10 +38,10 @@ module storage {
readonly attribute DOMString fullPath;
readonly attribute DOMFileSystem filesystem;
+ void getMetadata(in [Optional, Callback] MetadataCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
void moveTo(in Entry parent, in [Optional] DOMString name, in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
void copyTo(in Entry parent, in [Optional] DOMString name, in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
void remove(in [Optional, Callback] VoidCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
void getParent(in [Optional, Callback] EntryCallback successCallback, in [Optional, Callback] ErrorCallback errorCallback);
- DOMString toURI(in [Optional] DOMString mimeType);
};
}
diff --git a/WebCore/fileapi/ErrorCallback.h b/WebCore/fileapi/ErrorCallback.h
index 91143e8..cceb354 100644
--- a/WebCore/fileapi/ErrorCallback.h
+++ b/WebCore/fileapi/ErrorCallback.h
@@ -38,7 +38,6 @@
namespace WebCore {
class FileError;
-class ScriptExecutionContext;
class ErrorCallback : public RefCounted<ErrorCallback> {
public:
diff --git a/WebCore/fileapi/FileCallback.h b/WebCore/fileapi/FileCallback.h
new file mode 100644
index 0000000..6f5ca3d
--- /dev/null
+++ b/WebCore/fileapi/FileCallback.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FileCallback_h
+#define FileCallback_h
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "File.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class FileCallback : public RefCounted<FileCallback> {
+public:
+ virtual ~FileCallback() { }
+ virtual bool handleEvent(File*) = 0;
+};
+
+} // namespace
+
+#endif // ENABLE(FILE_SYSTEM)
+
+#endif // FileCallback_h
diff --git a/WebCore/fileapi/FileCallback.idl b/WebCore/fileapi/FileCallback.idl
new file mode 100644
index 0000000..0ab814f
--- /dev/null
+++ b/WebCore/fileapi/FileCallback.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module fileapi {
+ interface [
+ Conditional=FILE_SYSTEM,
+ Callback
+ ] FileCallback {
+ boolean handleEvent(in File file);
+ };
+}
diff --git a/WebCore/fileapi/FileWriterCallback.h b/WebCore/fileapi/FileWriterCallback.h
new file mode 100644
index 0000000..f5f4d37
--- /dev/null
+++ b/WebCore/fileapi/FileWriterCallback.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FileWriterCallback_h
+#define FileWriterCallback_h
+
+#if ENABLE(FILE_SYSTEM) && ENABLE(FILE_WRITER)
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class FileWriter;
+
+class FileWriterCallback : public RefCounted<FileWriterCallback> {
+public:
+ virtual ~FileWriterCallback() { }
+ virtual bool handleEvent(FileWriter*) = 0;
+};
+
+} // namespace
+
+#endif // ENABLE(FILE_SYSTEM) && ENABLE(FILE_WRITER)
+
+#endif // FileWriterCallback_h
diff --git a/WebCore/fileapi/FileWriterCallback.idl b/WebCore/fileapi/FileWriterCallback.idl
new file mode 100644
index 0000000..ba77891
--- /dev/null
+++ b/WebCore/fileapi/FileWriterCallback.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module fileapi {
+ interface [
+ Conditional=FILE_SYSTEM&FILE_WRITER,
+ Callback
+ ] FileWriterCallback {
+ boolean handleEvent(in FileWriter fileWriter);
+ };
+}
diff --git a/WebCore/fileapi/MetadataCallback.h b/WebCore/fileapi/MetadataCallback.h
index 3d57400..725a0c1 100644
--- a/WebCore/fileapi/MetadataCallback.h
+++ b/WebCore/fileapi/MetadataCallback.h
@@ -38,7 +38,6 @@
namespace WebCore {
class Metadata;
-class ScriptExecutionContext;
class MetadataCallback : public RefCounted<MetadataCallback> {
public:
diff --git a/WebCore/loader/FTPDirectoryDocument.cpp b/WebCore/html/FTPDirectoryDocument.cpp
index 6475ea9..6475ea9 100644
--- a/WebCore/loader/FTPDirectoryDocument.cpp
+++ b/WebCore/html/FTPDirectoryDocument.cpp
diff --git a/WebCore/loader/FTPDirectoryDocument.h b/WebCore/html/FTPDirectoryDocument.h
index e7e52f7..e7e52f7 100644
--- a/WebCore/loader/FTPDirectoryDocument.h
+++ b/WebCore/html/FTPDirectoryDocument.h
diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp
index eeb28e7..e88ee81 100644
--- a/WebCore/html/HTMLEmbedElement.cpp
+++ b/WebCore/html/HTMLEmbedElement.cpp
@@ -120,6 +120,52 @@ void HTMLEmbedElement::parseMappedAttribute(Attribute* attr)
HTMLPlugInImageElement::parseMappedAttribute(attr);
}
+void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues)
+{
+ NamedNodeMap* attributes = this->attributes(true);
+ if (!attributes)
+ return;
+
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ paramNames.append(it->localName().string());
+ paramValues.append(it->value().string());
+ }
+}
+
+// FIXME: This should be unified with HTMLObjectElement::updateWidget and
+// moved down into HTMLPluginImageElement.cpp
+void HTMLEmbedElement::updateWidget(bool onlyCreateNonNetscapePlugins)
+{
+ ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing());
+ // FIXME: We should ASSERT(needsWidgetUpdate()), but currently
+ // FrameView::updateWidget() calls updateWidget(false) without checking if
+ // the widget actually needs updating!
+ setNeedsWidgetUpdate(false);
+
+ if (m_url.isEmpty() && m_serviceType.isEmpty())
+ return;
+
+ // Note these pass m_url and m_serviceType to allow better code sharing with
+ // <object> which modifies url and serviceType before calling these.
+ if (!allowedToLoadFrameURL(m_url))
+ return;
+ if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(m_url, m_serviceType))
+ return;
+
+ // FIXME: These should be joined into a PluginParameters class.
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ parametersForPlugin(paramNames, paramValues);
+
+ if (!dispatchBeforeLoadEvent(m_url))
+ return;
+
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
+ loader->requestObject(this, m_url, getAttribute(nameAttr), m_serviceType, paramNames, paramValues);
+}
+
bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style)
{
if (isImageType())
diff --git a/WebCore/html/HTMLEmbedElement.h b/WebCore/html/HTMLEmbedElement.h
index e27b717..70eb0dc 100644
--- a/WebCore/html/HTMLEmbedElement.h
+++ b/WebCore/html/HTMLEmbedElement.h
@@ -41,13 +41,17 @@ private:
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
-
+
virtual bool isURLAttribute(Attribute*) const;
virtual const QualifiedName& imageSourceAttributeName() const;
virtual RenderWidget* renderWidgetForJSBindings() const;
+ virtual void updateWidget(bool onlyCreateNonNetscapePlugins);
+
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+
+ void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues);
};
}
diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp
index b7ece78..d223b1e 100644
--- a/WebCore/html/HTMLImageElement.cpp
+++ b/WebCore/html/HTMLImageElement.cpp
@@ -267,10 +267,8 @@ int HTMLImageElement::width(bool ignorePendingStylesheets) const
return width;
// if the image is available, use its width
- if (m_imageLoader.image()) {
- float zoomFactor = document()->view() ? document()->view()->pageZoomFactor() : 1.0f;
- return m_imageLoader.image()->imageSize(zoomFactor).width();
- }
+ if (m_imageLoader.image())
+ return m_imageLoader.image()->imageSize(1.0f).width();
}
if (ignorePendingStylesheets)
@@ -278,7 +276,8 @@ int HTMLImageElement::width(bool ignorePendingStylesheets) const
else
document()->updateLayout();
- return renderBox() ? renderBox()->contentWidth() : 0;
+ RenderBox* box = renderBox();
+ return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0;
}
int HTMLImageElement::height(bool ignorePendingStylesheets) const
@@ -291,10 +290,8 @@ int HTMLImageElement::height(bool ignorePendingStylesheets) const
return height;
// if the image is available, use its height
- if (m_imageLoader.image()) {
- float zoomFactor = document()->view() ? document()->view()->pageZoomFactor() : 1.0f;
- return m_imageLoader.image()->imageSize(zoomFactor).height();
- }
+ if (m_imageLoader.image())
+ return m_imageLoader.image()->imageSize(1.0f).height();
}
if (ignorePendingStylesheets)
@@ -302,7 +299,8 @@ int HTMLImageElement::height(bool ignorePendingStylesheets) const
else
document()->updateLayout();
- return renderBox() ? renderBox()->contentHeight() : 0;
+ RenderBox* box = renderBox();
+ return box ? adjustForAbsoluteZoom(box->contentHeight(), box) : 0;
}
int HTMLImageElement::naturalWidth() const
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index c2e5416..5ff979b 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -263,7 +263,8 @@ bool HTMLInputElement::typeMismatch(const String& value) const
case COLOR:
return !isValidColorString(value);
case NUMBER:
- return !parseToDoubleForNumberType(value, 0);
+ ASSERT(parseToDoubleForNumberType(value, 0));
+ return false;
case URL:
return !KURL(KURL(), value).isValid();
case EMAIL: {
@@ -830,6 +831,14 @@ void HTMLInputElement::handleFocusEvent()
void HTMLInputElement::handleBlurEvent()
{
+ if (inputType() == NUMBER) {
+ // Reset the renderer value, which might be unmatched with the element value.
+ setFormControlValueMatchesRenderer(false);
+ // We need to reset the renderer value explicitly because an unacceptable
+ // renderer value should be purged before style calculation.
+ if (renderer())
+ renderer()->updateFromElement();
+ }
InputElement::dispatchBlurEvent(this, this);
}
@@ -2273,7 +2282,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
&& evt->isKeyboardEvent()
&& focused()
&& document()->frame()
- && document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
+ && document()->frame()->editor()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
evt->setDefaultHandled();
return;
}
@@ -2676,8 +2685,18 @@ FileList* HTMLInputElement::files()
return m_fileList.get();
}
+bool HTMLInputElement::isAcceptableValue(const String& proposedValue) const
+{
+ if (inputType() != NUMBER)
+ return true;
+ return proposedValue.isEmpty() || parseToDoubleForNumberType(proposedValue, 0);
+}
+
String HTMLInputElement::sanitizeValue(const String& proposedValue) const
{
+ if (inputType() == NUMBER)
+ return parseToDoubleForNumberType(proposedValue, 0) ? proposedValue : String();
+
if (isTextField())
return InputElement::sanitizeValueForTextField(this, proposedValue);
@@ -2690,6 +2709,11 @@ String HTMLInputElement::sanitizeValue(const String& proposedValue) const
return proposedValue;
}
+bool HTMLInputElement::hasUnacceptableValue() const
+{
+ return inputType() == NUMBER && renderer() && !isAcceptableValue(toRenderTextControl(renderer())->text());
+}
+
bool HTMLInputElement::needsActivationCallback()
{
return inputType() == PASSWORD || m_autocomplete == Off;
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index 657b468..e023796 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -281,7 +281,9 @@ private:
virtual void cacheSelection(int start, int end);
+ virtual bool isAcceptableValue(const String&) const;
virtual String sanitizeValue(const String&) const;
+ virtual bool hasUnacceptableValue() const;
virtual void documentDidBecomeActive();
diff --git a/WebCore/html/HTMLLinkElement.cpp b/WebCore/html/HTMLLinkElement.cpp
index bc7b9a6..939b375 100644
--- a/WebCore/html/HTMLLinkElement.cpp
+++ b/WebCore/html/HTMLLinkElement.cpp
@@ -27,7 +27,7 @@
#include "Attribute.h"
#include "CSSHelper.h"
#include "CachedCSSStyleSheet.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -212,7 +212,7 @@ void HTMLLinkElement::process()
#if ENABLE(LINK_PREFETCH)
if (m_relAttribute.m_isLinkPrefetch && m_url.isValid() && document()->frame())
- document()->docLoader()->requestLinkPrefetch(m_url);
+ document()->cachedResourceLoader()->requestLinkPrefetch(m_url);
#endif
bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet();
@@ -243,7 +243,7 @@ void HTMLLinkElement::process()
if (!isAlternate())
document()->addPendingSheet();
- m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(m_url, charset);
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(m_url, charset);
if (m_cachedSheet)
m_cachedSheet->addClient(this);
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index bc7960c..827158e 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -29,14 +29,14 @@
#include "HTMLMediaElement.h"
#include "Attribute.h"
-#include "CSSHelper.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "ClientRect.h"
#include "ClientRectList.h"
#include "ContentType.h"
+#include "CSSHelper.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
#include "Event.h"
#include "EventNames.h"
#include "ExceptionCode.h"
@@ -48,12 +48,13 @@
#include "HTMLNames.h"
#include "HTMLSourceElement.h"
#include "HTMLVideoElement.h"
-#include "MIMETypeRegistry.h"
+#include "Logging.h"
#include "MediaDocument.h"
#include "MediaError.h"
#include "MediaList.h"
#include "MediaPlayer.h"
#include "MediaQueryEvaluator.h"
+#include "MIMETypeRegistry.h"
#include "Page.h"
#include "RenderVideo.h"
#include "RenderView.h"
@@ -78,10 +79,33 @@ using namespace std;
namespace WebCore {
+#if !LOG_DISABLED
+static String urlForLogging(const String& url)
+{
+ static unsigned maximumURLLengthForLogging = 128;
+
+ if (url.length() < maximumURLLengthForLogging)
+ return url;
+ return url.substring(0, maximumURLLengthForLogging) + "...";
+}
+
+static const char *boolString(bool val)
+{
+ return val ? "true" : "false";
+}
+#endif
+
+#ifndef LOG_MEDIA_EVENTS
+// Default to not logging events because so many are generated they can overwhelm the rest of
+// the logging.
+#define LOG_MEDIA_EVENTS 0
+#endif
+
using namespace HTMLNames;
-HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
- : HTMLElement(tagName, doc)
+HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* document)
+ : HTMLElement(tagName, document)
+ , ActiveDOMObject(document, this)
, m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
, m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
@@ -132,8 +156,8 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_loadInitiatedByUserGesture(false)
, m_completelyLoaded(false)
{
- document()->registerForDocumentActivationCallbacks(this);
- document()->registerForMediaVolumeCallbacks(this);
+ document->registerForDocumentActivationCallbacks(this);
+ document->registerForMediaVolumeCallbacks(this);
}
HTMLMediaElement::~HTMLMediaElement()
@@ -365,6 +389,9 @@ void HTMLMediaElement::scheduleNextSourceChild()
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
{
+#if LOG_MEDIA_EVENTS
+ LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
+#endif
m_pendingEvents.append(Event::create(eventName, false, true));
if (!m_asyncEventTimer.isActive())
m_asyncEventTimer.startOneShot(0);
@@ -387,6 +414,9 @@ void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
m_pendingEvents.swap(pendingEvents);
unsigned count = pendingEvents.size();
for (unsigned ndx = 0; ndx < count; ++ndx) {
+#if LOG_MEDIA_EVENTS
+ LOG(Media, "HTMLMediaElement::asyncEventTimerFired - dispatching '%s'", pendingEvents[ndx]->type().string().ascii().data());
+#endif
if (pendingEvents[ndx]->type() == eventNames().canplayEvent) {
m_dispatchingCanPlayEvent = true;
dispatchEvent(pendingEvents[ndx].release(), ec);
@@ -479,11 +509,15 @@ String HTMLMediaElement::canPlayType(const String& mimeType) const
break;
}
+ LOG(Media, "HTMLMediaElement::canPlayType(%s) -> %s", mimeType.utf8().data(), canPlay.utf8().data());
+
return canPlay;
}
void HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
{
+ LOG(Media, "HTMLMediaElement::load(isUserGesture : %s)", boolString(isUserGesture));
+
if (m_restrictions & RequireUserGestureForLoadRestriction && !isUserGesture)
ec = INVALID_STATE_ERR;
else {
@@ -495,6 +529,8 @@ void HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
void HTMLMediaElement::prepareForLoad()
{
+ LOG(Media, "HTMLMediaElement::prepareForLoad");
+
// Perform the cleanup required for the resource load algorithm to run.
stopPeriodicTimers();
m_loadTimer.stop();
@@ -578,6 +614,8 @@ void HTMLMediaElement::loadInternal()
void HTMLMediaElement::selectMediaResource()
{
+ LOG(Media, "HTMLMediaElement::selectMediaResource");
+
enum Mode { attribute, children };
Mode mode = attribute;
@@ -596,6 +634,8 @@ void HTMLMediaElement::selectMediaResource()
// ... set the networkState to NETWORK_EMPTY, and abort these steps
m_networkState = NETWORK_EMPTY;
+
+ LOG(Media, "HTMLMediaElement::selectMediaResource, nothing to load");
return;
}
@@ -616,6 +656,7 @@ void HTMLMediaElement::selectMediaResource()
KURL mediaURL = getNonEmptyURLAttribute(srcAttr);
if (mediaURL.isEmpty()) {
noneSupported();
+ LOG(Media, "HTMLMediaElement::selectMediaResource, empty 'src'");
return;
}
@@ -626,6 +667,7 @@ void HTMLMediaElement::selectMediaResource()
} else
noneSupported();
+ LOG(Media, "HTMLMediaElement::selectMediaResource, 'src' not used");
return;
}
@@ -656,6 +698,8 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
{
ASSERT(isSafeToLoadURL(initialURL, Complain));
+ LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL.string()).utf8().data(), contentType.raw().utf8().data());
+
Frame* frame = document()->frame();
if (!frame)
return;
@@ -672,6 +716,8 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
m_currentSrc = url;
+ LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc).utf8().data());
+
if (m_sendProgressEvents)
startProgressEventTimer();
@@ -698,16 +744,19 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction actionIfInvalid)
{
- if (!url.isValid())
+ if (!url.isValid()) {
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url.string()).utf8().data());
return false;
+ }
Frame* frame = document()->frame();
FrameLoader* loader = frame ? frame->loader() : 0;
// don't allow remote to local urls, and check with the frame loader client.
- if (!loader || !SecurityOrigin::canLoad(url, String(), document())) {
+ if (!loader || !SecurityOrigin::canDisplay(url, String(), document())) {
if (actionIfInvalid == Complain)
FrameLoader::reportLocalLoadFailed(frame, url.string());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url.string()).utf8().data());
return false;
}
@@ -727,6 +776,8 @@ void HTMLMediaElement::startProgressEventTimer()
void HTMLMediaElement::waitForSourceChange()
{
+ LOG(Media, "HTMLMediaElement::waitForSourceChange");
+
stopPeriodicTimers();
m_loadState = WaitingForSource;
@@ -739,6 +790,8 @@ void HTMLMediaElement::waitForSourceChange()
void HTMLMediaElement::noneSupported()
{
+ LOG(Media, "HTMLMediaElement::noneSupported");
+
stopPeriodicTimers();
m_loadState = WaitingForSource;
m_currentSourceNode = 0;
@@ -769,6 +822,8 @@ void HTMLMediaElement::noneSupported()
void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
{
+ LOG(Media, "HTMLMediaElement::mediaEngineError(%d)", static_cast<int>(err->code()));
+
// 1 - The user agent should cancel the fetching process.
stopPeriodicTimers();
m_loadState = WaitingForSource;
@@ -794,6 +849,8 @@ void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
void HTMLMediaElement::cancelPendingEventsAndCallbacks()
{
+ LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
+
m_pendingEvents.clear();
for (Node* node = firstChild(); node; node = node->nextSibling()) {
@@ -821,6 +878,8 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
{
+ LOG(Media, "HTMLMediaElement::setNetworkState(%d) - current state is %d", static_cast<int>(state), static_cast<int>(m_networkState));
+
if (state == MediaPlayer::Empty) {
// just update the cached state and leave, we can't do anything
m_networkState = NETWORK_EMPTY;
@@ -834,10 +893,13 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
// <source> children, schedule the next one
if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
m_currentSourceNode->scheduleErrorEvent();
- if (havePotentialSourceChild())
+ if (havePotentialSourceChild()) {
+ LOG(Media, "HTMLMediaElement::setNetworkState scheduling next <source>");
scheduleNextSourceChild();
- else
+ } else {
+ LOG(Media, "HTMLMediaElement::setNetworkState no more <source> elements, waiting");
waitForSourceChange();
+ }
return;
}
@@ -891,6 +953,8 @@ void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
{
+ LOG(Media, "HTMLMediaElement::setReadyState(%d) - current state is %d,", static_cast<int>(state), static_cast<int>(m_readyState));
+
// Set "wasPotentiallyPlaying" BEFORE updating m_readyState, potentiallyPlaying() uses it
bool wasPotentiallyPlaying = potentiallyPlaying();
@@ -1004,18 +1068,22 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
void HTMLMediaElement::rewind(float timeDelta)
{
+ LOG(Media, "HTMLMediaElement::rewind(%f)", timeDelta);
+
ExceptionCode e;
setCurrentTime(max(currentTime() - timeDelta, minTimeSeekable()), e);
}
void HTMLMediaElement::returnToRealtime()
{
+ LOG(Media, "HTMLMediaElement::returnToRealtime");
ExceptionCode e;
setCurrentTime(maxTimeSeekable(), e);
}
void HTMLMediaElement::addPlayedRange(float start, float end)
{
+ LOG(Media, "HTMLMediaElement::addPlayedRange(%f, %f)", start, end);
if (!m_playedTimeRanges)
m_playedTimeRanges = TimeRanges::create();
m_playedTimeRanges->add(start, end);
@@ -1028,6 +1096,8 @@ bool HTMLMediaElement::supportsSave() const
void HTMLMediaElement::seek(float time, ExceptionCode& ec)
{
+ LOG(Media, "HTMLMediaElement::seek(%f)", time);
+
// 4.8.9.9 Seeking
// 1 - If the media element's readyState is HAVE_NOTHING, then raise an INVALID_STATE_ERR exception.
@@ -1080,6 +1150,8 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
void HTMLMediaElement::finishSeek()
{
+ LOG(Media, "HTMLMediaElement::finishSeek");
+
// 4.8.10.10 Seeking step 12
m_seeking = false;
@@ -1164,6 +1236,8 @@ float HTMLMediaElement::playbackRate() const
void HTMLMediaElement::setPlaybackRate(float rate)
{
+ LOG(Media, "HTMLMediaElement::setPlaybackRate(%f)", rate);
+
if (m_playbackRate != rate) {
m_playbackRate = rate;
scheduleEvent(eventNames().ratechangeEvent);
@@ -1179,6 +1253,8 @@ bool HTMLMediaElement::webkitPreservesPitch() const
void HTMLMediaElement::setWebkitPreservesPitch(bool preservesPitch)
{
+ LOG(Media, "HTMLMediaElement::setWebkitPreservesPitch(%s)", boolString(preservesPitch));
+
m_webkitPreservesPitch = preservesPitch;
if (!m_player)
@@ -1202,6 +1278,7 @@ bool HTMLMediaElement::autoplay() const
void HTMLMediaElement::setAutoplay(bool b)
{
+ LOG(Media, "HTMLMediaElement::setAutoplay(%s)", boolString(b));
setBooleanAttribute(autoplayAttr, b);
}
@@ -1225,11 +1302,14 @@ String HTMLMediaElement::preload() const
void HTMLMediaElement::setPreload(const String& preload)
{
+ LOG(Media, "HTMLMediaElement::setPreload(%s)", preload.utf8().data());
setAttribute(preloadAttr, preload);
}
void HTMLMediaElement::play(bool isUserGesture)
{
+ LOG(Media, "HTMLMediaElement::play(isUserGesture : %s)", boolString(isUserGesture));
+
if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
return;
@@ -1249,6 +1329,8 @@ void HTMLMediaElement::play(bool isUserGesture)
void HTMLMediaElement::playInternal()
{
+ LOG(Media, "HTMLMediaElement::playInternal");
+
// 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY)
scheduleLoad();
@@ -1276,6 +1358,8 @@ void HTMLMediaElement::playInternal()
void HTMLMediaElement::pause(bool isUserGesture)
{
+ LOG(Media, "HTMLMediaElement::pause(isUserGesture : %s)", boolString(isUserGesture));
+
if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture)
return;
@@ -1285,6 +1369,8 @@ void HTMLMediaElement::pause(bool isUserGesture)
void HTMLMediaElement::pauseInternal()
{
+ LOG(Media, "HTMLMediaElement::pauseInternal");
+
// 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY)
scheduleLoad();
@@ -1307,6 +1393,7 @@ bool HTMLMediaElement::loop() const
void HTMLMediaElement::setLoop(bool b)
{
+ LOG(Media, "HTMLMediaElement::setLoop(%s)", boolString(b));
setBooleanAttribute(loopAttr, b);
}
@@ -1323,6 +1410,7 @@ bool HTMLMediaElement::controls() const
void HTMLMediaElement::setControls(bool b)
{
+ LOG(Media, "HTMLMediaElement::setControls(%s)", boolString(b));
setBooleanAttribute(controlsAttr, b);
}
@@ -1333,6 +1421,8 @@ float HTMLMediaElement::volume() const
void HTMLMediaElement::setVolume(float vol, ExceptionCode& ec)
{
+ LOG(Media, "HTMLMediaElement::setControls(%f)", vol);
+
if (vol < 0.0f || vol > 1.0f) {
ec = INDEX_SIZE_ERR;
return;
@@ -1352,6 +1442,8 @@ bool HTMLMediaElement::muted() const
void HTMLMediaElement::setMuted(bool muted)
{
+ LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
+
if (m_muted != muted) {
m_muted = muted;
// Avoid recursion when the player reports volume changes.
@@ -1369,6 +1461,8 @@ void HTMLMediaElement::setMuted(bool muted)
void HTMLMediaElement::togglePlayState()
{
+ LOG(Media, "HTMLMediaElement::togglePlayState - canPlay() is %s", boolString(canPlay()));
+
// We can safely call the internal play/pause methods, which don't check restrictions, because
// this method is only called from the built-in media controller
if (canPlay())
@@ -1379,6 +1473,8 @@ void HTMLMediaElement::togglePlayState()
void HTMLMediaElement::beginScrubbing()
{
+ LOG(Media, "HTMLMediaElement::beginScrubbing - paused() is %s", boolString(paused()));
+
if (!paused()) {
if (ended()) {
// Because a media element stays in non-paused state when it reaches end, playback resumes
@@ -1396,6 +1492,8 @@ void HTMLMediaElement::beginScrubbing()
void HTMLMediaElement::endScrubbing()
{
+ LOG(Media, "HTMLMediaElement::beginScrubbing - m_pausedInternal is %s", boolString(m_pausedInternal));
+
if (m_pausedInternal)
setPausedInternal(false);
}
@@ -1482,6 +1580,13 @@ bool HTMLMediaElement::havePotentialSourceChild()
KURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSourceAction actionIfInvalid)
{
+#if !LOG_DISABLED
+ // Don't log if this was just called to find out if there are any valid <source> elements.
+ bool shouldLog = actionIfInvalid != DoNothing;
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild(contentType : \"%s\")", contentType ? contentType->raw().utf8().data() : "");
+#endif
+
KURL mediaURL;
Node* node;
bool lookingForPreviousNode = m_currentSourceNode;
@@ -1501,17 +1606,29 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSo
// If candidate does not have a src attribute, or if its src attribute's value is the empty string ... jump down to the failed step below
mediaURL = source->getNonEmptyURLAttribute(srcAttr);
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLogging(mediaURL).utf8().data());
+#endif
if (mediaURL.isEmpty())
goto check_again;
if (source->hasAttribute(mediaAttr)) {
MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'media' is %s", source->media().utf8().data());
+#endif
if (!screenEval.eval(media.get()))
goto check_again;
}
if (source->hasAttribute(typeAttr)) {
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'type' is %s", source->type().utf8().data());
+#endif
if (!MediaPlayer::supportsType(ContentType(source->type())))
goto check_again;
}
@@ -1533,11 +1650,17 @@ check_again:
if (!canUse)
m_currentSourceNode = 0;
+#if !LOG_DISABLED
+ if (shouldLog)
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %s", canUse ? urlForLogging(mediaURL.string()).utf8().data() : "");
+#endif
return canUse ? mediaURL : KURL();
}
void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged");
+
beginProcessingMediaPlayerCallback();
// Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity,
@@ -1572,6 +1695,8 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerVolumeChanged");
+
beginProcessingMediaPlayerCallback();
if (m_player)
m_volume = m_player->volume();
@@ -1581,6 +1706,8 @@ void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerMuteChanged");
+
beginProcessingMediaPlayerCallback();
if (m_player)
setMuted(m_player->muted());
@@ -1589,6 +1716,8 @@ void HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged");
+
beginProcessingMediaPlayerCallback();
scheduleEvent(eventNames().durationchangeEvent);
if (renderer())
@@ -1598,6 +1727,8 @@ void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
void HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerRateChanged");
+
beginProcessingMediaPlayerCallback();
// Stash the rate in case the one we tried to set isn't what the engine is
// using (eg. it can't handle the rate we set)
@@ -1605,8 +1736,25 @@ void HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
endProcessingMediaPlayerCallback();
}
+void HTMLMediaElement::mediaPlayerPlaybackStateChanged(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged");
+
+ if (!m_player)
+ return;
+
+ beginProcessingMediaPlayerCallback();
+ if (m_player->paused())
+ pauseInternal();
+ else
+ playInternal();
+ endProcessingMediaPlayerCallback();
+}
+
void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerSawUnsupportedTracks");
+
// The MediaPlayer came across content it cannot completely handle.
// This is normally acceptable except when we are in a standalone
// MediaDocument. If so, tell the document what has happened.
@@ -1628,6 +1776,8 @@ void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
void HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged");
+
beginProcessingMediaPlayerCallback();
if (renderer())
renderer()->updateFromElement();
@@ -1646,6 +1796,8 @@ bool HTMLMediaElement::mediaPlayerRenderingCanBeAccelerated(MediaPlayer*)
void HTMLMediaElement::mediaPlayerRenderingModeChanged(MediaPlayer*)
{
+ LOG(Media, "HTMLMediaElement::mediaPlayerRenderingModeChanged");
+
// Kick off a fake recalcStyle that will update the compositing tree.
setNeedsStyleRecalc(SyntheticStyleChange);
}
@@ -1780,24 +1932,36 @@ void HTMLMediaElement::updatePlayState()
bool shouldBePlaying = potentiallyPlaying();
bool playerPaused = m_player->paused();
- if (shouldBePlaying && playerPaused) {
+
+ LOG(Media, "HTMLMediaElement::updatePlayState - shouldBePlaying = %s, playerPaused = %s",
+ boolString(shouldBePlaying), boolString(playerPaused));
+
+ if (shouldBePlaying) {
setDisplayMode(Video);
- // Set rate before calling play in case the rate was set before the media engine wasn't setup.
- // The media engine should just stash the rate since it isn't already playing.
- m_player->setRate(m_playbackRate);
- m_player->play();
+ if (playerPaused) {
+ // Set rate before calling play in case the rate was set before the media engine was setup.
+ // The media engine should just stash the rate since it isn't already playing.
+ m_player->setRate(m_playbackRate);
+ m_player->play();
+ }
+
startPlaybackProgressTimer();
m_playing = true;
- } else if (!shouldBePlaying && !playerPaused) {
- m_player->pause();
+
+ } else { // Should not be playing right now
+ if (!playerPaused)
+ m_player->pause();
+
m_playbackProgressTimer.stop();
m_playing = false;
float time = currentTime();
if (time > m_lastSeekTime)
addPlayedRange(m_lastSeekTime, time);
- } else if (couldPlayIfEnoughData() && playerPaused)
- m_player->prepareToPlay();
+
+ if (couldPlayIfEnoughData())
+ m_player->prepareToPlay();
+ }
if (renderer())
renderer()->updateFromElement();
@@ -1817,6 +1981,8 @@ void HTMLMediaElement::stopPeriodicTimers()
void HTMLMediaElement::userCancelledLoad()
{
+ LOG(Media, "HTMLMediaElement::userCancelledLoad");
+
if (m_networkState == NETWORK_EMPTY || m_completelyLoaded)
return;
@@ -1855,8 +2021,21 @@ void HTMLMediaElement::userCancelledLoad()
m_readyState = HAVE_NOTHING;
}
-void HTMLMediaElement::documentWillBecomeInactive()
+bool HTMLMediaElement::canSuspend() const
+{
+ return true;
+}
+
+void HTMLMediaElement::stop()
+{
+ LOG(Media, "HTMLMediaElement::stop");
+ suspend();
+}
+
+void HTMLMediaElement::suspend()
{
+ LOG(Media, "HTMLMediaElement::suspend");
+
if (m_isFullscreen)
exitFullscreen();
@@ -1873,8 +2052,10 @@ void HTMLMediaElement::documentWillBecomeInactive()
cancelPendingEventsAndCallbacks();
}
-void HTMLMediaElement::documentDidBecomeActive()
+void HTMLMediaElement::resume()
{
+ LOG(Media, "HTMLMediaElement::resume");
+
m_inActiveDocument = true;
setPausedInternal(false);
@@ -1891,8 +2072,18 @@ void HTMLMediaElement::documentDidBecomeActive()
renderer()->updateFromElement();
}
+bool HTMLMediaElement::hasPendingActivity() const
+{
+ // Return true when we have pending events so we can't fire events after the JS
+ // object gets collected.
+ bool pending = m_pendingEvents.size();
+ LOG(Media, "HTMLMediaElement::hasPendingActivity -> %s", boolString(pending));
+ return pending;
+}
+
void HTMLMediaElement::mediaVolumeDidChange()
{
+ LOG(Media, "HTMLMediaElement::mediaVolumeDidChange");
updateVolume();
}
@@ -2004,6 +2195,8 @@ void HTMLMediaElement::createMediaPlayerProxy()
if (!loader)
return;
+ LOG(Media, "HTMLMediaElement::createMediaPlayerProxy");
+
KURL url;
Vector<String> paramNames;
Vector<String> paramValues;
@@ -2016,10 +2209,26 @@ void HTMLMediaElement::createMediaPlayerProxy()
if (m_proxyWidget)
m_needWidgetUpdate = false;
}
+
+void HTMLMediaElement::updateWidget(bool)
+{
+ mediaElement->setNeedWidgetUpdate(false);
+
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ KURL kurl;
+
+ mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ loader->loadMediaPlayerProxyPlugin(mediaElement, kurl, paramNames, paramValues);
+}
+
#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
void HTMLMediaElement::enterFullscreen()
{
+ LOG(Media, "HTMLMediaElement::enterFullscreen");
+
ASSERT(!m_isFullscreen);
m_isFullscreen = true;
if (document() && document()->page()) {
@@ -2030,6 +2239,8 @@ void HTMLMediaElement::enterFullscreen()
void HTMLMediaElement::exitFullscreen()
{
+ LOG(Media, "HTMLMediaElement::exitFullscreen");
+
ASSERT(m_isFullscreen);
m_isFullscreen = false;
if (document() && document()->page()) {
@@ -2062,6 +2273,8 @@ bool HTMLMediaElement::closedCaptionsVisible() const
void HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible)
{
+ LOG(Media, "HTMLMediaElement::setClosedCaptionsVisible(%s)", boolString(closedCaptionVisible));
+
if (!m_player ||!hasClosedCaptions())
return;
@@ -2089,6 +2302,8 @@ bool HTMLMediaElement::webkitHasClosedCaptions() const
void HTMLMediaElement::mediaCanStart()
{
+ LOG(Media, "HTMLMediaElement::mediaCanStart");
+
ASSERT(m_isWaitingUntilMediaCanStart);
m_isWaitingUntilMediaCanStart = false;
loadInternal();
@@ -2118,6 +2333,8 @@ void HTMLMediaElement::setShouldDelayLoadEvent(bool shouldDelay)
return;
}
+ LOG(Media, "HTMLMediaElement::setShouldDelayLoadEvent(%s)", boolString(shouldDelay));
+
m_shouldDelayLoadEvent = shouldDelay;
m_isWaitingToDecrementLoadEventDelayCount = false;
if (shouldDelay)
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index 3895fe3..adea0fd 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -29,6 +29,7 @@
#if ENABLE(VIDEO)
#include "HTMLElement.h"
+#include "ActiveDOMObject.h"
#include "MediaCanStartListener.h"
#include "MediaPlayer.h"
@@ -51,7 +52,7 @@ class Widget;
// But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
-class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener {
+class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, private MediaCanStartListener, private ActiveDOMObject {
public:
MediaPlayer* player() const { return m_player.get(); }
@@ -153,6 +154,7 @@ public:
void getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values);
virtual void finishParsingChildren();
void createMediaPlayerProxy();
+ void updateWidget(bool onlyCreateNonNetscapePlugins);
#endif
bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
@@ -195,8 +197,13 @@ private:
float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const;
void setTimeOffsetAttribute(const QualifiedName&, float value);
- virtual void documentWillBecomeInactive();
- virtual void documentDidBecomeActive();
+ // ActiveDOMObject functions.
+ virtual bool canSuspend() const;
+ virtual void suspend();
+ virtual void resume();
+ virtual void stop();
+ virtual bool hasPendingActivity() const;
+
virtual void mediaVolumeDidChange();
virtual void updateDisplayState() { }
@@ -212,6 +219,7 @@ private:
virtual void mediaPlayerMuteChanged(MediaPlayer*);
virtual void mediaPlayerDurationChanged(MediaPlayer*);
virtual void mediaPlayerRateChanged(MediaPlayer*);
+ virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*);
virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
virtual void mediaPlayerRepaint(MediaPlayer*);
virtual void mediaPlayerSizeChanged(MediaPlayer*);
diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp
index e8884ef..56a6095 100644
--- a/WebCore/html/HTMLObjectElement.cpp
+++ b/WebCore/html/HTMLObjectElement.cpp
@@ -33,6 +33,7 @@
#include "HTMLFormElement.h"
#include "HTMLImageLoader.h"
#include "HTMLNames.h"
+#include "HTMLParamElement.h"
#include "MIMETypeRegistry.h"
#include "RenderEmbeddedObject.h"
#include "RenderImage.h"
@@ -115,6 +116,173 @@ void HTMLObjectElement::parseMappedAttribute(Attribute* attr)
HTMLPlugInImageElement::parseMappedAttribute(attr);
}
+typedef HashMap<String, String, CaseFoldingHash> ClassIdToTypeMap;
+
+static ClassIdToTypeMap* createClassIdToTypeMap()
+{
+ ClassIdToTypeMap* map = new ClassIdToTypeMap;
+ map->add("clsid:D27CDB6E-AE6D-11CF-96B8-444553540000", "application/x-shockwave-flash");
+ map->add("clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA", "audio/x-pn-realaudio-plugin");
+ map->add("clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", "video/quicktime");
+ map->add("clsid:166B1BCA-3F9C-11CF-8075-444553540000", "application/x-director");
+ map->add("clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6", "application/x-mplayer2");
+ map->add("clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95", "application/x-mplayer2");
+ return map;
+}
+
+static String serviceTypeForClassId(const String& classId)
+{
+ // Return early if classId is empty (since we won't do anything below).
+ // Furthermore, if classId is null, calling get() below will crash.
+ if (classId.isEmpty())
+ return String();
+
+ static ClassIdToTypeMap* map = createClassIdToTypeMap();
+ return map->get(classId);
+}
+
+static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
+{
+ // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
+ // require "src" attribute).
+ int srcIndex = -1, dataIndex = -1;
+ for (unsigned int i = 0; i < paramNames->size(); ++i) {
+ if (equalIgnoringCase((*paramNames)[i], "src"))
+ srcIndex = i;
+ else if (equalIgnoringCase((*paramNames)[i], "data"))
+ dataIndex = i;
+ }
+
+ if (srcIndex == -1 && dataIndex != -1) {
+ paramNames->append("src");
+ paramValues->append((*paramValues)[dataIndex]);
+ }
+}
+
+// FIXME: This function should not deal with url or serviceType!
+void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
+{
+ HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
+
+ // Scan the PARAM children and store their name/value pairs.
+ // Get the URL and type from the params if we don't already have them.
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ if (!child->hasTagName(paramTag))
+ continue;
+
+ HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
+ String name = p->name();
+ if (name.isEmpty())
+ continue;
+
+ uniqueParamNames.add(name.impl());
+ paramNames.append(p->name());
+ paramValues.append(p->value());
+
+ // FIXME: url adjustment does not belong in this function.
+ if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
+ url = deprecatedParseURL(p->value());
+ // FIXME: serviceType calculation does not belong in this function.
+ if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
+ serviceType = p->value();
+ size_t pos = serviceType.find(";");
+ if (pos != notFound)
+ serviceType = serviceType.left(pos);
+ }
+ }
+
+ // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
+ // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
+ // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
+ // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
+ // else our Java plugin will misinterpret it. [4004531]
+ String codebase;
+ if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
+ codebase = "codebase";
+ uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
+ }
+
+ // Turn the attributes of the <object> element into arrays, but don't override <param> values.
+ NamedNodeMap* attributes = this->attributes(true);
+ if (attributes) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ const AtomicString& name = it->name().localName();
+ if (!uniqueParamNames.contains(name.impl())) {
+ paramNames.append(name.string());
+ paramValues.append(it->value().string());
+ }
+ }
+ }
+
+ mapDataParamToSrc(&paramNames, &paramValues);
+
+ // If we still don't have a type, try to map from a specific CLASSID to a type.
+ if (serviceType.isEmpty())
+ serviceType = serviceTypeForClassId(classId());
+}
+
+
+bool HTMLObjectElement::hasFallbackContent() const
+{
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ // Ignore whitespace-only text, and <param> tags, any other content is fallback content.
+ if (child->isTextNode()) {
+ if (!static_cast<Text*>(child)->containsOnlyWhitespace())
+ return true;
+ } else if (!child->hasTagName(paramTag))
+ return true;
+ }
+ return false;
+}
+
+// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
+// moved down into HTMLPluginImageElement.cpp
+void HTMLObjectElement::updateWidget(bool onlyCreateNonNetscapePlugins)
+{
+ ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing());
+ // FIXME: We should ASSERT(needsWidgetUpdate()), but currently
+ // FrameView::updateWidget() calls updateWidget(false) without checking if
+ // the widget actually needs updating!
+ setNeedsWidgetUpdate(false);
+ // FIXME: This should ASSERT isFinishedParsingChildren() instead.
+ if (!isFinishedParsingChildren())
+ return;
+
+ String url = this->url();
+ String serviceType = this->serviceType();
+
+ // FIXME: These should be joined into a PluginParameters class.
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ parametersForPlugin(paramNames, paramValues, url, serviceType);
+
+ // Note: url is modified above by parametersForPlugin.
+ if (!allowedToLoadFrameURL(url))
+ return;
+
+ bool fallbackContent = hasFallbackContent();
+ renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
+
+ if (onlyCreateNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType))
+ return;
+
+ bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
+
+ // beforeload events can modify the DOM, potentially causing
+ // RenderWidget::destroy() to be called. Ensure we haven't been
+ // destroyed before continuing.
+ // FIXME: Should this render fallback content?
+ if (!renderer())
+ return;
+
+ SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
+ bool success = beforeLoadAllowedLoad && loader->requestObject(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues);
+
+ if (!success && fallbackContent)
+ renderFallbackContent();
+}
+
bool HTMLObjectElement::rendererIsNeeded(RenderStyle* style)
{
// FIXME: This check should not be needed, detached documents never render!
diff --git a/WebCore/html/HTMLObjectElement.h b/WebCore/html/HTMLObjectElement.h
index 9fafae9..2d416c3 100644
--- a/WebCore/html/HTMLObjectElement.h
+++ b/WebCore/html/HTMLObjectElement.h
@@ -31,8 +31,6 @@ class HTMLObjectElement : public HTMLPlugInImageElement {
public:
static PassRefPtr<HTMLObjectElement> create(const QualifiedName&, Document*, bool createdByParser);
- void renderFallbackContent();
-
bool isDocNamedItem() const { return m_docNamedItem; }
const String& classId() const { return m_classId; }
@@ -40,6 +38,7 @@ public:
bool containsJavaApplet() const;
virtual bool useFallbackContent() const { return m_useFallbackContent; }
+ void renderFallbackContent();
private:
HTMLObjectElement(const QualifiedName&, Document*, bool createdByParser);
@@ -59,8 +58,15 @@ private:
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual void updateWidget(bool onlyCreateNonNetscapePlugins);
void updateDocNamedItem();
+ bool hasFallbackContent() const;
+
+ // FIXME: This function should not deal with url or serviceType
+ // so that we can better share code between <object> and <embed>.
+ void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType);
+
AtomicString m_id;
String m_classId;
bool m_docNamedItem : 1;
diff --git a/WebCore/html/HTMLPlugInImageElement.cpp b/WebCore/html/HTMLPlugInImageElement.cpp
index 75407dd..9ac5ad8 100644
--- a/WebCore/html/HTMLPlugInImageElement.cpp
+++ b/WebCore/html/HTMLPlugInImageElement.cpp
@@ -26,6 +26,7 @@
#include "FrameLoaderClient.h"
#include "HTMLImageLoader.h"
#include "Image.h"
+#include "Page.h"
#include "RenderEmbeddedObject.h"
#include "RenderImage.h"
@@ -63,6 +64,46 @@ bool HTMLPlugInImageElement::isImageType()
return Image::supportsType(m_serviceType);
}
+// We don't use m_url, as it may not be the final URL that the object loads,
+// depending on <param> values.
+bool HTMLPlugInImageElement::allowedToLoadFrameURL(const String& url)
+{
+ ASSERT(document());
+ ASSERT(document()->frame());
+ if (document()->frame()->page()->frameCount() >= Page::maxNumberOfFrames)
+ return false;
+
+ // We allow one level of self-reference because some sites depend on that.
+ // But we don't allow more than one.
+ KURL completeURL = document()->completeURL(url);
+ bool foundSelfReference = false;
+ for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) {
+ if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
+ if (foundSelfReference)
+ return false;
+ foundSelfReference = true;
+ }
+ }
+ return true;
+}
+
+// We don't use m_url, or m_serviceType as they may not be the final values
+// that <object> uses depending on <param> values.
+bool HTMLPlugInImageElement::wouldLoadAsNetscapePlugin(const String& url, const String& serviceType)
+{
+ ASSERT(document());
+ ASSERT(document()->frame());
+ FrameLoader* frameLoader = document()->frame()->loader();
+ ASSERT(frameLoader);
+ KURL completedURL;
+ if (!url.isEmpty())
+ completedURL = frameLoader->completeURL(url);
+
+ if (frameLoader->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
+ return true;
+ return false;
+}
+
RenderObject* HTMLPlugInImageElement::createRenderer(RenderArena* arena, RenderStyle* style)
{
// Fallback content breaks the DOM->Renderer class relationship of this
@@ -106,7 +147,7 @@ void HTMLPlugInImageElement::attach()
void HTMLPlugInImageElement::detach()
{
- // FIXME: Because of the insanity that is HTMLObjectElement::recalcStyle,
+ // FIXME: Because of the insanity that is HTMLPlugInImageElement::recalcStyle,
// we can end up detaching during an attach() call, before we even have a
// renderer. In that case, don't mark the widget for update.
if (attached() && renderer() && !useFallbackContent())
@@ -115,11 +156,18 @@ void HTMLPlugInImageElement::detach()
HTMLPlugInElement::detach();
}
-void HTMLPlugInImageElement::updateWidget()
+void HTMLPlugInImageElement::updateWidgetIfNecessary()
{
document()->updateStyleIfNeeded();
- if (needsWidgetUpdate() && renderEmbeddedObject() && !useFallbackContent() && !isImageType())
- renderEmbeddedObject()->updateWidget(true);
+
+ if (!needsWidgetUpdate() || useFallbackContent() || isImageType())
+ return;
+
+ if (!renderEmbeddedObject() || renderEmbeddedObject()->pluginCrashedOrWasMissing())
+ return;
+
+ // True indicates that this code path should only create non-netscape plugins (no clue why).
+ updateWidget(true);
}
void HTMLPlugInImageElement::finishParsingChildren()
@@ -142,7 +190,7 @@ void HTMLPlugInImageElement::willMoveToNewOwnerDocument()
void HTMLPlugInImageElement::updateWidgetCallback(Node* n)
{
- static_cast<HTMLPlugInImageElement*>(n)->updateWidget();
+ static_cast<HTMLPlugInImageElement*>(n)->updateWidgetIfNecessary();
}
} // namespace WebCore
diff --git a/WebCore/html/HTMLPlugInImageElement.h b/WebCore/html/HTMLPlugInImageElement.h
index 65c5f37..60ad0e6 100644
--- a/WebCore/html/HTMLPlugInImageElement.h
+++ b/WebCore/html/HTMLPlugInImageElement.h
@@ -27,23 +27,23 @@
namespace WebCore {
class HTMLImageLoader;
+class FrameLoader;
// Base class for HTMLObjectElement and HTMLEmbedElement
class HTMLPlugInImageElement : public HTMLPlugInElement {
public:
- const String& serviceType() const { return m_serviceType; }
- const String& url() const { return m_url; }
-
- bool needsWidgetUpdate() const { return m_needsWidgetUpdate; }
- void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
-
RenderEmbeddedObject* renderEmbeddedObject() const;
+ virtual void updateWidget(bool onlyCreateNonNetscapePlugins) = 0;
+
protected:
HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser);
bool isImageType();
+ const String& serviceType() const { return m_serviceType; }
+ const String& url() const { return m_url; }
+
OwnPtr<HTMLImageLoader> m_imageLoader;
String m_serviceType;
String m_url;
@@ -52,6 +52,12 @@ protected:
virtual void attach();
virtual void detach();
+ bool needsWidgetUpdate() const { return m_needsWidgetUpdate; }
+ void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
+
+ bool allowedToLoadFrameURL(const String& url);
+ bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
+
private:
virtual bool canLazyAttach() { return false; }
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
@@ -60,7 +66,7 @@ private:
virtual void finishParsingChildren();
virtual void willMoveToNewOwnerDocument();
- void updateWidget();
+ void updateWidgetIfNecessary();
virtual bool useFallbackContent() const { return false; }
bool m_needsWidgetUpdate;
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp
index b1b6d23..c680e92 100644
--- a/WebCore/html/HTMLSelectElement.cpp
+++ b/WebCore/html/HTMLSelectElement.cpp
@@ -85,8 +85,17 @@ void HTMLSelectElement::setSelectedIndex(int optionIndex, bool deselect)
SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, false, false);
}
-void HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow)
+void HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow, bool allowMultipleSelection)
{
+ // List box selects can fire onchange events through user interaction, such as
+ // mousedown events. This allows that same behavior programmatically.
+ if (!m_data.usesMenuList()) {
+ updateSelectedState(m_data, this, optionIndex, allowMultipleSelection, false);
+ if (fireOnChangeNow)
+ listBoxOnChange();
+ return;
+ }
+
// Bail out if this index is already the selected one, to avoid running unnecessary JavaScript that can mess up
// autofill, when there is no actual change (see https://bugs.webkit.org/show_bug.cgi?id=35256 and rdar://7467917 ).
// Perhaps this logic could be moved into SelectElement, but some callers of SelectElement::setSelectedIndex()
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index 79b0789..a3b4460 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -41,7 +41,7 @@ public:
virtual int selectedIndex() const;
virtual void setSelectedIndex(int index, bool deselect = true);
- virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false);
+ virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false);
unsigned length() const;
diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp
index 3299b27..f7217eb 100644
--- a/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/WebCore/html/HTMLViewSourceDocument.cpp
@@ -41,7 +41,7 @@
#include "HTMLViewSourceParser.h"
#include "SegmentedString.h"
#include "Text.h"
-#include "TextDocument.h"
+#include "TextViewSourceParser.h"
namespace WebCore {
@@ -58,7 +58,6 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, co
PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
{
- // Use HTMLDocumentParser if applicable, otherwise use TextDocumentParser.
if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type)
#if ENABLE(XHTMLMP)
|| m_type == "application/vnd.wap.xhtml+xml"
@@ -66,7 +65,7 @@ PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
)
return HTMLViewSourceParser::create(this);
- return createTextDocumentParser(this);
+ return TextViewSourceParser::create(this);
}
void HTMLViewSourceDocument::createContainingTable()
@@ -96,13 +95,6 @@ void HTMLViewSourceDocument::createContainingTable()
m_current = m_tbody;
}
-void HTMLViewSourceDocument::addViewSourceText(const String& text)
-{
- if (!m_current)
- createContainingTable();
- addText(text, "");
-}
-
void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
{
if (!m_current)
diff --git a/WebCore/html/HTMLViewSourceDocument.h b/WebCore/html/HTMLViewSourceDocument.h
index 445c95b..30e4df3 100644
--- a/WebCore/html/HTMLViewSourceDocument.h
+++ b/WebCore/html/HTMLViewSourceDocument.h
@@ -42,9 +42,6 @@ public:
void addSource(const String&, HTMLToken&);
- void addViewSourceToken(HTMLToken&); // Used by the HTMLDocumentParser.
- void addViewSourceText(const String&); // Used by the TextDocumentParser.
-
private:
HTMLViewSourceDocument(Frame*, const KURL&, const String& mimeType);
diff --git a/WebCore/loader/ImageDocument.cpp b/WebCore/html/ImageDocument.cpp
index 702ed9d..6951b7b 100644
--- a/WebCore/loader/ImageDocument.cpp
+++ b/WebCore/html/ImageDocument.cpp
@@ -138,7 +138,7 @@ void ImageDocumentParser::appendBytes(DocumentWriter*, const char*, int, bool)
void ImageDocumentParser::finish()
{
- if (!m_parserStopped && document()->imageElement()) {
+ if (!isStopped() && document()->imageElement()) {
CachedImage* cachedImage = document()->cachedImage();
RefPtr<SharedBuffer> data = document()->frame()->loader()->documentLoader()->mainResourceData();
@@ -152,7 +152,9 @@ void ImageDocumentParser::finish()
cachedImage->setResponse(document()->frame()->loader()->documentLoader()->response());
- IntSize size = cachedImage->imageSize(pageZoomFactor(document()));
+ // Report the natural image size in the page title, regardless of zoom
+ // level.
+ IntSize size = cachedImage->imageSize(1.0f);
if (size.width()) {
// Compute the title, we use the decoded filename of the resource, falling
// back on the (decoded) hostname if there is no path.
diff --git a/WebCore/loader/ImageDocument.h b/WebCore/html/ImageDocument.h
index 5d00bd6..5d00bd6 100644
--- a/WebCore/loader/ImageDocument.h
+++ b/WebCore/html/ImageDocument.h
diff --git a/WebCore/loader/MediaDocument.cpp b/WebCore/html/MediaDocument.cpp
index 77c3d1f..875141b 100644
--- a/WebCore/loader/MediaDocument.cpp
+++ b/WebCore/html/MediaDocument.cpp
@@ -72,7 +72,7 @@ void MediaDocumentParser::createDocumentStructure()
RefPtr<Element> rootElement = document()->createElement(htmlTag, false);
document()->appendChild(rootElement, ec);
- if (document()->frame() && document()->frame()->loader())
+ if (document()->frame())
document()->frame()->loader()->dispatchDocumentElementAvailable();
RefPtr<Element> body = document()->createElement(bodyTag, false);
diff --git a/WebCore/loader/MediaDocument.h b/WebCore/html/MediaDocument.h
index 2d81296..2d81296 100644
--- a/WebCore/loader/MediaDocument.h
+++ b/WebCore/html/MediaDocument.h
diff --git a/WebCore/loader/PluginDocument.cpp b/WebCore/html/PluginDocument.cpp
index ad11dfb..ad11dfb 100644
--- a/WebCore/loader/PluginDocument.cpp
+++ b/WebCore/html/PluginDocument.cpp
diff --git a/WebCore/loader/PluginDocument.h b/WebCore/html/PluginDocument.h
index 3bb5d99..3bb5d99 100644
--- a/WebCore/loader/PluginDocument.h
+++ b/WebCore/html/PluginDocument.h
diff --git a/WebCore/html/TextDocument.cpp b/WebCore/html/TextDocument.cpp
new file mode 100644
index 0000000..9334a39
--- /dev/null
+++ b/WebCore/html/TextDocument.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextDocument.h"
+
+#include "TextDocumentParser.h"
+
+namespace WebCore {
+
+TextDocument::TextDocument(Frame* frame, const KURL& url)
+ : HTMLDocument(frame, url)
+{
+ setCompatibilityMode(QuirksMode);
+ lockCompatibilityMode();
+}
+
+PassRefPtr<DocumentParser> TextDocument::createParser()
+{
+ return TextDocumentParser::create(this);
+}
+
+}
diff --git a/WebCore/loader/TextDocument.h b/WebCore/html/TextDocument.h
index d5bf153..2ea49f8 100644
--- a/WebCore/loader/TextDocument.h
+++ b/WebCore/html/TextDocument.h
@@ -29,8 +29,6 @@
namespace WebCore {
-class HTMLViewSourceDocument;
-
class TextDocument : public HTMLDocument {
public:
static PassRefPtr<TextDocument> create(Frame* frame, const KURL& url)
@@ -44,8 +42,6 @@ private:
virtual PassRefPtr<DocumentParser> createParser();
};
-PassRefPtr<DocumentParser> createTextDocumentParser(HTMLViewSourceDocument*);
-
}
-#endif // TextDocument_h
+#endif
diff --git a/WebCore/html/canvas/ArrayBufferView.cpp b/WebCore/html/canvas/ArrayBufferView.cpp
index bd22f88..485d18b 100644
--- a/WebCore/html/canvas/ArrayBufferView.cpp
+++ b/WebCore/html/canvas/ArrayBufferView.cpp
@@ -59,6 +59,34 @@ void ArrayBufferView::setImpl(ArrayBufferView* array, unsigned byteOffset, Excep
memmove(base + byteOffset, array->baseAddress(), array->byteLength());
}
+void ArrayBufferView::setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset, ExceptionCode& ec)
+{
+ if (byteOffset > byteLength()
+ || byteOffset + dataByteLength > byteLength()
+ || byteOffset + dataByteLength < byteOffset) {
+ // Out of range offset or overflow
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ char* base = static_cast<char*>(baseAddress());
+ memmove(base + byteOffset, data, dataByteLength);
+}
+
+void ArrayBufferView::zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength, ExceptionCode& ec)
+{
+ if (byteOffset > byteLength()
+ || byteOffset + rangeByteLength > byteLength()
+ || byteOffset + rangeByteLength < byteOffset) {
+ // Out of range offset or overflow
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ char* base = static_cast<char*>(baseAddress());
+ memset(base + byteOffset, 0, rangeByteLength);
+}
+
void ArrayBufferView::calculateOffsetAndLength(int start, int end, unsigned arraySize,
unsigned* offset, unsigned* length)
{
diff --git a/WebCore/html/canvas/ArrayBufferView.h b/WebCore/html/canvas/ArrayBufferView.h
index 29ad691..ee685b1 100644
--- a/WebCore/html/canvas/ArrayBufferView.h
+++ b/WebCore/html/canvas/ArrayBufferView.h
@@ -73,6 +73,10 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
void setImpl(ArrayBufferView* array, unsigned byteOffset, ExceptionCode& ec);
+ void setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset, ExceptionCode& ec);
+
+ void zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength, ExceptionCode& ec);
+
static void calculateOffsetAndLength(int start, int end, unsigned arraySize,
unsigned* offset, unsigned* length);
diff --git a/WebCore/html/canvas/CanvasRenderingContext.cpp b/WebCore/html/canvas/CanvasRenderingContext.cpp
index 1e897d3..e019332 100644
--- a/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -25,9 +25,6 @@
#include "config.h"
#include "CanvasRenderingContext.h"
-#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(3D_CANVAS)
-#include "GraphicsContext3D.h"
-#endif
#include "HTMLCanvasElement.h"
namespace WebCore {
@@ -47,13 +44,4 @@ void CanvasRenderingContext::deref()
m_canvas->deref();
}
-bool CanvasRenderingContext::paintsIntoCanvasBuffer() const
-{
-#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(3D_CANVAS)
- if (GraphicsContext3D* context3D = graphicsContext3D())
- return context3D->paintsIntoCanvasBuffer();
-#endif
- return true;
-}
-
} // namespace WebCore
diff --git a/WebCore/html/canvas/CanvasRenderingContext.h b/WebCore/html/canvas/CanvasRenderingContext.h
index 2cdbe1d..8499b47 100644
--- a/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/WebCore/html/canvas/CanvasRenderingContext.h
@@ -26,12 +26,13 @@
#ifndef CanvasRenderingContext_h
#define CanvasRenderingContext_h
+#include "GraphicsLayer.h"
+
#include <wtf/Noncopyable.h>
namespace WebCore {
class WebGLObject;
- class GraphicsContext3D;
class HTMLCanvasElement;
class CanvasRenderingContext : public Noncopyable {
@@ -49,12 +50,12 @@ namespace WebCore {
virtual bool is3d() const { return false; }
virtual bool isAccelerated() const { return false; }
- // For accelerated canvases, returns a pointer to the underlying GraphicsContext3D.
- // For non accelerated canvases returns 0.
- virtual GraphicsContext3D* graphicsContext3D() const { return 0; }
-
virtual void paintRenderingResultsToCanvas() {}
- bool paintsIntoCanvasBuffer() const;
+ virtual bool paintsIntoCanvasBuffer() const { return true; }
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const { return 0; }
+#endif
private:
HTMLCanvasElement* m_canvas;
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 6df6abf..338960c 100644..100755
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -25,7 +25,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -59,8 +59,12 @@
#include "TextMetrics.h"
#if ENABLE(ACCELERATED_2D_CANVAS)
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DrawingBuffer.h"
#include "FrameView.h"
#include "GraphicsContext3D.h"
+#include "SharedGraphicsContext3D.h"
#if USE(ACCELERATED_COMPOSITING)
#include "RenderLayer.h"
#endif
@@ -124,17 +128,11 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, bo
return;
if (!p->settings()->accelerated2dCanvasEnabled())
return;
- if (FrameView* view = canvas->document()->view()) {
- if (ScrollView* rootView = view->root()) {
- if (HostWindow* hostWindow = rootView->hostWindow()) {
- // Set up our context
- GraphicsContext3D::Attributes attr;
- attr.stencil = true;
- m_context3D = GraphicsContext3D::create(attr, hostWindow);
- if (m_context3D)
- if (GraphicsContext* c = drawingContext())
- c->setGraphicsContext3D(m_context3D.get(), IntSize(canvas->width(), canvas->height()));
- }
+ m_context3D = p->chrome()->client()->getSharedGraphicsContext3D();
+ if (m_context3D) {
+ if (GraphicsContext* c = drawingContext()) {
+ m_drawingBuffer = DrawingBuffer::create(m_context3D.get(), IntSize(canvas->width(), canvas->height()));
+ c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas->width(), canvas->height()));
}
}
#endif
@@ -153,6 +151,16 @@ bool CanvasRenderingContext2D::isAccelerated() const
#endif
}
+bool CanvasRenderingContext2D::paintsIntoCanvasBuffer() const
+{
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (m_context3D)
+ return m_context3D->paintsIntoCanvasBuffer();
+#endif
+ return true;
+}
+
+
void CanvasRenderingContext2D::reset()
{
m_stateStack.resize(1);
@@ -160,8 +168,10 @@ void CanvasRenderingContext2D::reset()
m_path.clear();
#if ENABLE(ACCELERATED_2D_CANVAS)
if (m_context3D) {
- if (GraphicsContext* c = drawingContext())
- c->setGraphicsContext3D(m_context3D.get(), IntSize(canvas()->width(), canvas()->height()));
+ if (GraphicsContext* c = drawingContext()) {
+ m_drawingBuffer->reset(IntSize(canvas()->width(), canvas()->height()));
+ c->setSharedGraphicsContext3D(m_context3D.get(), m_drawingBuffer.get(), IntSize(canvas()->width(), canvas()->height()));
+ }
}
#endif
}
@@ -209,7 +219,7 @@ void CanvasRenderingContext2D::restore()
c->restore();
}
-void CanvasRenderingContext2D::setAllAttributesToDefault()
+void CanvasRenderingContext2D::setAllAttributesToDefault()
{
state().m_globalAlpha = 1;
state().m_shadowOffset = FloatSize();
@@ -431,6 +441,15 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
if (!c)
return;
c->setCompositeOperation(op);
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (isAccelerated() && op != CompositeSourceOver) {
+ c->setSharedGraphicsContext3D(0, 0, IntSize());
+ m_drawingBuffer.clear();
+ m_context3D.clear();
+ // Mark as needing a style recalc so our compositing layer can be removed.
+ canvas()->setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+#endif
}
void CanvasRenderingContext2D::scale(float sx, float sy)
@@ -640,7 +659,7 @@ void CanvasRenderingContext2D::closePath()
FloatRect boundRect = m_path.boundingRect();
if (boundRect.width() || boundRect.height())
- m_path.closeSubpath();
+ m_path.closeCanvasSubpath();
}
void CanvasRenderingContext2D::moveTo(float x, float y)
@@ -924,7 +943,7 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
{
if (!validateRectForCanvas(x, y, width, height))
return;
-
+
if (!(lineWidth >= 0))
return;
@@ -1257,7 +1276,7 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
return;
if (!state().m_invertibleCTM)
return;
-
+
FloatRect sourceRect = c->roundToDevicePixels(srcRect);
FloatRect destRect = c->roundToDevicePixels(dstRect);
@@ -1269,7 +1288,16 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
if (!sourceCanvas->originClean())
canvas()->setOriginTainted();
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
+ // as that will do a readback to software.
+ CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext();
+ // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible.
+ if (!isAccelerated() || !sourceContext || !sourceContext->isAccelerated() || !sourceContext->is2d())
+ sourceCanvas->makeRenderingResultsAvailable();
+#else
sourceCanvas->makeRenderingResultsAvailable();
+#endif
c->drawImageBuffer(buffer, DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
didDraw(destRect);
@@ -1482,12 +1510,12 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
return;
FloatRect dirtyRect = r;
- if (options & CanvasWillDrawApplyTransform) {
+ if (options & CanvasDidDrawApplyTransform) {
AffineTransform ctm = state().m_transform;
dirtyRect = ctm.mapRect(r);
}
- if (options & CanvasWillDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
+ if (options & CanvasDidDrawApplyShadow && alphaChannel(state().m_shadowColor)) {
// The shadow gets applied after transformation
FloatRect shadowRect(dirtyRect);
shadowRect.move(state().m_shadowOffset);
@@ -1495,16 +1523,20 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& r, unsigned options)
dirtyRect.unite(shadowRect);
}
- if (options & CanvasWillDrawApplyClip) {
+ if (options & CanvasDidDrawApplyClip) {
// FIXME: apply the current clip to the rectangle. Unfortunately we can't get the clip
// back out of the GraphicsContext, so to take clip into account for incremental painting,
// we'd have to keep the clip path around.
}
+#if ENABLE(ACCELERATED_2D_CANVAS)
+ if (isAccelerated())
+ drawingContext()->markDirtyRect(enclosingIntRect(dirtyRect));
+#endif
#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
// If we are drawing to hardware and we have a composited layer, just call rendererContentChanged().
RenderBox* renderBox = canvas()->renderBox();
- if (m_context3D && renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
+ if (isAccelerated() && renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
renderBox->layer()->rendererContentChanged();
else
#endif
@@ -1577,7 +1609,7 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy,
scaledRect.setWidth(1);
if (scaledRect.height() < 1)
scaledRect.setHeight(1);
- ImageBuffer* buffer = canvas() ? canvas()->buffer() : 0;
+ ImageBuffer* buffer = canvas()->buffer();
if (!buffer)
return createEmptyImageData(scaledRect.size());
return buffer->getUnmultipliedImageData(scaledRect);
@@ -1630,7 +1662,7 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy,
IntPoint destPoint(destOffset.width(), destOffset.height());
buffer->putUnmultipliedImageData(data, sourceRect, destPoint);
- didDraw(sourceRect, 0); // ignore transform, shadow and clip
+ didDraw(sourceRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip
}
String CanvasRenderingContext2D::font() const
@@ -1850,11 +1882,11 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
c->drawBidiText(font, textRun, location);
if (fill)
- canvas()->didDraw(textRect);
+ didDraw(textRect);
else {
// When stroking text, pointy miters can extend outside of textRect, so we
// punt and dirty the whole canvas.
- canvas()->didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+ didDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
}
#if PLATFORM(QT)
@@ -1877,4 +1909,11 @@ void CanvasRenderingContext2D::paintRenderingResultsToCanvas()
#endif
}
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+PlatformLayer* CanvasRenderingContext2D::platformLayer() const
+{
+ return m_drawingBuffer->platformLayer();
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.h b/WebCore/html/canvas/CanvasRenderingContext2D.h
index 9857344..91b6549 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CanvasRenderingContext2D_h
@@ -61,7 +61,8 @@ class KURL;
class TextMetrics;
#if ENABLE(ACCELERATED_2D_CANVAS)
-class GraphicsContext3D;
+class DrawingBuffer;
+class SharedGraphicsContext3D;
#endif
typedef int ExceptionCode;
@@ -74,6 +75,7 @@ public:
virtual bool is2d() const { return true; }
virtual bool isAccelerated() const;
+ virtual bool paintsIntoCanvasBuffer() const;
CanvasStyle* strokeStyle() const;
void setStrokeStyle(PassRefPtr<CanvasStyle>);
@@ -223,8 +225,8 @@ public:
virtual void paintRenderingResultsToCanvas();
-#if ENABLE(ACCELERATED_2D_CANVAS)
- virtual GraphicsContext3D* graphicsContext3D() const { return m_context3D.get(); }
+#if ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const;
#endif
private:
@@ -262,14 +264,15 @@ private:
void applyShadow();
- enum CanvasWillDrawOption {
- CanvasWillDrawApplyTransform = 1,
- CanvasWillDrawApplyShadow = 1 << 1,
- CanvasWillDrawApplyClip = 1 << 2,
- CanvasWillDrawApplyAll = 0xffffffff
+ enum CanvasDidDrawOption {
+ CanvasDidDrawApplyNone = 0,
+ CanvasDidDrawApplyTransform = 1,
+ CanvasDidDrawApplyShadow = 1 << 1,
+ CanvasDidDrawApplyClip = 1 << 2,
+ CanvasDidDrawApplyAll = 0xffffffff
};
- void didDraw(const FloatRect&, unsigned options = CanvasWillDrawApplyAll);
+ void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
GraphicsContext* drawingContext() const;
@@ -298,7 +301,8 @@ private:
#endif
#if ENABLE(ACCELERATED_2D_CANVAS)
- OwnPtr<GraphicsContext3D> m_context3D;
+ OwnPtr<DrawingBuffer> m_drawingBuffer;
+ RefPtr<SharedGraphicsContext3D> m_context3D;
#endif
};
diff --git a/WebCore/html/canvas/TypedArrayBase.h b/WebCore/html/canvas/TypedArrayBase.h
index e69c2b5..77283df 100644
--- a/WebCore/html/canvas/TypedArrayBase.h
+++ b/WebCore/html/canvas/TypedArrayBase.h
@@ -42,6 +42,16 @@ class TypedArrayBase : public ArrayBufferView {
setImpl(array, offset * sizeof(T), ec);
}
+ void setRange(const T* data, size_t dataLength, unsigned offset, ExceptionCode& ec)
+ {
+ setRangeImpl(reinterpret_cast<const char*>(data), dataLength * sizeof(T), offset * sizeof(T), ec);
+ }
+
+ void zeroRange(unsigned offset, size_t length, ExceptionCode& ec)
+ {
+ zeroRangeImpl(offset * sizeof(T), length * sizeof(T), ec);
+ }
+
// Overridden from ArrayBufferView. This must be public because of
// rules about inheritance of members in template classes, and
// because it is accessed via pointers to subclasses.
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 2a1464a..bda3569 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -170,6 +170,11 @@ void WebGLRenderingContext::paintRenderingResultsToCanvas()
m_context->paintRenderingResultsToCanvas(this);
}
+bool WebGLRenderingContext::paintsIntoCanvasBuffer() const
+{
+ return m_context->paintsIntoCanvasBuffer();
+}
+
void WebGLRenderingContext::reshape(int width, int height)
{
if (m_needsUpdate) {
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index 66ec8d8..d812c69 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -63,6 +63,7 @@ public:
virtual bool is3d() const { return true; }
virtual bool isAccelerated() const { return true; }
+ virtual bool paintsIntoCanvasBuffer() const;
void activeTexture(unsigned long texture, ExceptionCode& ec);
void attachShader(WebGLProgram*, WebGLShader*, ExceptionCode& ec);
@@ -277,7 +278,10 @@ public:
void viewport(long x, long y, unsigned long width, unsigned long height);
- virtual GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+ GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+#if USE(ACCELERATED_COMPOSITING)
+ virtual PlatformLayer* platformLayer() const { return m_context->platformLayer(); }
+#endif
void reshape(int width, int height);
diff --git a/WebCore/html/parser/CSSPreloadScanner.cpp b/WebCore/html/parser/CSSPreloadScanner.cpp
index 729103e..6ac923d 100644
--- a/WebCore/html/parser/CSSPreloadScanner.cpp
+++ b/WebCore/html/parser/CSSPreloadScanner.cpp
@@ -30,7 +30,7 @@
#include "CSSHelper.h"
#include "CachedCSSStyleSheet.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "HTMLToken.h"
@@ -151,7 +151,7 @@ void CSSPreloadScanner::emitRule()
String value(m_ruleValue.data(), m_ruleValue.size());
String url = deprecatedParseURL(value);
if (!url.isEmpty())
- m_document->docLoader()->preload(CachedResource::CSSStyleSheet, url, String(), m_scanningBody);
+ m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, url, String(), m_scanningBody);
}
m_rule.clear();
m_ruleValue.clear();
diff --git a/WebCore/html/parser/HTMLConstructionSite.cpp b/WebCore/html/parser/HTMLConstructionSite.cpp
index 975b1af..0172b3d 100644
--- a/WebCore/html/parser/HTMLConstructionSite.cpp
+++ b/WebCore/html/parser/HTMLConstructionSite.cpp
@@ -213,7 +213,7 @@ void HTMLConstructionSite::insertDoctype(AtomicHTMLToken& token)
void HTMLConstructionSite::insertComment(AtomicHTMLToken& token)
{
ASSERT(token.type() == HTMLToken::Comment);
- attach(currentElement(), Comment::create(m_document, token.comment()));
+ attach(currentElement(), Comment::create(currentElement()->document(), token.comment()));
}
void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken& token)
@@ -225,7 +225,8 @@ void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken& token)
void HTMLConstructionSite::insertCommentOnHTMLHtmlElement(AtomicHTMLToken& token)
{
ASSERT(token.type() == HTMLToken::Comment);
- attach(m_openElements.htmlElement(), Comment::create(m_document, token.comment()));
+ Element* parent = m_openElements.htmlElement();
+ attach(parent, Comment::create(parent->document(), token.comment()));
}
PassRefPtr<Element> HTMLConstructionSite::attachToCurrent(PassRefPtr<Element> child)
@@ -293,7 +294,7 @@ void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken& token)
void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken& token)
{
- RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, m_document, true);
+ RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, currentElement()->document(), true);
if (m_fragmentScriptingPermission == FragmentScriptingAllowed)
element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
m_openElements.push(attachToCurrent(element.release()));
@@ -326,13 +327,13 @@ void HTMLConstructionSite::insertTextNode(const String& characters)
return;
}
- attachAtSite(site, Text::create(m_document, characters));
+ attachAtSite(site, Text::create(site.parent->document(), characters));
}
PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken& token, const AtomicString& namespaceURI)
{
QualifiedName tagName(nullAtom, token.name(), namespaceURI);
- RefPtr<Element> element = m_document->createElement(tagName, true);
+ RefPtr<Element> element = currentElement()->document()->createElement(tagName, true);
element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
return element.release();
}
@@ -343,7 +344,7 @@ 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(tagName, m_document, form(), true);
+ RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, currentElement()->document(), form(), true);
element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
ASSERT(element->isHTMLElement());
return element.release();
diff --git a/WebCore/html/parser/HTMLDocumentParser.cpp b/WebCore/html/parser/HTMLDocumentParser.cpp
index 0a1208d..a442d54 100644
--- a/WebCore/html/parser/HTMLDocumentParser.cpp
+++ b/WebCore/html/parser/HTMLDocumentParser.cpp
@@ -146,6 +146,32 @@ void HTMLDocumentParser::stopParsing()
m_parserScheduler.clear(); // Deleting the scheduler will clear any timers.
}
+// This kicks off "Once the user agent stops parsing" as described by:
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
+void HTMLDocumentParser::prepareToStopParsing()
+{
+ ASSERT(!hasInsertionPoint());
+
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtr<HTMLDocumentParser> protect(this);
+
+ // NOTE: This pump should only ever emit buffered character tokens,
+ // so ForceSynchronous vs. AllowYield should be meaningless.
+ pumpTokenizerIfPossible(ForceSynchronous);
+
+ if (isStopped())
+ return;
+
+ DocumentParser::prepareToStopParsing();
+
+ // We will not have a scriptRunner when parsing a DocumentFragment.
+ if (m_scriptRunner)
+ document()->setReadyState(Document::Interactive);
+
+ attemptToRunDeferredScriptsAndEnd();
+}
+
bool HTMLDocumentParser::processingData() const
{
return isScheduledForResume() || inWrite();
@@ -153,7 +179,7 @@ bool HTMLDocumentParser::processingData() const
void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
{
- if (m_parserStopped || m_treeBuilder->isPaused())
+ if (isStopped() || m_treeBuilder->isPaused())
return;
// Once a resume is scheduled, HTMLParserScheduler controls when we next pump.
@@ -197,8 +223,7 @@ bool HTMLDocumentParser::runScriptsForPausedTreeBuilder()
void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
{
- ASSERT(!isDetached());
- ASSERT(!m_parserStopped);
+ ASSERT(!isStopped());
ASSERT(!m_treeBuilder->isPaused());
ASSERT(!isScheduledForResume());
// ASSERT that this object is both attached to the Document and protected.
@@ -218,7 +243,7 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
m_token.clear();
// JavaScript may have stopped or detached the parser.
- if (isDetached() || m_parserStopped)
+ if (isStopped())
return;
// The parser will pause itself when waiting on a script to load or run.
@@ -230,7 +255,7 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
m_treeBuilder->setPaused(!shouldContinueParsing);
// JavaScript may have stopped or detached the parser.
- if (isDetached() || m_parserStopped)
+ if (isStopped())
return;
if (!shouldContinueParsing)
@@ -279,7 +304,7 @@ bool HTMLDocumentParser::hasInsertionPoint()
void HTMLDocumentParser::insert(const SegmentedString& source)
{
- if (m_parserStopped)
+ if (isStopped())
return;
#ifdef ANDROID_INSTRUMENT
@@ -304,7 +329,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
void HTMLDocumentParser::append(const SegmentedString& source)
{
- if (m_parserStopped)
+ if (isStopped())
return;
// pumpTokenizer can cause this parser to be detached from the Document,
@@ -342,18 +367,19 @@ void HTMLDocumentParser::end()
ASSERT(!isDetached());
ASSERT(!isScheduledForResume());
- // pumpTokenizer can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
-
- // NOTE: This pump should only ever emit buffered character tokens,
- // so ForceSynchronous vs. AllowYield should be meaningless.
- pumpTokenizerIfPossible(ForceSynchronous);
-
// Informs the the rest of WebCore that parsing is really finished (and deletes this).
m_treeBuilder->finished();
}
+void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()
+{
+ ASSERT(isStopping());
+ ASSERT(!hasInsertionPoint());
+ if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
+ return;
+ end();
+}
+
void HTMLDocumentParser::attemptToEnd()
{
// finish() indicates we will not receive any more data. If we are waiting on
@@ -363,7 +389,7 @@ void HTMLDocumentParser::attemptToEnd()
m_endWasDelayed = true;
return;
}
- end();
+ prepareToStopParsing();
}
void HTMLDocumentParser::endIfDelayed()
@@ -376,7 +402,7 @@ void HTMLDocumentParser::endIfDelayed()
return;
m_endWasDelayed = false;
- end();
+ prepareToStopParsing();
}
void HTMLDocumentParser::finish()
@@ -467,6 +493,11 @@ void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
ASSERT(m_scriptRunner);
ASSERT(!inScriptExecution());
+ if (isStopping()) {
+ attemptToRunDeferredScriptsAndEnd();
+ return;
+ }
+
ASSERT(m_treeBuilder->isPaused());
// Note: We only ever wait on one script at a time, so we always know this
// is the one we were waiting on and can un-pause the tree builder.
diff --git a/WebCore/html/parser/HTMLDocumentParser.h b/WebCore/html/parser/HTMLDocumentParser.h
index da21a2b..6d5b6d7 100644
--- a/WebCore/html/parser/HTMLDocumentParser.h
+++ b/WebCore/html/parser/HTMLDocumentParser.h
@@ -69,18 +69,22 @@ public:
protected:
virtual void insert(const SegmentedString&);
+ virtual void append(const SegmentedString&);
virtual void finish();
HTMLDocumentParser(HTMLDocument*, bool reportErrors);
HTMLDocumentParser(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
+ HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
+ HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
+
private:
// DocumentParser
virtual void detach();
virtual bool hasInsertionPoint();
- virtual void append(const SegmentedString&);
virtual bool finishWasCalled();
virtual bool processingData() const;
+ virtual void prepareToStopParsing();
virtual void stopParsing();
virtual bool isWaitingForScripts() const;
virtual bool isExecutingScript() const;
@@ -113,6 +117,7 @@ private:
void begin();
void attemptToEnd();
void endIfDelayed();
+ void attemptToRunDeferredScriptsAndEnd();
void end();
bool isScheduledForResume() const;
diff --git a/WebCore/html/HTMLInputStream.h b/WebCore/html/parser/HTMLInputStream.h
index a709bd9..a709bd9 100644
--- a/WebCore/html/HTMLInputStream.h
+++ b/WebCore/html/parser/HTMLInputStream.h
diff --git a/WebCore/html/parser/HTMLPreloadScanner.cpp b/WebCore/html/parser/HTMLPreloadScanner.cpp
index 7aafd90..5283fa3 100644
--- a/WebCore/html/parser/HTMLPreloadScanner.cpp
+++ b/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -29,7 +29,7 @@
#include "HTMLPreloadScanner.h"
#include "CSSHelper.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "HTMLTokenizer.h"
#include "HTMLTreeBuilder.h"
@@ -98,13 +98,13 @@ public:
if (m_urlToLoad.isEmpty())
return;
- DocLoader* docLoader = document->docLoader();
+ CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
if (m_tagName == scriptTag)
- docLoader->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody);
+ cachedResourceLoader->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody);
else if (m_tagName == imgTag)
- docLoader->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody);
+ cachedResourceLoader->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody);
else if (m_tagName == linkTag && m_linkIsStyleSheet)
- docLoader->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody);
+ cachedResourceLoader->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody);
}
const AtomicString& tagName() const { return m_tagName; }
diff --git a/WebCore/html/parser/HTMLScriptRunner.cpp b/WebCore/html/parser/HTMLScriptRunner.cpp
index 6d470a0..e1fc120 100644
--- a/WebCore/html/parser/HTMLScriptRunner.cpp
+++ b/WebCore/html/parser/HTMLScriptRunner.cpp
@@ -28,7 +28,7 @@
#include "Attribute.h"
#include "CachedScript.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Element.h"
#include "Event.h"
#include "Frame.h"
@@ -75,6 +75,12 @@ HTMLScriptRunner::~HTMLScriptRunner()
// FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction?
if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parsingBlockingScript);
+
+ while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
+ PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst();
+ if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
+ stopWatchingForLoad(pendingScript);
+ }
}
void HTMLScriptRunner::detach()
@@ -129,10 +135,6 @@ void HTMLScriptRunner::executeParsingBlockingScript()
ASSERT(m_document->haveStylesheetsLoaded());
ASSERT(isPendingScriptReady(m_parsingBlockingScript));
- // Stop watching loads before executeScript to prevent recursion if the script reloads itself.
- if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
- stopWatchingForLoad(m_parsingBlockingScript);
-
InsertionPointRecord insertionPointRecord(m_host->inputStream());
executePendingScriptAndDispatchEvent(m_parsingBlockingScript);
}
@@ -142,6 +144,10 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
bool errorOccurred = false;
ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
+ // Stop watching loads before executeScript to prevent recursion if the script reloads itself.
+ if (pendingScript.cachedScript() && pendingScript.watchingForLoad())
+ stopWatchingForLoad(pendingScript);
+
// Clear the pending script before possible rentrancy from executeScript()
RefPtr<Element> scriptElement = pendingScript.releaseElementAndClear();
{
@@ -238,6 +244,24 @@ bool HTMLScriptRunner::executeScriptsWaitingForStylesheets()
return executeParsingBlockingScripts();
}
+bool HTMLScriptRunner::executeScriptsWaitingForParsing()
+{
+ while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
+ ASSERT(!m_scriptNestingLevel);
+ ASSERT(!haveParsingBlockingScript());
+ ASSERT(m_scriptsToExecuteAfterParsing.first().cachedScript());
+ if (!m_scriptsToExecuteAfterParsing.first().cachedScript()->isLoaded()) {
+ watchForLoad(m_scriptsToExecuteAfterParsing.first());
+ return false;
+ }
+ PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst();
+ executePendingScriptAndDispatchEvent(first);
+ if (!m_document)
+ return false;
+ }
+ return true;
+}
+
void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
{
if (!requestPendingScript(m_parsingBlockingScript, element))
@@ -252,6 +276,16 @@ void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
watchForLoad(m_parsingBlockingScript);
}
+void HTMLScriptRunner::requestDeferredScript(Element* element)
+{
+ PendingScript pendingScript;
+ if (!requestPendingScript(pendingScript, element))
+ return;
+
+ ASSERT(pendingScript.cachedScript());
+ m_scriptsToExecuteAfterParsing.append(pendingScript);
+}
+
bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Element* script) const
{
ASSERT(!pendingScript.element());
@@ -264,7 +298,7 @@ bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Elemen
return false;
pendingScript.adoptElement(script);
// This should correctly return 0 for empty or invalid srcValues.
- CachedScript* cachedScript = m_document->docLoader()->requestScript(srcValue, toScriptElement(script)->scriptCharset());
+ CachedScript* cachedScript = m_document->cachedResourceLoader()->requestScript(srcValue, toScriptElement(script)->scriptCharset());
if (!cachedScript) {
notImplemented(); // Dispatch error event.
return false;
@@ -287,8 +321,13 @@ void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
notImplemented(); // event for support
if (script->hasAttribute(srcAttr)) {
- // FIXME: Handle defer and async
- requestParsingBlockingScript(script);
+ if (script->hasAttribute(asyncAttr)) // Async takes precendence over defer.
+ return; // Asynchronous scripts handle themselves.
+
+ if (script->hasAttribute(deferAttr))
+ requestDeferredScript(script);
+ else
+ requestParsingBlockingScript(script);
} else {
// FIXME: We do not block inline <script> tags on stylesheets to match the
// old parser for now. When we do, the ASSERT below should be added.
diff --git a/WebCore/html/parser/HTMLScriptRunner.h b/WebCore/html/parser/HTMLScriptRunner.h
index ead9289..47c96fd 100644
--- a/WebCore/html/parser/HTMLScriptRunner.h
+++ b/WebCore/html/parser/HTMLScriptRunner.h
@@ -27,6 +27,7 @@
#define HTMLScriptRunner_h
#include "PendingScript.h"
+#include <wtf/Deque.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassRefPtr.h>
@@ -56,6 +57,7 @@ public:
bool executeScriptsWaitingForLoad(CachedResource*);
bool hasScriptsWaitingForStylesheets() const { return m_hasScriptsWaitingForStylesheets; }
bool executeScriptsWaitingForStylesheets();
+ bool executeScriptsWaitingForParsing();
bool isExecutingScript() const { return !!m_scriptNestingLevel; }
@@ -71,6 +73,7 @@ private:
bool executeParsingBlockingScripts();
void requestParsingBlockingScript(Element*);
+ void requestDeferredScript(Element*);
bool requestPendingScript(PendingScript&, Element*) const;
void runScript(Element*, int startingLineNumber);
@@ -84,6 +87,7 @@ private:
Document* m_document;
HTMLScriptRunnerHost* m_host;
PendingScript m_parsingBlockingScript;
+ Deque<PendingScript> m_scriptsToExecuteAfterParsing; // http://www.whatwg.org/specs/web-apps/current-work/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing
unsigned m_scriptNestingLevel;
// We only want stylesheet loads to trigger script execution if script
diff --git a/WebCore/html/parser/HTMLTokenizer.cpp b/WebCore/html/parser/HTMLTokenizer.cpp
index 5791842..f5405ff 100644
--- a/WebCore/html/parser/HTMLTokenizer.cpp
+++ b/WebCore/html/parser/HTMLTokenizer.cpp
@@ -293,7 +293,9 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
ADVANCE_TO(DataState);
if (m_state == RCDATAState)
ADVANCE_TO(RCDATAState);
- ASSERT_NOT_REACHED();
+ // When parsing text/plain documents, we run the tokenizer in the
+ // PLAINTEXTState and ignore m_skipLeadingNewLineForListing.
+ ASSERT(m_state == PLAINTEXTState);
}
}
diff --git a/WebCore/html/parser/HTMLTreeBuilder.cpp b/WebCore/html/parser/HTMLTreeBuilder.cpp
index 8c76fc0..406bb6c 100644
--- a/WebCore/html/parser/HTMLTreeBuilder.cpp
+++ b/WebCore/html/parser/HTMLTreeBuilder.cpp
@@ -463,6 +463,11 @@ HTMLTokenizer::State HTMLTreeBuilder::adjustedLexerState(HTMLTokenizer::State st
void HTMLTreeBuilder::constructTreeFromToken(HTMLToken& rawToken)
{
AtomicHTMLToken token(rawToken);
+ constructTreeFromAtomicToken(token);
+}
+
+void HTMLTreeBuilder::constructTreeFromAtomicToken(AtomicHTMLToken& token)
+{
processToken(token);
// Swallowing U+0000 characters isn't in the HTML5 spec, but turning all
diff --git a/WebCore/html/parser/HTMLTreeBuilder.h b/WebCore/html/parser/HTMLTreeBuilder.h
index c30e6b8..4634f0a 100644
--- a/WebCore/html/parser/HTMLTreeBuilder.h
+++ b/WebCore/html/parser/HTMLTreeBuilder.h
@@ -68,6 +68,8 @@ public:
// The token really should be passed as a const& since it's never modified.
void constructTreeFromToken(HTMLToken&);
+ void constructTreeFromAtomicToken(AtomicHTMLToken&);
+
// Must be called when parser is paused before calling the parser again.
PassRefPtr<Element> takeScriptToProcess(int& scriptStartLine);
diff --git a/WebCore/html/parser/HTMLViewSourceParser.h b/WebCore/html/parser/HTMLViewSourceParser.h
index 34caf43..abe55b4 100644
--- a/WebCore/html/parser/HTMLViewSourceParser.h
+++ b/WebCore/html/parser/HTMLViewSourceParser.h
@@ -50,9 +50,12 @@ public:
}
virtual ~HTMLViewSourceParser();
-private:
- HTMLViewSourceParser(HTMLViewSourceDocument*);
+protected:
+ explicit HTMLViewSourceParser(HTMLViewSourceDocument*);
+
+ HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
+private:
// DocumentParser
virtual void insert(const SegmentedString&);
virtual void append(const SegmentedString&);
diff --git a/WebCore/html/parser/TextDocumentParser.cpp b/WebCore/html/parser/TextDocumentParser.cpp
new file mode 100644
index 0000000..d03b744
--- /dev/null
+++ b/WebCore/html/parser/TextDocumentParser.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextDocumentParser.h"
+
+#include "HTMLDocument.h"
+#include "HTMLNames.h"
+#include "HTMLTokenizer.h"
+#include "HTMLTreeBuilder.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+TextDocumentParser::TextDocumentParser(HTMLDocument* document)
+ : HTMLDocumentParser(document, false)
+ , m_haveInsertedFakePreElement(false)
+{
+ tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+}
+
+TextDocumentParser::~TextDocumentParser()
+{
+}
+
+void TextDocumentParser::append(const SegmentedString& text)
+{
+ if (!m_haveInsertedFakePreElement)
+ insertFakePreElement();
+ HTMLDocumentParser::append(text);
+}
+
+void TextDocumentParser::insertFakePreElement()
+{
+ // In principle, we should create a specialized tree builder for
+ // TextDocuments, but instead we re-use the existing HTMLTreeBuilder.
+ // We create a fake token and give it to the tree builder rather than
+ // sending fake bytes through the front-end of the parser to avoid
+ // distrubing the line/column number calculations.
+
+ RefPtr<Attribute> styleAttribute = Attribute::createMapped("style", "word-wrap: break-word; white-space: pre-wrap;");
+ RefPtr<NamedNodeMap> attributes = NamedNodeMap::create();
+ attributes->insertAttribute(styleAttribute.release(), false);
+ AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), attributes.release());
+
+ treeBuilder()->constructTreeFromAtomicToken(fakePre);
+ m_haveInsertedFakePreElement = true;
+}
+
+}
diff --git a/WebCore/html/parser/TextDocumentParser.h b/WebCore/html/parser/TextDocumentParser.h
new file mode 100644
index 0000000..1cccc5b
--- /dev/null
+++ b/WebCore/html/parser/TextDocumentParser.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef TextDocumentParser_h
+#define TextDocumentParser_h
+
+#include "HTMLDocumentParser.h"
+
+namespace WebCore {
+
+class TextDocumentParser : public HTMLDocumentParser {
+public:
+ static PassRefPtr<TextDocumentParser> create(HTMLDocument* document)
+ {
+ return adoptRef(new TextDocumentParser(document));
+ }
+ virtual ~TextDocumentParser();
+
+private:
+ explicit TextDocumentParser(HTMLDocument*);
+
+ virtual void append(const SegmentedString&);
+ void insertFakePreElement();
+
+ bool m_haveInsertedFakePreElement;
+};
+
+}
+
+#endif
diff --git a/WebCore/html/parser/TextViewSourceParser.cpp b/WebCore/html/parser/TextViewSourceParser.cpp
new file mode 100644
index 0000000..d7e6e3d
--- /dev/null
+++ b/WebCore/html/parser/TextViewSourceParser.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextViewSourceParser.h"
+
+#include "HTMLTokenizer.h"
+
+namespace WebCore {
+
+TextViewSourceParser::TextViewSourceParser(HTMLViewSourceDocument* document)
+ : HTMLViewSourceParser(document)
+{
+ tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+}
+
+TextViewSourceParser::~TextViewSourceParser()
+{
+}
+
+}
diff --git a/WebCore/html/parser/TextViewSourceParser.h b/WebCore/html/parser/TextViewSourceParser.h
new file mode 100644
index 0000000..e4170ed
--- /dev/null
+++ b/WebCore/html/parser/TextViewSourceParser.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextViewSourceParser_h
+#define TextViewSourceParser_h
+
+#include "HTMLViewSourceParser.h"
+
+namespace WebCore {
+
+class TextViewSourceParser : public HTMLViewSourceParser {
+public:
+ static PassRefPtr<TextViewSourceParser> create(HTMLViewSourceDocument* document)
+ {
+ return adoptRef(new TextViewSourceParser(document));
+ }
+ virtual ~TextViewSourceParser();
+
+private:
+ explicit TextViewSourceParser(HTMLViewSourceDocument*);
+};
+
+}
+
+#endif
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm
index d76fbd3..c7907b4 100644
--- a/WebCore/inspector/CodeGeneratorInspector.pm
+++ b/WebCore/inspector/CodeGeneratorInspector.pm
@@ -533,7 +533,7 @@ WebInspector.InspectorBackendStub.prototype = {
}
if (args.length === 1) {
- if (typeof args[0] !== "function") {
+ if (typeof args[0] !== "function" && typeof args[0] !== "undefined") {
console.error("Protocol Error: Optional callback argument for 'InspectorBackend.%s' call should be a function but its type is '%s'.", request.command, typeof args[0]);
return;
}
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index ff1c2af..169b188 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -40,10 +40,9 @@ module core {
[notify] void childNodeCountUpdated(out long id, out int newValue);
[notify] void childNodeInserted(out long parentId, out long prevId, out Object node);
[notify] void childNodeRemoved(out long parentId, out long id);
- [notify] void close();
[notify] void didCommitLoad();
[notify] void evaluateForTestInFrontend(out long testCallId, out String script);
- [notify] void inspectedPageDestroyed();
+ [notify] void disconnectFromBackend();
[notify] void inspectedURLChanged(out String url);
[notify] void monitoringXHRWasEnabled();
[notify] void monitoringXHRWasDisabled();
@@ -73,7 +72,7 @@ module core {
[notify] void debuggerWasDisabled();
[notify] void failedToParseScriptSource(out String url, out String data, out int firstLine, out int errorLine, out String errorMessage);
[notify] void parsedScriptSource(out String sourceID, out String url, out String data, out int firstLine, out int scriptWorldType);
- [notify] void pausedScript(out Value callFrames);
+ [notify] void pausedScript(out Object details);
[notify] void profilerWasEnabled();
[notify] void profilerWasDisabled();
[notify] void restoredBreakpoint(out String sourceID, out String url, out int line, out boolean enabled, out String condition);
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index 7fb052c..1e131f7 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -59,11 +59,12 @@
#include "InspectorBackendDispatcher.h"
#include "InspectorCSSStore.h"
#include "InspectorClient.h"
-#include "InspectorFrontend.h"
-#include "InspectorFrontendClient.h"
+#include "InspectorDOMAgent.h"
#include "InspectorDOMStorageResource.h"
#include "InspectorDatabaseResource.h"
#include "InspectorDebuggerAgent.h"
+#include "InspectorFrontend.h"
+#include "InspectorFrontendClient.h"
#include "InspectorProfilerAgent.h"
#include "InspectorResource.h"
#include "InspectorStorageAgent.h"
@@ -198,7 +199,7 @@ InspectorController::~InspectorController()
void InspectorController::inspectedPageDestroyed()
{
if (m_frontend)
- m_frontend->inspectedPageDestroyed();
+ m_frontend->disconnectFromBackend();
hideHighlight();
@@ -537,7 +538,8 @@ void InspectorController::close()
{
if (!m_frontend)
return;
- m_frontend->close();
+ m_frontend->disconnectFromBackend();
+ disconnectFrontend();
}
void InspectorController::disconnectFrontend()
@@ -1843,6 +1845,58 @@ void InspectorController::reloadPage()
m_inspectedPage->mainFrame()->redirectScheduler()->scheduleRefresh(true);
}
+void InspectorController::willInsertDOMNodeImpl(Node* node, Node* parent)
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (!m_debuggerAgent || !m_domAgent)
+ return;
+ PassRefPtr<InspectorValue> details;
+ if (m_domAgent->shouldBreakOnNodeInsertion(node, parent, &details))
+ m_debuggerAgent->breakProgram(details);
+#endif
+}
+
+void InspectorController::didInsertDOMNodeImpl(Node* node)
+{
+ if (m_domAgent)
+ m_domAgent->didInsertDOMNode(node);
+}
+
+void InspectorController::willRemoveDOMNodeImpl(Node* node)
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (!m_debuggerAgent || !m_domAgent)
+ return;
+ PassRefPtr<InspectorValue> details;
+ if (m_domAgent->shouldBreakOnNodeRemoval(node, &details))
+ m_debuggerAgent->breakProgram(details);
+#endif
+}
+
+void InspectorController::didRemoveDOMNodeImpl(Node* node)
+{
+ if (m_domAgent)
+ m_domAgent->didRemoveDOMNode(node);
+}
+
+void InspectorController::willModifyDOMAttrImpl(Element* element)
+{
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ if (!m_debuggerAgent || !m_domAgent)
+ return;
+ PassRefPtr<InspectorValue> details;
+ if (m_domAgent->shouldBreakOnAttributeModification(element, &details))
+ m_debuggerAgent->breakProgram(details);
+#endif
+}
+
+void InspectorController::didModifyDOMAttrImpl(Element* element)
+{
+ if (m_domAgent)
+ m_domAgent->didModifyDOMAttr(element);
+}
+
+
} // namespace WebCore
#endif // ENABLE(INSPECTOR)
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index 7ed2549..40099c6 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -31,7 +31,8 @@
#include "Console.h"
#include "Cookie.h"
-#include "InspectorDOMAgent.h"
+#include "Element.h"
+#include "Page.h"
#include "PlatformString.h"
#include "ScriptState.h"
#include <wtf/HashMap.h>
@@ -58,6 +59,7 @@ class InspectorBackend;
class InspectorBackendDispatcher;
class InspectorClient;
class InspectorCSSStore;
+class InspectorDOMAgent;
class InspectorDOMStorageResource;
class InspectorDatabaseResource;
class InspectorDebuggerAgent;
@@ -183,9 +185,12 @@ public:
void mainResourceFiredLoadEvent(DocumentLoader*, const KURL&);
void mainResourceFiredDOMContentEvent(DocumentLoader*, const KURL&);
- void didInsertDOMNode(Node*);
- void didRemoveDOMNode(Node*);
- void didModifyDOMAttr(Element*);
+ static void willInsertDOMNode(Node* node, Node* parent);
+ static void didInsertDOMNode(Node*);
+ static void willRemoveDOMNode(Node*);
+ static void willModifyDOMAttr(Element*);
+ static void didModifyDOMAttr(Element*);
+
#if ENABLE(WORKERS)
enum WorkerAction { WorkerCreated, WorkerDestroyed };
@@ -306,6 +311,14 @@ private:
void didEvaluateForTestInFrontend(long callId, const String& jsonResult);
+ static InspectorController* inspectorControllerForNode(Node*);
+ void willInsertDOMNodeImpl(Node* node, Node* parent);
+ void didInsertDOMNodeImpl(Node*);
+ void willRemoveDOMNodeImpl(Node*);
+ void didRemoveDOMNodeImpl(Node*);
+ void willModifyDOMAttrImpl(Element*);
+ void didModifyDOMAttrImpl(Element*);
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
friend class InspectorDebuggerAgent;
String breakpointsSettingKey();
@@ -376,30 +389,62 @@ private:
#endif
};
+inline void InspectorController::willInsertDOMNode(Node* node, Node* parent)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspectorController = inspectorControllerForNode(parent))
+ inspectorController->willInsertDOMNodeImpl(node, parent);
+#endif
+}
+
inline void InspectorController::didInsertDOMNode(Node* node)
{
#if ENABLE(INSPECTOR)
- if (m_domAgent)
- m_domAgent->didInsertDOMNode(node);
+ if (InspectorController* inspectorController = inspectorControllerForNode(node))
+ inspectorController->didInsertDOMNodeImpl(node);
+#endif
+}
+
+inline void InspectorController::willRemoveDOMNode(Node* node)
+{
+#if ENABLE(INSPECTOR)
+ if (InspectorController* inspectorController = inspectorControllerForNode(node)) {
+ inspectorController->willRemoveDOMNodeImpl(node);
+ inspectorController->didRemoveDOMNodeImpl(node);
+ }
#endif
}
-inline void InspectorController::didRemoveDOMNode(Node* node)
+inline void InspectorController::willModifyDOMAttr(Element* element)
{
#if ENABLE(INSPECTOR)
- if (m_domAgent)
- m_domAgent->didRemoveDOMNode(node);
+ if (InspectorController* inspectorController = inspectorControllerForNode(element))
+ inspectorController->willModifyDOMAttrImpl(element);
#endif
}
inline void InspectorController::didModifyDOMAttr(Element* element)
{
#if ENABLE(INSPECTOR)
- if (m_domAgent)
- m_domAgent->didModifyDOMAttr(element);
+ if (InspectorController* inspectorController = inspectorControllerForNode(element))
+ inspectorController->didModifyDOMAttrImpl(element);
#endif
}
+inline InspectorController* InspectorController::inspectorControllerForNode(Node* node)
+{
+#if ENABLE(INSPECTOR)
+ if (Page* page = node->document()->page()) {
+ if (InspectorController* inspectorController = page->inspectorController()) {
+ if (inspectorController->hasFrontend())
+ return inspectorController;
+ }
+ }
+#endif
+
+ return 0;
+}
+
} // namespace WebCore
#endif // !defined(InspectorController_h)
diff --git a/WebCore/inspector/InspectorDOMAgent.cpp b/WebCore/inspector/InspectorDOMAgent.cpp
index d2760e4..23c22aa 100644
--- a/WebCore/inspector/InspectorDOMAgent.cpp
+++ b/WebCore/inspector/InspectorDOMAgent.cpp
@@ -64,7 +64,6 @@
#include "PlatformString.h"
#include "RenderStyle.h"
#include "RenderStyleConstants.h"
-#include "ScriptDebugServer.h"
#include "ScriptEventListener.h"
#include "StyleSheetList.h"
#include "Text.h"
@@ -210,8 +209,6 @@ const int domBreakpointDerivedTypeShift = 16;
}
-InspectorDOMAgent* InspectorDOMAgent::s_domAgentOnBreakpoint = 0;
-
InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFrontend* frontend)
: EventListener(InspectorDOMAgentType)
, m_cssStore(cssStore)
@@ -224,9 +221,6 @@ InspectorDOMAgent::InspectorDOMAgent(InspectorCSSStore* cssStore, InspectorFront
InspectorDOMAgent::~InspectorDOMAgent()
{
reset();
-
- if (this == s_domAgentOnBreakpoint)
- s_domAgentOnBreakpoint = 0;
}
void InspectorDOMAgent::reset()
@@ -780,6 +774,42 @@ void InspectorDOMAgent::removeDOMBreakpoint(long nodeId, long type)
}
}
+bool InspectorDOMAgent::shouldBreakOnNodeInsertion(Node*, Node* parent, PassRefPtr<InspectorValue>* details)
+{
+ if (!hasBreakpoint(parent, SubtreeModified))
+ return false;
+ RefPtr<InspectorObject> detailsObject = InspectorObject::create();
+ detailsObject->setObject("breakpoint", createBreakpoint(parent, SubtreeModified));
+ *details = detailsObject;
+ return true;
+}
+
+bool InspectorDOMAgent::shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details)
+{
+ bool hasNodeRemovedBreakpoint = hasBreakpoint(node, NodeRemoved);
+ bool hasAnyBreakpoint = hasNodeRemovedBreakpoint || hasBreakpoint(innerParentNode(node), SubtreeModified);
+ if (!hasAnyBreakpoint)
+ return false;
+
+ RefPtr<InspectorObject> detailsObject = InspectorObject::create();
+ if (hasNodeRemovedBreakpoint)
+ detailsObject->setObject("breakpoint", createBreakpoint(node, NodeRemoved));
+ else
+ detailsObject->setObject("breakpoint", createBreakpoint(innerParentNode(node), SubtreeModified));
+ *details = detailsObject;
+ return true;
+}
+
+bool InspectorDOMAgent::shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details)
+{
+ if (!hasBreakpoint(element, AttributeModified))
+ return false;
+ RefPtr<InspectorObject> detailsObject = InspectorObject::create();
+ detailsObject->setObject("breakpoint", createBreakpoint(element, AttributeModified));
+ *details = detailsObject;
+ return true;
+}
+
String InspectorDOMAgent::documentURLString(Document* document) const
{
if (!document || document->url().isNull())
@@ -985,12 +1015,7 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node)
return;
if (m_breakpoints.size()) {
- Node* parent = innerParentNode(node);
- if (hasBreakpoint(parent, SubtreeModified)) {
- if (!pauseOnBreakpoint())
- return;
- }
- uint32_t mask = m_breakpoints.get(parent);
+ uint32_t mask = m_breakpoints.get(innerParentNode(node));
uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask;
if (inheritableTypesMask)
updateSubtreeBreakpoints(node, inheritableTypesMask, true);
@@ -1023,10 +1048,6 @@ void InspectorDOMAgent::didRemoveDOMNode(Node* node)
return;
if (m_breakpoints.size()) {
- if (hasBreakpoint(node, NodeRemoved) || hasBreakpoint(innerParentNode(node), SubtreeModified)) {
- if (!pauseOnBreakpoint())
- return;
- }
// Remove subtree breakpoints.
m_breakpoints.remove(node);
Vector<Node*> stack(1, innerFirstChild(node));
@@ -1063,12 +1084,24 @@ void InspectorDOMAgent::didModifyDOMAttr(Element* element)
if (!id)
return;
- if (hasBreakpoint(element, AttributeModified)) {
- if (!pauseOnBreakpoint())
- return;
+ m_frontend->attributesUpdated(id, buildArrayForElementAttributes(element));
+}
+
+PassRefPtr<InspectorObject> InspectorDOMAgent::createBreakpoint(Node* node, long type)
+{
+ RefPtr<InspectorObject> breakpoint = InspectorObject::create();
+
+ // Find breakpoint owner.
+ while (!(m_breakpoints.get(node) & (1 << type))) {
+ node = innerParentNode(node);
+ ASSERT(node);
}
+ long nodeId = m_documentNodeToIdMap.get(node);
+ ASSERT(nodeId);
- m_frontend->attributesUpdated(id, buildArrayForElementAttributes(element));
+ breakpoint->setNumber("nodeId", nodeId);
+ breakpoint->setNumber("type", type);
+ return breakpoint.release();
}
bool InspectorDOMAgent::hasBreakpoint(Node* node, long type)
@@ -1078,19 +1111,6 @@ bool InspectorDOMAgent::hasBreakpoint(Node* node, long type)
return m_breakpoints.get(node) & (rootBit | derivedBit);
}
-bool InspectorDOMAgent::pauseOnBreakpoint()
-{
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- s_domAgentOnBreakpoint = this;
- ScriptDebugServer::shared().breakProgram();
- bool deleted = !s_domAgentOnBreakpoint;
- s_domAgentOnBreakpoint = 0;
- return !deleted;
-#else
- return true;
-#endif
-}
-
void InspectorDOMAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set)
{
uint32_t oldMask = m_breakpoints.get(node);
diff --git a/WebCore/inspector/InspectorDOMAgent.h b/WebCore/inspector/InspectorDOMAgent.h
index fd3c5b5..9751e8e 100644
--- a/WebCore/inspector/InspectorDOMAgent.h
+++ b/WebCore/inspector/InspectorDOMAgent.h
@@ -36,7 +36,6 @@
#include "InspectorCSSStore.h"
#include "InspectorValues.h"
#include "NodeList.h"
-#include "ScriptState.h"
#include "Timer.h"
#include <wtf/Deque.h>
@@ -114,6 +113,9 @@ namespace WebCore {
void searchCanceled();
void setDOMBreakpoint(long nodeId, long type);
void removeDOMBreakpoint(long nodeId, long type);
+ bool shouldBreakOnNodeInsertion(Node* node, Node* parent, PassRefPtr<InspectorValue>* details);
+ bool shouldBreakOnNodeRemoval(Node* node, PassRefPtr<InspectorValue>* details);
+ bool shouldBreakOnAttributeModification(Element* element, PassRefPtr<InspectorValue>* details);
// Methods called from the frontend for CSS styles inspection.
void getStyles(long nodeId, bool authorOnly, RefPtr<InspectorValue>* styles);
@@ -160,7 +162,7 @@ namespace WebCore {
bool pushDocumentToFrontend();
bool hasBreakpoint(Node* node, long type);
- bool pauseOnBreakpoint();
+ PassRefPtr<InspectorObject> createBreakpoint(Node* node, long type);
void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
PassRefPtr<InspectorObject> buildObjectForAttributeStyles(Element* element);
@@ -217,8 +219,6 @@ namespace WebCore {
HashSet<RefPtr<Node> > m_searchResults;
Vector<long> m_inspectedNodes;
HashMap<Node*, uint32_t> m_breakpoints;
-
- static InspectorDOMAgent* s_domAgentOnBreakpoint;
};
#endif
diff --git a/WebCore/inspector/InspectorDebuggerAgent.cpp b/WebCore/inspector/InspectorDebuggerAgent.cpp
index 357a043..fd9fdf3 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.cpp
+++ b/WebCore/inspector/InspectorDebuggerAgent.cpp
@@ -56,11 +56,14 @@ PassOwnPtr<InspectorDebuggerAgent> InspectorDebuggerAgent::create(InspectorContr
return agent.release();
}
+InspectorDebuggerAgent* InspectorDebuggerAgent::s_debuggerAgentOnBreakpoint = 0;
+
InspectorDebuggerAgent::InspectorDebuggerAgent(InspectorController* inspectorController, InspectorFrontend* frontend)
: m_inspectorController(inspectorController)
, m_frontend(frontend)
, m_pausedScriptState(0)
, m_breakpointsLoaded(false)
+ , m_breakProgramReason(InspectorValue::null())
{
}
@@ -68,6 +71,9 @@ InspectorDebuggerAgent::~InspectorDebuggerAgent()
{
ScriptDebugServer::shared().removeListener(this, m_inspectorController->inspectedPage());
m_pausedScriptState = 0;
+
+ if (this == s_debuggerAgentOnBreakpoint)
+ s_debuggerAgentOnBreakpoint = 0;
}
bool InspectorDebuggerAgent::isDebuggerAlwaysEnabled()
@@ -282,9 +288,12 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
void InspectorDebuggerAgent::didPause(ScriptState* scriptState)
{
ASSERT(scriptState && !m_pausedScriptState);
+ ASSERT(m_breakProgramReason);
m_pausedScriptState = scriptState;
- RefPtr<InspectorValue> callFrames = currentCallFrames();
- m_frontend->pausedScript(callFrames.get());
+ RefPtr<InspectorObject> details = InspectorObject::create();
+ details->setValue("callFrames", currentCallFrames());
+ details->setValue("reason", m_breakProgramReason);
+ m_frontend->pausedScript(details);
}
void InspectorDebuggerAgent::didContinue()
@@ -293,6 +302,19 @@ void InspectorDebuggerAgent::didContinue()
m_frontend->resumedScript();
}
+void InspectorDebuggerAgent::breakProgram(PassRefPtr<InspectorValue> reason)
+{
+ s_debuggerAgentOnBreakpoint = this;
+ m_breakProgramReason = reason;
+
+ ScriptDebugServer::shared().breakProgram();
+ if (!s_debuggerAgentOnBreakpoint)
+ return;
+
+ s_debuggerAgentOnBreakpoint = 0;
+ m_breakProgramReason = InspectorValue::null();
+}
+
} // namespace WebCore
#endif // ENABLE(JAVASCRIPT_DEBUGGER)
diff --git a/WebCore/inspector/InspectorDebuggerAgent.h b/WebCore/inspector/InspectorDebuggerAgent.h
index 91bcd49..79b0a0e 100644
--- a/WebCore/inspector/InspectorDebuggerAgent.h
+++ b/WebCore/inspector/InspectorDebuggerAgent.h
@@ -61,6 +61,7 @@ public:
void getScriptSource(const String& sourceID, String* scriptSource);
void pause();
+ void breakProgram(PassRefPtr<InspectorValue> reason);
void resume();
void stepOverStatement();
void stepIntoStatement();
@@ -93,6 +94,8 @@ private:
HashMap<String, SourceBreakpoints> m_stickyBreakpoints;
HashMap<String, unsigned> m_breakpointsMapping;
bool m_breakpointsLoaded;
+ static InspectorDebuggerAgent* s_debuggerAgentOnBreakpoint;
+ RefPtr<InspectorValue> m_breakProgramReason;
};
} // namespace WebCore
diff --git a/WebCore/inspector/InspectorFrontendClient.h b/WebCore/inspector/InspectorFrontendClient.h
index cbbbc53..31f52b7 100644
--- a/WebCore/inspector/InspectorFrontendClient.h
+++ b/WebCore/inspector/InspectorFrontendClient.h
@@ -53,6 +53,7 @@ public:
virtual void bringToFront() = 0;
virtual void closeWindow() = 0;
+ virtual void disconnectFromBackend() = 0;
virtual void requestAttachWindow() = 0;
virtual void requestDetachWindow() = 0;
diff --git a/WebCore/inspector/InspectorFrontendHost.cpp b/WebCore/inspector/InspectorFrontendHost.cpp
index 8dc00ae..bc529ea 100644
--- a/WebCore/inspector/InspectorFrontendHost.cpp
+++ b/WebCore/inspector/InspectorFrontendHost.cpp
@@ -166,6 +166,14 @@ void InspectorFrontendHost::closeWindow()
}
}
+void InspectorFrontendHost::disconnectFromBackend()
+{
+ if (m_client) {
+ m_client->disconnectFromBackend();
+ disconnectClient(); // Disconnect from client.
+ }
+}
+
void InspectorFrontendHost::bringToFront()
{
if (m_client)
diff --git a/WebCore/inspector/InspectorFrontendHost.h b/WebCore/inspector/InspectorFrontendHost.h
index 4b343fd..d333893 100644
--- a/WebCore/inspector/InspectorFrontendHost.h
+++ b/WebCore/inspector/InspectorFrontendHost.h
@@ -62,6 +62,7 @@ public:
void requestAttachWindow();
void requestDetachWindow();
void closeWindow();
+ void disconnectFromBackend();
void bringToFront();
void inspectedURLChanged(const String&);
diff --git a/WebCore/inspector/InspectorFrontendHost.idl b/WebCore/inspector/InspectorFrontendHost.idl
index 0c7cf8b..6853c7d 100644
--- a/WebCore/inspector/InspectorFrontendHost.idl
+++ b/WebCore/inspector/InspectorFrontendHost.idl
@@ -34,6 +34,7 @@ module core {
interface [Conditional=INSPECTOR] InspectorFrontendHost {
void loaded();
void closeWindow();
+ void disconnectFromBackend();
void bringToFront();
void inspectedURLChanged(in DOMString newURL);
diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp
index 131ce95..be77827 100644
--- a/WebCore/inspector/InspectorResource.cpp
+++ b/WebCore/inspector/InspectorResource.cpp
@@ -35,7 +35,7 @@
#include "Cache.h"
#include "CachedResource.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "DocumentLoader.h"
#include "Frame.h"
#include "InspectorFrontend.h"
@@ -264,11 +264,11 @@ void InspectorResource::releaseScriptObject(InspectorFrontend* frontend)
CachedResource* InspectorResource::cachedResource() const
{
- // Try hard to find a corresponding CachedResource. During preloading, DocLoader may not have the resource in document resources set yet,
+ // Try hard to find a corresponding CachedResource. During preloading, CachedResourceLoader may not have the resource in document resources set yet,
// but Inspector will already try to fetch data that is only available via CachedResource (and it won't update once the resource is added,
// because m_changes will not have the appropriate bits set).
const String& url = m_requestURL.string();
- CachedResource* cachedResource = m_frame->document()->docLoader()->cachedResource(url);
+ CachedResource* cachedResource = m_frame->document()->cachedResourceLoader()->cachedResource(url);
if (!cachedResource)
cachedResource = cache()->resourceForURL(url);
return cachedResource;
diff --git a/WebCore/inspector/InspectorValues.h b/WebCore/inspector/InspectorValues.h
index 3dd9594..4036f55 100644
--- a/WebCore/inspector/InspectorValues.h
+++ b/WebCore/inspector/InspectorValues.h
@@ -67,6 +67,8 @@ public:
Type type() const { return m_type; }
+ bool isNull() const { return m_type == TypeNull; }
+
virtual bool asBoolean(bool* output) const;
virtual bool asNumber(double* output) const;
virtual bool asNumber(long* output) const;
diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 3a0860f..cda72fb 100644
--- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -106,7 +106,7 @@ WebInspector.BreakpointItem = function(breakpoint)
this._element.appendChild(checkboxElement);
this._breakpoint.addEventListener("enable-changed", this._enableChanged, this);
- this._breakpoint.addEventListener("removed", this._removed, this);
+ this._breakpoint.addEventListener("removed", this.dispatchEventToListeners.bind(this, "removed"));
}
WebInspector.BreakpointItem.prototype = {
@@ -128,15 +128,10 @@ WebInspector.BreakpointItem.prototype = {
event.stopPropagation();
},
- _enableChanged: function()
+ _enableChanged: function(event)
{
var checkbox = this._element.firstChild;
checkbox.checked = this._breakpoint.enabled;
- },
-
- _removed: function()
- {
- this.dispatchEventToListeners("removed");
}
}
@@ -188,7 +183,8 @@ WebInspector.DOMBreakpointItem = function(breakpoint)
{
WebInspector.BreakpointItem.call(this, breakpoint);
- var link = WebInspector.panels.elements.linkifyNodeReference(this._breakpoint.node);
+ var node = WebInspector.domAgent.nodeForId(this._breakpoint.nodeId);
+ var link = WebInspector.panels.elements.linkifyNodeReference(node);
this._element.appendChild(link);
var type = WebInspector.DOMBreakpoint.labelForType(this._breakpoint.type);
diff --git a/WebCore/inspector/front-end/DOMAgent.js b/WebCore/inspector/front-end/DOMAgent.js
index 5aaa0d3..9b386c3 100644
--- a/WebCore/inspector/front-end/DOMAgent.js
+++ b/WebCore/inspector/front-end/DOMAgent.js
@@ -143,6 +143,40 @@ WebInspector.DOMNode.prototype = {
this.ownerDocument._domAgent.removeAttributeAsync(this, name, callback);
},
+ path: function()
+ {
+ var path = [];
+ var node = this;
+ while (node && "index" in node && node.nodeName.length) {
+ path.push([node.index, node.nodeName]);
+ node = node.parentNode;
+ }
+ path.reverse();
+ return path.join(",");
+ },
+
+ setBreakpoint: function(type)
+ {
+ return WebInspector.domBreakpointManager.setBreakpoint(this.id, type, true, this.path());
+ },
+
+ hasBreakpoint: function(type)
+ {
+ return !!WebInspector.domBreakpointManager.findBreakpoint(this.id, type);
+ },
+
+ removeBreakpoint: function(type)
+ {
+ var breakpoint = WebInspector.domBreakpointManager.findBreakpoint(this.id, type);
+ if (breakpoint)
+ breakpoint.remove();
+ },
+
+ removeBreakpoints: function()
+ {
+ WebInspector.domBreakpointManager.removeBreakpointsForNode(this.id);
+ },
+
_setAttributesPayload: function(attrs)
{
this.attributes = [];
@@ -362,6 +396,7 @@ WebInspector.DOMAgent.prototype = {
this.document = new WebInspector.DOMDocument(this, this._window, payload);
this._idToDOMNode[payload.id] = this.document;
this._bindNodes(this.document.children);
+ WebInspector.domBreakpointManager.restoreBreakpoints();
} else
this.document = null;
WebInspector.panels.elements.setDocument(this.document);
@@ -418,7 +453,17 @@ WebInspector.DOMAgent.prototype = {
var event = { target : node, relatedNode : parent };
this.document._fireDomEvent("DOMNodeRemoved", event);
delete this._idToDOMNode[nodeId];
- }
+ this._removeBreakpoints(node);
+ },
+
+ _removeBreakpoints: function(node)
+ {
+ node.removeBreakpoints();
+ if (!node.children)
+ return;
+ for (var i = 0; i < node.children.length; ++i)
+ this._removeBreakpoints(node.children[i]);
+ }
}
WebInspector.ApplicationCache = {}
@@ -679,20 +724,24 @@ WebInspector.childNodeRemoved = function()
WebInspector.DOMBreakpointManager = function()
{
this._breakpoints = {};
+ this._pathCache = {};
}
WebInspector.DOMBreakpointManager.prototype = {
- setBreakpoint: function(node, type)
+ setBreakpoint: function(nodeId, type, enabled, path)
{
- if (!(node.id in this._breakpoints))
- this._breakpoints[node.id] = {};
- else if (type in this._breakpoints[node.id])
+ if (!(nodeId in this._breakpoints))
+ this._breakpoints[nodeId] = {};
+ else if (type in this._breakpoints[nodeId])
return;
- var breakpoint = new WebInspector.DOMBreakpoint(node, type);
- this._breakpoints[node.id][type] = breakpoint;
+ var breakpoint = new WebInspector.DOMBreakpoint(nodeId, type, enabled);
+ this._breakpoints[nodeId][type] = breakpoint;
breakpoint.addEventListener("removed", this._breakpointRemoved, this);
+ if (!(nodeId in this._pathCache))
+ this._pathCache[nodeId] = path;
+
this.dispatchEventToListeners("dom-breakpoint-added", breakpoint);
},
@@ -703,9 +752,9 @@ WebInspector.DOMBreakpointManager.prototype = {
return nodeBreakpoints[type];
},
- removeBreakpointsForNode: function(node)
+ removeBreakpointsForNode: function(nodeId)
{
- var nodeBreakpoints = this._breakpoints[node.id];
+ var nodeBreakpoints = this._breakpoints[nodeId];
for (var type in nodeBreakpoints)
nodeBreakpoints[type].remove();
},
@@ -714,23 +763,49 @@ WebInspector.DOMBreakpointManager.prototype = {
{
var breakpoint = event.target;
- var nodeBreakpoints = this._breakpoints[breakpoint.node.id];
+ var nodeBreakpoints = this._breakpoints[breakpoint.nodeId];
delete nodeBreakpoints[breakpoint.type];
for (var type in nodeBreakpoints)
return;
- delete this._breakpoints[breakpoint.node.id];
+
+ delete this._breakpoints[breakpoint.nodeId];
+ delete this._pathCache[breakpoint.nodeId];
+ },
+
+ restoreBreakpoints: function()
+ {
+ var breakpoints = this._breakpoints;
+ this._breakpoints = {};
+ var pathCache = this._pathCache;
+ this._pathCache = {};
+
+ for (var oldNodeId in breakpoints) {
+ var path = pathCache[oldNodeId];
+ InspectorBackend.pushNodeByPathToFrontend(path, restoreBreakpointsForNode.bind(this, breakpoints[oldNodeId], path));
+ }
+
+ function restoreBreakpointsForNode(nodeBreakpoints, path, nodeId)
+ {
+ if (!nodeId)
+ return;
+ for (var type in nodeBreakpoints) {
+ var breakpoint = nodeBreakpoints[type];
+ this.setBreakpoint(nodeId, breakpoint.type, breakpoint.enabled, path);
+ }
+ }
}
}
WebInspector.DOMBreakpointManager.prototype.__proto__ = WebInspector.Object.prototype;
-WebInspector.DOMBreakpoint = function(node, type)
+WebInspector.DOMBreakpoint = function(nodeId, type, enabled)
{
- this.node = node;
- this.type = type;
- this._enabled = true;
+ this._nodeId = nodeId;
+ this._type = type;
+ this._enabled = enabled;
- InspectorBackend.setDOMBreakpoint(this.node.id, this.type);
+ if (this.enabled)
+ InspectorBackend.setDOMBreakpoint(this.nodeId, this.type);
}
WebInspector.DOMBreakpoint.Types = {
@@ -762,6 +837,16 @@ WebInspector.DOMBreakpoint.contextMenuLabelForType = function(type)
}
WebInspector.DOMBreakpoint.prototype = {
+ get nodeId()
+ {
+ return this._nodeId;
+ },
+
+ get type()
+ {
+ return this._type;
+ },
+
get enabled()
{
return this._enabled;
@@ -773,18 +858,18 @@ WebInspector.DOMBreakpoint.prototype = {
return;
this._enabled = enabled;
- if (this._enabled)
- InspectorBackend.setDOMBreakpoint(this.node.id, this.type);
+ if (this.enabled)
+ InspectorBackend.setDOMBreakpoint(this.nodeId, this.type);
else
- InspectorBackend.removeDOMBreakpoint(this.node.id, this.type);
+ InspectorBackend.removeDOMBreakpoint(this.nodeId, this.type);
this.dispatchEventToListeners("enable-changed");
},
remove: function()
{
- if (this._enabled)
- InspectorBackend.removeDOMBreakpoint(this.node.id, this.type);
+ if (this.enabled)
+ InspectorBackend.removeDOMBreakpoint(this.nodeId, this.type);
this.dispatchEventToListeners("removed");
}
}
diff --git a/WebCore/inspector/front-end/ElementsPanel.js b/WebCore/inspector/front-end/ElementsPanel.js
index e1bc637..c60d4b1 100644
--- a/WebCore/inspector/front-end/ElementsPanel.js
+++ b/WebCore/inspector/front-end/ElementsPanel.js
@@ -159,16 +159,8 @@ WebInspector.ElementsPanel.prototype = {
reset: function()
{
- if (this.focusedDOMNode) {
- this._selectedPathOnReset = [];
- var node = this.focusedDOMNode;
- while ("index" in node && node.nodeName && node.nodeName.length) {
- this._selectedPathOnReset.push(node.nodeName);
- this._selectedPathOnReset.push(node.index);
- node = node.parentNode;
- }
- this._selectedPathOnReset.reverse();
- }
+ if (this.focusedDOMNode)
+ this._selectedPathOnReset = this.focusedDOMNode.path();
this.rootDOMNode = null;
this.focusedDOMNode = null;
@@ -225,7 +217,7 @@ WebInspector.ElementsPanel.prototype = {
}
if (this._selectedPathOnReset)
- InspectorBackend.pushNodeByPathToFrontend(this._selectedPathOnReset.join(","), selectLastSelectedNode.bind(this));
+ InspectorBackend.pushNodeByPathToFrontend(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
else
selectNode.call(this);
delete this._selectedPathOnReset;
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index ba3b320..10131f4 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -765,15 +765,17 @@ WebInspector.ElementsTreeElement.prototype = {
if (Preferences.domBreakpointsEnabled) {
// Add debbuging-related actions
contextMenu.appendSeparator();
- for (var type in WebInspector.DOMBreakpoint.Types) {
- var typeId = WebInspector.DOMBreakpoint.Types[type];
- var label = WebInspector.DOMBreakpoint.contextMenuLabelForType(typeId);
- var breakpoint = WebInspector.domBreakpointManager.findBreakpoint(this.representedObject.id, typeId);
- if (!breakpoint)
- var handler = WebInspector.domBreakpointManager.setBreakpoint.bind(WebInspector.domBreakpointManager, this.representedObject, typeId);
+
+ var node = this.representedObject;
+ for (var key in WebInspector.DOMBreakpoint.Types) {
+ var type = WebInspector.DOMBreakpoint.Types[key];
+ var label = WebInspector.DOMBreakpoint.contextMenuLabelForType(type);
+ var hasBreakpoint = node.hasBreakpoint(type);
+ if (!hasBreakpoint)
+ var handler = node.setBreakpoint.bind(node, type);
else
- var handler = breakpoint.remove.bind(breakpoint);
- contextMenu.appendCheckboxItem(label, handler, !!breakpoint);
+ var handler = node.removeBreakpoint.bind(node, type);
+ contextMenu.appendCheckboxItem(label, handler, hasBreakpoint);
}
}
},
diff --git a/WebCore/inspector/front-end/ExtensionServer.js b/WebCore/inspector/front-end/ExtensionServer.js
index f410d8c..bdf3a25 100644
--- a/WebCore/inspector/front-end/ExtensionServer.js
+++ b/WebCore/inspector/front-end/ExtensionServer.js
@@ -103,7 +103,7 @@ WebInspector.ExtensionServer.prototype = {
{
return {
id: resource.identifier,
- type: resource.type,
+ type: WebInspector.Resource.Type.toString(resource.type),
har: (new WebInspector.HAREntry(resource)).build(),
};
},
@@ -321,10 +321,20 @@ WebInspector.ExtensionServer.prototype = {
_buildExtensionAPIInjectedScript: function()
{
+ var resourceTypes = {};
+ var resourceTypeProperties = Object.getOwnPropertyNames(WebInspector.Resource.Type);
+ for (var i = 0; i < resourceTypeProperties.length; ++i) {
+ var propName = resourceTypeProperties[i];
+ var propValue = WebInspector.Resource.Type[propName];
+ if (typeof propValue === "number")
+ resourceTypes[propName] = WebInspector.Resource.Type.toString(propValue);
+ }
+
return "(function(){ " +
"var private = {};" +
"(" + WebInspector.commonExtensionSymbols.toString() + ")(private);" +
"(" + WebInspector.injectedExtensionAPI.toString() + ").apply(this, arguments);" +
+ "webInspector.resources.Types = " + JSON.stringify(resourceTypes) + ";" +
"})";
},
diff --git a/WebCore/inspector/front-end/HAREntry.js b/WebCore/inspector/front-end/HAREntry.js
index c06e64f..9f188ed 100644
--- a/WebCore/inspector/front-end/HAREntry.js
+++ b/WebCore/inspector/front-end/HAREntry.js
@@ -116,11 +116,13 @@ WebInspector.HAREntry.prototype = {
_buildPostData: function()
{
- return {
+ var res = {
mimeType: this._resource.requestHeaderValue("Content-Type"),
- params: this._buildParameters(this._resource.formParameters),
text: this._resource.requestFormData
};
+ if (this._resource.formParameters)
+ res.params = this._buildParameters(this._resource.formParameters);
+ return res;
},
_buildParameters: function(parameters)
diff --git a/WebCore/inspector/front-end/InspectorFrontendHostStub.js b/WebCore/inspector/front-end/InspectorFrontendHostStub.js
index c4e6bf4..07f392d 100644
--- a/WebCore/inspector/front-end/InspectorFrontendHostStub.js
+++ b/WebCore/inspector/front-end/InspectorFrontendHostStub.js
@@ -64,6 +64,11 @@ WebInspector.InspectorFrontendHostStub.prototype = {
this._windowVisible = false;
},
+ disconnectFromBackend: function()
+ {
+ this._windowVisible = false;
+ },
+
attach: function()
{
},
diff --git a/WebCore/inspector/front-end/Resource.js b/WebCore/inspector/front-end/Resource.js
index 06a610d..de87047 100644
--- a/WebCore/inspector/front-end/Resource.js
+++ b/WebCore/inspector/front-end/Resource.js
@@ -52,24 +52,33 @@ WebInspector.Resource.Type = {
return (type === this.Document) || (type === this.Stylesheet) || (type === this.Script) || (type === this.XHR);
},
+ toUIString: function(type)
+ {
+ return WebInspector.UIString(WebInspector.Resource.Type.toString(type));
+ },
+
+ // Returns locale-independent string identifier of resource type (primarily for use in extension API).
+ // The IDs need to be kept in sync with webInspector.resoureces.Types object in ExtensionAPI.js.
toString: function(type)
{
switch (type) {
case this.Document:
- return WebInspector.UIString("document");
+ return "document";
case this.Stylesheet:
- return WebInspector.UIString("stylesheet");
+ return "stylesheet";
case this.Image:
- return WebInspector.UIString("image");
+ return "image";
case this.Font:
- return WebInspector.UIString("font");
+ return "font";
case this.Script:
- return WebInspector.UIString("script");
+ return "script";
case this.XHR:
- return WebInspector.UIString("XHR");
+ return "XHR";
+ case this.Media:
+ return "media";
case this.Other:
default:
- return WebInspector.UIString("other");
+ return "other";
}
}
}
@@ -603,7 +612,7 @@ WebInspector.Resource.prototype = {
this.url,
null,
1,
- String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message, WebInspector.Resource.Type.toString(this.type), this.mimeType),
+ String.sprintf(WebInspector.Warnings.IncorrectMIMEType.message, WebInspector.Resource.Type.toUIString(this.type), this.mimeType),
null,
null);
break;
diff --git a/WebCore/inspector/front-end/Script.js b/WebCore/inspector/front-end/Script.js
index 42d6850..be3f020 100644
--- a/WebCore/inspector/front-end/Script.js
+++ b/WebCore/inspector/front-end/Script.js
@@ -62,11 +62,14 @@ WebInspector.Script.prototype = {
{
if (!this.source)
return 0;
+ if (this._linesCount)
+ return this._linesCount;
this._linesCount = 0;
var lastIndex = this.source.indexOf("\n");
while (lastIndex !== -1) {
lastIndex = this.source.indexOf("\n", lastIndex + 1)
this._linesCount++;
}
+ return this._linesCount;
}
}
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 75fd6f7..c5267f7 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -276,14 +276,6 @@ WebInspector.ScriptsPanel.prototype = {
// Remove script from the files list.
script.filesSelectOption.parentElement.removeChild(script.filesSelectOption);
-
- // Move breakpoints to the resource's frame.
- if (script._scriptView) {
- var sourceFrame = script._scriptView.sourceFrame;
- var resourceFrame = this._sourceFrameForScriptOrResource(resource);
- for (var j = 0; j < sourceFrame.breakpoints; ++j)
- resourceFrame.addBreakpoint(sourceFrame.breakpoints[j]);
- }
}
// Adding first script will add resource.
this._addScriptToFilesMenu(resource._scriptsPendingResourceLoad[0]);
@@ -599,10 +591,6 @@ WebInspector.ScriptsPanel.prototype = {
return null;
view = WebInspector.panels.resources.resourceViewForResource(scriptOrResource);
view.headersVisible = false;
- var sourceFrame = this._sourceFrameForScriptOrResource(scriptOrResource);
- var breakpoints = WebInspector.breakpointManager.breakpointsForURL(scriptOrResource.url);
- for (var i = 0; i < breakpoints.length; ++i)
- sourceFrame.addBreakpoint(breakpoints[i]);
} else if (scriptOrResource instanceof WebInspector.Script)
view = this.scriptViewForScript(scriptOrResource);
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 16b8e8d..a9033f2 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -598,9 +598,11 @@ WebInspector.SourceFrame.prototype = {
var popupContentElement = null;
if (result.type !== "object" && result.type !== "node" && result.type !== "array") {
popupContentElement = document.createElement("span");
- popupContentElement.className = "monospace";
+ popupContentElement.className = "monospace console-formatted-" + result.type;
popupContentElement.style.whiteSpace = "pre";
popupContentElement.textContent = result.description;
+ if (result.type === "string")
+ popupContentElement.textContent = "\"" + popupContentElement.textContent + "\"";
this._popup = new WebInspector.Popover(popupContentElement);
this._popup.show(element);
} else {
diff --git a/WebCore/inspector/front-end/SourceView.js b/WebCore/inspector/front-end/SourceView.js
index 240dca1..3f762cc 100644
--- a/WebCore/inspector/front-end/SourceView.js
+++ b/WebCore/inspector/front-end/SourceView.js
@@ -99,6 +99,9 @@ WebInspector.SourceView.prototype = {
var mimeType = this._canonicalMimeType(this.resource);
this.sourceFrame.setContent(mimeType, content, this.resource.url);
this._sourceFrameSetupFinished();
+ var breakpoints = WebInspector.breakpointManager.breakpointsForURL(this.resource.url);
+ for (var i = 0; i < breakpoints.length; ++i)
+ this.sourceFrame.addBreakpoint(breakpoints[i]);
},
_canonicalMimeType: function(resource)
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index b640936..f90a9fe 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -106,6 +106,7 @@
<file>WelcomeView.js</file>
<file>WorkersSidebarPane.js</file>
<file>audits.css</file>
+ <file>heapProfiler.css</file>
<file>helpScreen.css</file>
<file>inspector.css</file>
<file>inspectorSyntaxHighlight.css</file>
diff --git a/WebCore/inspector/front-end/heapProfiler.css b/WebCore/inspector/front-end/heapProfiler.css
new file mode 100644
index 0000000..03a6dd0
--- /dev/null
+++ b/WebCore/inspector/front-end/heapProfiler.css
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.heap-snapshot-sidebar-tree-item .icon {
+ content: url(Images/profileIcon.png);
+}
+
+.heap-snapshot-sidebar-tree-item.small .icon {
+ content: url(Images/profileSmallIcon.png);
+}
+
+.heap-snapshot-view {
+ display: none;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.heap-snapshot-view.visible {
+ display: block;
+}
+
+.heap-snapshot-view .data-grid {
+ border: none;
+ max-height: 100%;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 93px;
+}
+
+.heap-snapshot-view .data-grid th.count-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.count-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.size-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.size-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.countDelta-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.countDelta-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.sizeDelta-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.sizeDelta-column {
+ text-align: right;
+}
+
+#heap-snapshot-summary-container {
+ position: absolute;
+ padding-top: 20px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 93px;
+ margin-left: -1px;
+ border-left: 1px solid rgb(102, 102, 102);
+ background-color: rgb(101, 111, 130);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
+ background-repeat: repeat-x;
+ background-position: top;
+ text-align: center;
+ text-shadow: black 0 1px 1px;
+ white-space: nowrap;
+ color: white;
+ -webkit-background-size: 1px 6px;
+ -webkit-background-origin: padding;
+ -webkit-background-clip: padding;
+}
+
+.heap-snapshot-summary {
+ display: inline-block;
+ width: 50%;
+ min-width: 300px;
+ position: relative;
+}
+
+.heap-snapshot-summary canvas.summary-graph {
+ width: 225px;
+}
+
+.heap-snapshot-summary-label {
+ font-size: 12px;
+ font-weight: bold;
+ position: absolute;
+ top: 1px;
+ width: 50%;
+ left: 25%;
+}
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index a3ffa44..4319816 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -3910,115 +3910,6 @@ button.enable-toggle-status-bar-item .glyph {
-webkit-mask-image: url(Images/reloadButtonGlyph.png);
}
-/* Heap Snapshot View Styles */
-
-/* FIXME: move to a separate css file */
-.heap-snapshot-sidebar-tree-item .icon {
- content: url(Images/profileIcon.png);
-}
-
-.heap-snapshot-sidebar-tree-item.small .icon {
- content: url(Images/profileSmallIcon.png);
-}
-
-.heap-snapshot-view {
- display: none;
- overflow: hidden;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-.heap-snapshot-view.visible {
- display: block;
-}
-
-.heap-snapshot-view .data-grid {
- border: none;
- max-height: 100%;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 93px;
-}
-
-.heap-snapshot-view .data-grid th.count-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.count-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid th.size-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.size-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid th.countDelta-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.countDelta-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid th.sizeDelta-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.sizeDelta-column {
- text-align: right;
-}
-
-#heap-snapshot-summary-container {
- position: absolute;
- padding-top: 20px;
- bottom: 0;
- left: 0;
- right: 0;
- height: 93px;
- margin-left: -1px;
- border-left: 1px solid rgb(102, 102, 102);
- background-color: rgb(101, 111, 130);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
- background-repeat: repeat-x;
- background-position: top;
- text-align: center;
- text-shadow: black 0 1px 1px;
- white-space: nowrap;
- color: white;
- -webkit-background-size: 1px 6px;
- -webkit-background-origin: padding;
- -webkit-background-clip: padding;
-}
-
-.heap-snapshot-summary {
- display: inline-block;
- width: 50%;
- min-width: 300px;
- position: relative;
-}
-
-.heap-snapshot-summary canvas.summary-graph {
- width: 225px;
-}
-
-.heap-snapshot-summary-label {
- font-size: 12px;
- font-weight: bold;
- position: absolute;
- top: 1px;
- width: 50%;
- left: 25%;
-}
-
.delete-storage-status-bar-item .glyph {
-webkit-mask-image: url(Images/excludeButtonGlyph.png);
}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 3e4b6c1..0536ee6 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -30,6 +30,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="audits.css">
+ <link rel="stylesheet" type="text/css" href="heapProfiler.css">
<link rel="stylesheet" type="text/css" href="inspector.css">
<link rel="stylesheet" type="text/css" href="inspectorSyntaxHighlight.css">
<link rel="stylesheet" type="text/css" href="popover.css">
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 0bff335..840745f 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -715,9 +715,9 @@ WebInspector.close = function(event)
InspectorFrontendHost.closeWindow();
}
-WebInspector.inspectedPageDestroyed = function()
+WebInspector.disconnectFromBackend = function()
{
- WebInspector.close();
+ InspectorFrontendHost.disconnectFromBackend();
}
WebInspector.documentMouseOver = function(event)
@@ -1445,9 +1445,9 @@ WebInspector.failedToParseScriptSource = function(sourceURL, source, startingLin
this.panels.scripts.addScript(null, sourceURL, source, startingLine, errorLine, errorMessage);
}
-WebInspector.pausedScript = function(callFrames)
+WebInspector.pausedScript = function(details)
{
- this.panels.scripts.debuggerPaused(callFrames);
+ this.panels.scripts.debuggerPaused(details.callFrames);
InspectorFrontendHost.bringToFront();
}
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index cb536e2..7acbd56 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -28,7 +28,7 @@
#include "CachedImage.h"
#include "CachedScript.h"
#include "CachedXSLStyleSheet.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "FrameLoader.h"
#include "FrameLoaderTypes.h"
@@ -93,7 +93,7 @@ static CachedResource* createResource(CachedResource::Type type, const KURL& url
return 0;
}
-CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload)
+CachedResource* Cache::requestResource(CachedResourceLoader* cachedResourceLoader, CachedResource::Type type, const KURL& url, const String& charset, bool requestIsPreload)
{
// FIXME: Do we really need to special-case an empty URL?
// Would it be better to just go on with the cache code and let it fail later?
@@ -106,8 +106,8 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
if (resource && requestIsPreload && !resource->isPreloaded())
return 0;
- if (SecurityOrigin::restrictAccessToLocal() && !SecurityOrigin::canLoad(url, String(), docLoader->doc())) {
- Document* doc = docLoader->doc();
+ if (SecurityOrigin::restrictAccessToLocal() && !SecurityOrigin::canDisplay(url, String(), cachedResourceLoader->doc())) {
+ Document* doc = cachedResourceLoader->doc();
if (doc && !requestIsPreload)
FrameLoader::reportLocalLoadFailed(doc->frame(), url.string());
return 0;
@@ -122,7 +122,7 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
// FIXME: CachedResource should just use normal refcounting instead.
resource->setInCache(true);
- resource->load(docLoader);
+ resource->load(cachedResourceLoader);
if (resource->errorOccurred()) {
// We don't support immediate loads, but we do support immediate failure.
@@ -138,7 +138,7 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
else {
// Kick the resource out of the cache, because the cache is disabled.
resource->setInCache(false);
- resource->setDocLoader(docLoader);
+ resource->setCachedResourceLoader(cachedResourceLoader);
}
}
@@ -153,7 +153,7 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
return resource;
}
-CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(DocLoader* docLoader, const String& url, const String& charset)
+CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(CachedResourceLoader* cachedResourceLoader, const String& url, const String& charset)
{
CachedCSSStyleSheet* userSheet;
if (CachedResource* existing = resourceForURL(url)) {
@@ -167,7 +167,7 @@ CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(DocLoader* docLoader, const
// FIXME: CachedResource should just use normal refcounting instead.
userSheet->setInCache(true);
// Don't load incrementally, skip load checks, don't send resource load callbacks.
- userSheet->load(docLoader, false, SkipSecurityCheck, false);
+ userSheet->load(cachedResourceLoader, false, SkipSecurityCheck, false);
if (!disabled())
m_resources.set(url, userSheet);
else
@@ -182,7 +182,7 @@ CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(DocLoader* docLoader, const
return userSheet;
}
-void Cache::revalidateResource(CachedResource* resource, DocLoader* docLoader)
+void Cache::revalidateResource(CachedResource* resource, CachedResourceLoader* cachedResourceLoader)
{
ASSERT(resource);
ASSERT(resource->inCache());
@@ -201,7 +201,7 @@ void Cache::revalidateResource(CachedResource* resource, DocLoader* docLoader)
m_resources.set(url, newResource);
newResource->setInCache(true);
resourceAccessed(newResource);
- newResource->load(docLoader);
+ newResource->load(cachedResourceLoader);
}
void Cache::revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse& response)
@@ -422,14 +422,14 @@ void Cache::evict(CachedResource* resource)
delete resource;
}
-void Cache::addDocLoader(DocLoader* docLoader)
+void Cache::addCachedResourceLoader(CachedResourceLoader* cachedResourceLoader)
{
- m_docLoaders.add(docLoader);
+ m_cachedResourceLoaders.add(cachedResourceLoader);
}
-void Cache::removeDocLoader(DocLoader* docLoader)
+void Cache::removeCachedResourceLoader(CachedResourceLoader* cachedResourceLoader)
{
- m_docLoaders.remove(docLoader);
+ m_cachedResourceLoaders.remove(cachedResourceLoader);
}
static inline unsigned fastLog2(unsigned i)
diff --git a/WebCore/loader/Cache.h b/WebCore/loader/Cache.h
index ce8cde4..9d7e8be 100644
--- a/WebCore/loader/Cache.h
+++ b/WebCore/loader/Cache.h
@@ -39,7 +39,7 @@ namespace WebCore {
class CachedCSSStyleSheet;
class CachedResource;
-class DocLoader;
+class CachedResourceLoader;
class KURL;
// This cache holds subresources used by Web pages: images, scripts, stylesheets, etc.
@@ -93,11 +93,11 @@ public:
// Request resources from the cache. A load will be initiated and a cache object created if the object is not
// found in the cache.
- CachedResource* requestResource(DocLoader*, CachedResource::Type, const KURL& url, const String& charset, bool isPreload = false);
+ CachedResource* requestResource(CachedResourceLoader*, CachedResource::Type, const KURL& url, const String& charset, bool isPreload = false);
- CachedCSSStyleSheet* requestUserCSSStyleSheet(DocLoader*, const String& url, const String& charset);
+ CachedCSSStyleSheet* requestUserCSSStyleSheet(CachedResourceLoader*, const String& url, const String& charset);
- void revalidateResource(CachedResource*, DocLoader*);
+ void revalidateResource(CachedResource*, CachedResourceLoader*);
void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
void revalidationFailed(CachedResource* revalidatingResource);
@@ -129,8 +129,8 @@ public:
// Remove an existing cache entry from both the resource map and from the LRU list.
void remove(CachedResource* resource) { evict(resource); }
- void addDocLoader(DocLoader*);
- void removeDocLoader(DocLoader*);
+ void addCachedResourceLoader(CachedResourceLoader*);
+ void removeCachedResourceLoader(CachedResourceLoader*);
CachedResource* resourceForURL(const String&);
@@ -176,7 +176,7 @@ private:
void evict(CachedResource*);
// Member variables.
- HashSet<DocLoader*> m_docLoaders;
+ HashSet<CachedResourceLoader*> m_cachedResourceLoaders;
Loader m_loader;
bool m_disabled; // Whether or not the cache is enabled.
diff --git a/WebCore/loader/CachedCSSStyleSheet.h b/WebCore/loader/CachedCSSStyleSheet.h
index f5bf042..03bde69 100644
--- a/WebCore/loader/CachedCSSStyleSheet.h
+++ b/WebCore/loader/CachedCSSStyleSheet.h
@@ -32,7 +32,7 @@
namespace WebCore {
- class DocLoader;
+ class CachedResourceLoader;
class TextResourceDecoder;
class CachedCSSStyleSheet : public CachedResource {
diff --git a/WebCore/loader/CachedFont.cpp b/WebCore/loader/CachedFont.cpp
index 272166e..166fa85 100644
--- a/WebCore/loader/CachedFont.cpp
+++ b/WebCore/loader/CachedFont.cpp
@@ -71,7 +71,7 @@ CachedFont::~CachedFont()
#endif
}
-void CachedFont::load(DocLoader*)
+void CachedFont::load(CachedResourceLoader*)
{
// Don't load the file yet. Wait for an access before triggering the load.
setLoading(true);
@@ -94,7 +94,7 @@ void CachedFont::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
checkNotify();
}
-void CachedFont::beginLoadIfNeeded(DocLoader* dl)
+void CachedFont::beginLoadIfNeeded(CachedResourceLoader* dl)
{
if (!m_loadInitiated) {
m_loadInitiated = true;
diff --git a/WebCore/loader/CachedFont.h b/WebCore/loader/CachedFont.h
index 01c8c9c..95c2423 100644
--- a/WebCore/loader/CachedFont.h
+++ b/WebCore/loader/CachedFont.h
@@ -37,7 +37,7 @@
namespace WebCore {
-class DocLoader;
+class CachedResourceLoader;
class Cache;
class FontPlatformData;
class SVGFontElement;
@@ -49,7 +49,7 @@ public:
CachedFont(const String& url);
virtual ~CachedFont();
- virtual void load(DocLoader* docLoader);
+ virtual void load(CachedResourceLoader* cachedResourceLoader);
virtual void didAddClient(CachedResourceClient*);
virtual void data(PassRefPtr<SharedBuffer> data, bool allDataReceived);
@@ -59,7 +59,7 @@ public:
void checkNotify();
- void beginLoadIfNeeded(DocLoader* dl);
+ void beginLoadIfNeeded(CachedResourceLoader* dl);
bool ensureCustomFontData();
FontPlatformData platformDataFromCustomData(float size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode);
diff --git a/WebCore/loader/CachedImage.cpp b/WebCore/loader/CachedImage.cpp
index 97b80f2..4dd8ea3 100644
--- a/WebCore/loader/CachedImage.cpp
+++ b/WebCore/loader/CachedImage.cpp
@@ -28,7 +28,7 @@
#include "Cache.h"
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Frame.h"
#include "FrameLoaderTypes.h"
#include "FrameView.h"
@@ -80,14 +80,19 @@ void CachedImage::decodedDataDeletionTimerFired(Timer<CachedImage>*)
destroyDecodedData();
}
-void CachedImage::load(DocLoader* docLoader)
+void CachedImage::load(CachedResourceLoader* cachedResourceLoader)
{
+<<<<<<< HEAD
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
if (!docLoader || (docLoader->autoLoadImages() && !docLoader->shouldBlockNetworkImage(m_url)))
#else
if (!docLoader || docLoader->autoLoadImages())
#endif
CachedResource::load(docLoader, true, DoSecurityCheck, true);
+=======
+ if (!cachedResourceLoader || cachedResourceLoader->autoLoadImages())
+ CachedResource::load(cachedResourceLoader, true, DoSecurityCheck, true);
+>>>>>>> webkit.org at r67178
else
setLoading(false);
}
@@ -261,7 +266,7 @@ inline void CachedImage::createImage()
size_t CachedImage::maximumDecodedImageSize()
{
- Frame* frame = m_request ? m_request->docLoader()->frame() : 0;
+ Frame* frame = m_request ? m_request->cachedResourceLoader()->frame() : 0;
if (!frame)
return 0;
Settings* settings = frame->settings();
diff --git a/WebCore/loader/CachedImage.h b/WebCore/loader/CachedImage.h
index eb55955..15f4238 100644
--- a/WebCore/loader/CachedImage.h
+++ b/WebCore/loader/CachedImage.h
@@ -31,7 +31,7 @@
namespace WebCore {
-class DocLoader;
+class CachedResourceLoader;
class Cache;
class CachedImage : public CachedResource, public ImageObserver {
@@ -42,7 +42,7 @@ public:
CachedImage(Image*);
virtual ~CachedImage();
- virtual void load(DocLoader* docLoader);
+ virtual void load(CachedResourceLoader* cachedResourceLoader);
Image* image() const;
diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp
index 887b0b5..a6ff0ff 100644
--- a/WebCore/loader/CachedResource.cpp
+++ b/WebCore/loader/CachedResource.cpp
@@ -29,7 +29,7 @@
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
#include "CachedResourceHandle.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
#include "KURL.h"
@@ -78,7 +78,7 @@ CachedResource::CachedResource(const String& url, Type type)
, m_prevInAllResourcesList(0)
, m_nextInLiveResourcesList(0)
, m_prevInLiveResourcesList(0)
- , m_docLoader(0)
+ , m_cachedResourceLoader(0)
, m_resourceToRevalidate(0)
, m_proxyResource(0)
{
@@ -99,14 +99,14 @@ CachedResource::~CachedResource()
cachedResourceLeakCounter.decrement();
#endif
- if (m_docLoader)
- m_docLoader->removeCachedResource(this);
+ if (m_cachedResourceLoader)
+ m_cachedResourceLoader->removeCachedResource(this);
}
-void CachedResource::load(DocLoader* docLoader, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
+void CachedResource::load(CachedResourceLoader* cachedResourceLoader, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
{
m_sendResourceLoadCallbacks = sendResourceLoadCallbacks;
- cache()->loader()->load(docLoader, this, incremental, securityCheck, sendResourceLoadCallbacks);
+ cache()->loader()->load(cachedResourceLoader, this, incremental, securityCheck, sendResourceLoadCallbacks);
m_loading = true;
}
diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h
index f6eb730..958c8fd 100644
--- a/WebCore/loader/CachedResource.h
+++ b/WebCore/loader/CachedResource.h
@@ -39,7 +39,7 @@ class Cache;
class CachedMetadata;
class CachedResourceClient;
class CachedResourceHandleBase;
-class DocLoader;
+class CachedResourceLoader;
class Frame;
class InspectorResource;
class Request;
@@ -77,8 +77,8 @@ public:
CachedResource(const String& url, Type);
virtual ~CachedResource();
- virtual void load(DocLoader* docLoader) { load(docLoader, false, DoSecurityCheck, true); }
- void load(DocLoader*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
+ virtual void load(CachedResourceLoader* cachedResourceLoader) { load(cachedResourceLoader, false, DoSecurityCheck, true); }
+ void load(CachedResourceLoader*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
virtual void setEncoding(const String&) { }
virtual String encoding() const { return String(); }
@@ -182,7 +182,7 @@ public:
virtual void destroyDecodedData() { }
- void setDocLoader(DocLoader* docLoader) { m_docLoader = docLoader; }
+ void setCachedResourceLoader(CachedResourceLoader* cachedResourceLoader) { m_cachedResourceLoader = cachedResourceLoader; }
bool isPreloaded() const { return m_preloadCount; }
void increasePreloadCount() { ++m_preloadCount; }
@@ -269,7 +269,7 @@ private:
CachedResource* m_nextInLiveResourcesList;
CachedResource* m_prevInLiveResourcesList;
- DocLoader* m_docLoader; // only non-0 for resources that are not in the cache
+ CachedResourceLoader* m_cachedResourceLoader; // only non-0 for resources that are not in the cache
// If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
// using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/CachedResourceLoader.cpp
index d04e148..68cd7ec 100644
--- a/WebCore/loader/DocLoader.cpp
+++ b/WebCore/loader/CachedResourceLoader.cpp
@@ -25,7 +25,7 @@
*/
#include "config.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "loader.h"
#include "Cache.h"
@@ -50,7 +50,7 @@
namespace WebCore {
-DocLoader::DocLoader(Document* doc)
+CachedResourceLoader::CachedResourceLoader(Document* doc)
: m_cache(cache())
, m_doc(doc)
, m_requestCount(0)
@@ -61,10 +61,10 @@ DocLoader::DocLoader(Document* doc)
, m_loadInProgress(false)
, m_allowStaleResources(false)
{
- m_cache->addDocLoader(this);
+ m_cache->addCachedResourceLoader(this);
}
-DocLoader::~DocLoader()
+CachedResourceLoader::~CachedResourceLoader()
{
if (m_requestCount)
m_cache->loader()->cancelRequests(this);
@@ -72,19 +72,19 @@ DocLoader::~DocLoader()
clearPreloads();
DocumentResourceMap::iterator end = m_documentResources.end();
for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it)
- it->second->setDocLoader(0);
- m_cache->removeDocLoader(this);
+ it->second->setCachedResourceLoader(0);
+ m_cache->removeCachedResourceLoader(this);
- // Make sure no requests still point to this DocLoader
+ // Make sure no requests still point to this CachedResourceLoader
ASSERT(m_requestCount == 0);
}
-Frame* DocLoader::frame() const
+Frame* CachedResourceLoader::frame() const
{
return m_doc->frame();
}
-void DocLoader::checkForReload(const KURL& fullURL)
+void CachedResourceLoader::checkForReload(const KURL& fullURL)
{
if (m_allowStaleResources)
return; // Don't reload resources while pasting
@@ -123,7 +123,7 @@ void DocLoader::checkForReload(const KURL& fullURL)
m_reloadedURLs.add(fullURL.string());
}
-CachedImage* DocLoader::requestImage(const String& url)
+CachedImage* CachedResourceLoader::requestImage(const String& url)
{
if (Frame* f = frame()) {
Settings* settings = f->settings();
@@ -150,42 +150,42 @@ CachedImage* DocLoader::requestImage(const String& url)
return resource;
}
-CachedFont* DocLoader::requestFont(const String& url)
+CachedFont* CachedResourceLoader::requestFont(const String& url)
{
return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, url, String()));
}
-CachedCSSStyleSheet* DocLoader::requestCSSStyleSheet(const String& url, const String& charset)
+CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& url, const String& charset)
{
return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, charset));
}
-CachedCSSStyleSheet* DocLoader::requestUserCSSStyleSheet(const String& url, const String& charset)
+CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& url, const String& charset)
{
return cache()->requestUserCSSStyleSheet(this, url, charset);
}
-CachedScript* DocLoader::requestScript(const String& url, const String& charset)
+CachedScript* CachedResourceLoader::requestScript(const String& url, const String& charset)
{
return static_cast<CachedScript*>(requestResource(CachedResource::Script, url, charset));
}
#if ENABLE(XSLT)
-CachedXSLStyleSheet* DocLoader::requestXSLStyleSheet(const String& url)
+CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(const String& url)
{
return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, url, String()));
}
#endif
#if ENABLE(LINK_PREFETCH)
-CachedResource* DocLoader::requestLinkPrefetch(const String& url)
+CachedResource* CachedResourceLoader::requestLinkPrefetch(const String& url)
{
ASSERT(frame());
return requestResource(CachedResource::LinkPrefetch, url, String());
}
#endif
-bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
+bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url)
{
// Some types of resources can be loaded only from the same origin. Other
// types of resources, like Images, Scripts, and CSS, can be loaded from
@@ -253,7 +253,7 @@ bool DocLoader::canRequest(CachedResource::Type type, const KURL& url)
return true;
}
-CachedResource* DocLoader::requestResource(CachedResource::Type type, const String& url, const String& charset, bool isPreload)
+CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& url, const String& charset, bool isPreload)
{
KURL fullURL = m_doc->completeURL(url);
@@ -264,7 +264,7 @@ CachedResource* DocLoader::requestResource(CachedResource::Type type, const Stri
DocumentResourceMap::iterator it = m_documentResources.find(fullURL.string());
if (it != m_documentResources.end()) {
- it->second->setDocLoader(0);
+ it->second->setCachedResourceLoader(0);
m_documentResources.remove(it);
}
}
@@ -284,7 +284,7 @@ CachedResource* DocLoader::requestResource(CachedResource::Type type, const Stri
return resource;
}
-void DocLoader::printAccessDeniedMessage(const KURL& url) const
+void CachedResourceLoader::printAccessDeniedMessage(const KURL& url) const
{
if (url.isNull())
return;
@@ -308,7 +308,7 @@ void DocLoader::printAccessDeniedMessage(const KURL& url) const
frame()->domWindow()->console()->addMessage(OtherMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String());
}
-void DocLoader::setAutoLoadImages(bool enable)
+void CachedResourceLoader::setAutoLoadImages(bool enable)
{
if (enable == m_autoLoadImages)
return;
@@ -334,6 +334,7 @@ void DocLoader::setAutoLoadImages(bool enable)
}
}
+<<<<<<< HEAD:WebCore/loader/DocLoader.cpp
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
bool DocLoader::shouldBlockNetworkImage(const String& url) const
{
@@ -370,11 +371,14 @@ void DocLoader::setBlockNetworkImage(bool block)
#endif
CachePolicy DocLoader::cachePolicy() const
+=======
+CachePolicy CachedResourceLoader::cachePolicy() const
+>>>>>>> webkit.org at r67178:WebCore/loader/CachedResourceLoader.cpp
{
return frame() ? frame()->loader()->subresourceCachePolicy() : CachePolicyVerify;
}
-void DocLoader::removeCachedResource(CachedResource* resource) const
+void CachedResourceLoader::removeCachedResource(CachedResource* resource) const
{
#ifndef NDEBUG
DocumentResourceMap::iterator it = m_documentResources.find(resource->url());
@@ -384,14 +388,14 @@ void DocLoader::removeCachedResource(CachedResource* resource) const
m_documentResources.remove(resource->url());
}
-void DocLoader::setLoadInProgress(bool load)
+void CachedResourceLoader::setLoadInProgress(bool load)
{
m_loadInProgress = load;
if (!load && frame())
frame()->loader()->loadDone();
}
-void DocLoader::checkCacheObjectStatus(CachedResource* resource)
+void CachedResourceLoader::checkCacheObjectStatus(CachedResource* resource)
{
// Return from the function for objects that we didn't load from the cache or if we don't have a frame.
if (!resource || !frame())
@@ -411,7 +415,7 @@ void DocLoader::checkCacheObjectStatus(CachedResource* resource)
frame()->loader()->loadedResourceFromMemoryCache(resource);
}
-void DocLoader::incrementRequestCount(const CachedResource* res)
+void CachedResourceLoader::incrementRequestCount(const CachedResource* res)
{
if (res->isPrefetch())
return;
@@ -419,7 +423,7 @@ void DocLoader::incrementRequestCount(const CachedResource* res)
++m_requestCount;
}
-void DocLoader::decrementRequestCount(const CachedResource* res)
+void CachedResourceLoader::decrementRequestCount(const CachedResource* res)
{
if (res->isPrefetch())
return;
@@ -428,14 +432,14 @@ void DocLoader::decrementRequestCount(const CachedResource* res)
ASSERT(m_requestCount > -1);
}
-int DocLoader::requestCount()
+int CachedResourceLoader::requestCount()
{
if (loadInProgress())
return m_requestCount + 1;
return m_requestCount;
}
-void DocLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
+void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
{
bool hasRendering = m_doc->body() && m_doc->body()->renderer();
if (!hasRendering && (referencedFromBody || type == CachedResource::ImageResource)) {
@@ -448,7 +452,7 @@ void DocLoader::preload(CachedResource::Type type, const String& url, const Stri
requestPreload(type, url, charset);
}
-void DocLoader::checkForPendingPreloads()
+void CachedResourceLoader::checkForPendingPreloads()
{
unsigned count = m_pendingPreloads.size();
if (!count || !m_doc->body() || !m_doc->body()->renderer())
@@ -462,7 +466,7 @@ void DocLoader::checkForPendingPreloads()
m_pendingPreloads.clear();
}
-void DocLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
+void CachedResourceLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
{
String encoding;
if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
@@ -482,7 +486,7 @@ void DocLoader::requestPreload(CachedResource::Type type, const String& url, con
#endif
}
-void DocLoader::clearPreloads()
+void CachedResourceLoader::clearPreloads()
{
#if PRELOAD_DEBUG
printPreloadStats();
@@ -502,13 +506,13 @@ void DocLoader::clearPreloads()
m_preloads.clear();
}
-void DocLoader::clearPendingPreloads()
+void CachedResourceLoader::clearPendingPreloads()
{
m_pendingPreloads.clear();
}
#if PRELOAD_DEBUG
-void DocLoader::printPreloadStats()
+void CachedResourceLoader::printPreloadStats()
{
unsigned scripts = 0;
unsigned scriptMisses = 0;
diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/CachedResourceLoader.h
index d77bce5..16d73ad 100644
--- a/WebCore/loader/DocLoader.h
+++ b/WebCore/loader/CachedResourceLoader.h
@@ -23,8 +23,8 @@
pages from the web. It has a memory cache for these objects.
*/
-#ifndef DocLoader_h
-#define DocLoader_h
+#ifndef CachedResourceLoader_h
+#define CachedResourceLoader_h
#include "CachedResource.h"
#include "CachedResourceHandle.h"
@@ -46,14 +46,14 @@ class Frame;
class ImageLoader;
class KURL;
-// The DocLoader manages the loading of scripts/images/stylesheets for a single document.
-class DocLoader : public Noncopyable {
+// The CachedResourceLoader manages the loading of scripts/images/stylesheets for a single document.
+class CachedResourceLoader : public Noncopyable {
friend class Cache;
friend class ImageLoader;
public:
- DocLoader(Document*);
- ~DocLoader();
+ CachedResourceLoader(Document*);
+ ~CachedResourceLoader();
CachedImage* requestImage(const String& url);
CachedCSSStyleSheet* requestCSSStyleSheet(const String& url, const String& charset);
diff --git a/WebCore/loader/CachedScript.h b/WebCore/loader/CachedScript.h
index beab508..1bc4e8c 100644
--- a/WebCore/loader/CachedScript.h
+++ b/WebCore/loader/CachedScript.h
@@ -31,7 +31,7 @@
namespace WebCore {
- class DocLoader;
+ class CachedResourceLoader;
class TextResourceDecoder;
class CachedScript : public CachedResource {
diff --git a/WebCore/loader/CachedXSLStyleSheet.h b/WebCore/loader/CachedXSLStyleSheet.h
index a0b5477..8587b0b 100644
--- a/WebCore/loader/CachedXSLStyleSheet.h
+++ b/WebCore/loader/CachedXSLStyleSheet.h
@@ -31,7 +31,7 @@
namespace WebCore {
- class DocLoader;
+ class CachedResourceLoader;
class TextResourceDecoder;
#if ENABLE(XSLT)
diff --git a/WebCore/loader/DocumentLoader.cpp b/WebCore/loader/DocumentLoader.cpp
index 1e18077..1bb2f87 100644
--- a/WebCore/loader/DocumentLoader.cpp
+++ b/WebCore/loader/DocumentLoader.cpp
@@ -37,7 +37,7 @@
#include "SubstituteResource.h"
#endif
#include "CachedPage.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentParser.h"
#include "Event.h"
@@ -398,7 +398,7 @@ bool DocumentLoader::isLoadingInAPISense() const
if (!m_subresourceLoaders.isEmpty())
return true;
Document* doc = m_frame->document();
- if (doc->docLoader()->requestCount())
+ if (doc->cachedResourceLoader()->requestCount())
return true;
if (DocumentParser* parser = doc->parser())
if (parser->processingData())
@@ -480,7 +480,7 @@ PassRefPtr<ArchiveResource> DocumentLoader::subresource(const KURL& url) const
if (!isCommitted())
return 0;
- CachedResource* resource = m_frame->document()->docLoader()->cachedResource(url);
+ CachedResource* resource = m_frame->document()->cachedResourceLoader()->cachedResource(url);
if (!resource || !resource->isLoaded())
return archiveResourceForURL(url);
@@ -503,9 +503,9 @@ void DocumentLoader::getSubresources(Vector<PassRefPtr<ArchiveResource> >& subre
Document* document = m_frame->document();
- const DocLoader::DocumentResourceMap& allResources = document->docLoader()->allCachedResources();
- DocLoader::DocumentResourceMap::const_iterator end = allResources.end();
- for (DocLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
+ const CachedResourceLoader::DocumentResourceMap& allResources = document->cachedResourceLoader()->allCachedResources();
+ CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end();
+ for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
RefPtr<ArchiveResource> subresource = this->subresource(KURL(ParsedURLString, it->second->url()));
if (subresource)
subresources.append(subresource.release());
diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h
index 32722d6..e012b64 100644
--- a/WebCore/loader/EmptyClients.h
+++ b/WebCore/loader/EmptyClients.h
@@ -40,6 +40,7 @@
#include "FloatRect.h"
#include "FocusDirection.h"
#include "FrameLoaderClient.h"
+#include "FrameNetworkingContext.h"
#include "InspectorClient.h"
#include "PluginHalterClient.h"
#include "PopupMenu.h"
@@ -61,6 +62,8 @@
namespace WebCore {
+class SharedGraphicsContext3D;
+
class EmptyPopupMenu : public PopupMenu {
public:
virtual void show(const IntRect&, FrameView*, int) {}
@@ -194,9 +197,9 @@ public:
virtual void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) {}
#if USE(ACCELERATED_COMPOSITING)
- virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) {};
- virtual void setNeedsOneShotDrawingSynchronization() {};
- virtual void scheduleCompositingLayerSync() {};
+ virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) {}
+ virtual void setNeedsOneShotDrawingSynchronization() {}
+ virtual void scheduleCompositingLayerSync() {}
#endif
#if PLATFORM(WIN)
@@ -372,6 +375,7 @@ public:
virtual bool shouldCacheResponse(DocumentLoader*, unsigned long, const ResourceResponse&, const unsigned char*, unsigned long long) { return true; }
#endif
+ virtual PassRefPtr<FrameNetworkingContext> createNetworkingContext() { return PassRefPtr<FrameNetworkingContext>(); }
};
class EmptyEditorClient : public EditorClient, public Noncopyable {
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 496cac9..4cbfb00 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -45,7 +45,7 @@
#include "Chrome.h"
#include "DOMImplementation.h"
#include "DOMWindow.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentLoadTiming.h"
#include "DocumentLoader.h"
@@ -60,6 +60,7 @@
#include "Frame.h"
#include "FrameLoadRequest.h"
#include "FrameLoaderClient.h"
+#include "FrameNetworkingContext.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLAnchorElement.h"
@@ -163,7 +164,7 @@ static int numRequests(Document* document)
if (!document)
return 0;
- return document->docLoader()->requestCount();
+ return document->cachedResourceLoader()->requestCount();
}
// This is not in the FrameLoader class to emphasize that it does not depend on
@@ -223,6 +224,9 @@ FrameLoader::~FrameLoader()
(*it)->loader()->m_opener = 0;
m_client->frameLoaderDestroyed();
+
+ if (m_networkingContext)
+ m_networkingContext->invalidate();
}
void FrameLoader::init()
@@ -243,6 +247,8 @@ void FrameLoader::init()
m_frame->document()->cancelParsing();
m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
m_didCallImplicitClose = true;
+
+ m_networkingContext = m_client->createNetworkingContext();
}
void FrameLoader::setDefersLoading(bool defers)
@@ -426,8 +432,12 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
m_workingURL = KURL();
if (Document* doc = m_frame->document()) {
- if (DocLoader* docLoader = doc->docLoader())
- cache()->loader()->cancelRequests(docLoader);
+ // FIXME: HTML5 doesn't tell us to set the state to complete when aborting, but we do anyway to match legacy behavior.
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10537
+ doc->setReadyState(Document::Complete);
+
+ if (CachedResourceLoader* cachedResourceLoader = doc->cachedResourceLoader())
+ cache()->loader()->cancelRequests(cachedResourceLoader);
#if ENABLE(DATABASE)
if (databasePolicy == DatabasePolicyStop)
@@ -666,10 +676,14 @@ void FrameLoader::didBeginDocument(bool dispatch)
updateFirstPartyForCookies();
Settings* settings = m_frame->document()->settings();
+<<<<<<< HEAD
m_frame->document()->docLoader()->setAutoLoadImages(settings && settings->loadsImagesAutomatically());
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
m_frame->document()->docLoader()->setBlockNetworkImage(settings && settings->blockNetworkImage());
#endif
+=======
+ m_frame->document()->cachedResourceLoader()->setAutoLoadImages(settings && settings->loadsImagesAutomatically());
+>>>>>>> webkit.org at r67178
if (m_documentLoader) {
String dnsPrefetchControl = m_documentLoader->response().httpHeaderField("X-DNS-Prefetch-Control");
@@ -842,6 +856,7 @@ void FrameLoader::checkCompleted()
// OK, completed.
m_isComplete = true;
+ m_frame->document()->setReadyState(Document::Complete);
RefPtr<Frame> protect(m_frame);
checkCallImplicitClose(); // if we didn't do it before
@@ -1056,6 +1071,7 @@ void FrameLoader::setOpener(Frame* opener)
}
}
+// FIXME: This does not belong in FrameLoader!
void FrameLoader::handleFallbackContent()
{
HTMLFrameOwnerElement* owner = m_frame->ownerElement();
@@ -1272,7 +1288,7 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHis
ASSERT(frame()->document());
if (SchemeRegistry::shouldTreatURLAsLocal(url.string()) && !isFeedWithNestedProtocolInHTTPFamily(url)) {
- if (!SecurityOrigin::canLoad(url, String(), frame()->document()) && !SecurityOrigin::canLoad(url, referrer, 0)) {
+ if (!SecurityOrigin::canDisplay(url, String(), frame()->document()) && !SecurityOrigin::canDisplay(url, referrer, 0)) {
FrameLoader::reportLocalLoadFailed(m_frame, url.string());
return;
}
@@ -3478,6 +3494,11 @@ void FrameLoader::tellClientAboutPastMemoryCacheLoads()
}
}
+NetworkingContext* FrameLoader::networkingContext() const
+{
+ return m_networkingContext.get();
+}
+
bool FrameLoaderClient::hasHTMLView() const
{
return true;
diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h
index 754c151..a887e3b 100644
--- a/WebCore/loader/FrameLoader.h
+++ b/WebCore/loader/FrameLoader.h
@@ -64,10 +64,12 @@ class FormState;
class FormSubmission;
class Frame;
class FrameLoaderClient;
+class FrameNetworkingContext;
class HistoryItem;
class HTMLFormElement;
class IconLoader;
class NavigationAction;
+class NetworkingContext;
class ProtectionSpace;
class ResourceError;
class ResourceLoader;
@@ -335,6 +337,8 @@ public:
bool pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
+ inline NetworkingContext* networkingContext() const;
+
private:
bool canCachePageContainingThisFrame();
#ifndef NDEBUG
@@ -501,6 +505,8 @@ private:
#ifndef NDEBUG
bool m_didDispatchDidCommitLoad;
#endif
+
+ RefPtr<FrameNetworkingContext> m_networkingContext;
};
// This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
diff --git a/WebCore/loader/FrameLoaderClient.h b/WebCore/loader/FrameLoaderClient.h
index 26a1259..7c28c51 100644
--- a/WebCore/loader/FrameLoaderClient.h
+++ b/WebCore/loader/FrameLoaderClient.h
@@ -52,6 +52,7 @@ namespace WebCore {
class FormState;
class Frame;
class FrameLoader;
+ class FrameNetworkingContext;
class HistoryItem;
class HTMLAppletElement;
class HTMLFormElement;
@@ -285,6 +286,8 @@ namespace WebCore {
virtual void didNotAllowScript() { }
// This callback is similar, but for plugins.
virtual void didNotAllowPlugins() { }
+
+ virtual PassRefPtr<FrameNetworkingContext> createNetworkingContext() = 0;
};
} // namespace WebCore
diff --git a/WebCore/loader/HistoryController.cpp b/WebCore/loader/HistoryController.cpp
index 32a6a91..f06589e 100644
--- a/WebCore/loader/HistoryController.cpp
+++ b/WebCore/loader/HistoryController.cpp
@@ -450,9 +450,9 @@ void HistoryController::setProvisionalItem(HistoryItem* item)
PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
{
- DocumentLoader* docLoader = m_frame->loader()->documentLoader();
+ DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
- KURL unreachableURL = docLoader ? docLoader->unreachableURL() : KURL();
+ KURL unreachableURL = documentLoader ? documentLoader->unreachableURL() : KURL();
KURL url;
KURL originalURL;
@@ -461,11 +461,11 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
url = unreachableURL;
originalURL = unreachableURL;
} else {
- originalURL = docLoader ? docLoader->originalURL() : KURL();
+ originalURL = documentLoader ? documentLoader->originalURL() : KURL();
if (useOriginal)
url = originalURL;
- else if (docLoader)
- url = docLoader->requestURL();
+ else if (documentLoader)
+ url = documentLoader->requestURL();
}
LOG(History, "WebCoreHistory: Creating item for %s", url.string().ascii().data());
@@ -482,20 +482,20 @@ PassRefPtr<HistoryItem> HistoryController::createItem(bool useOriginal)
Frame* parentFrame = m_frame->tree()->parent();
String parent = parentFrame ? parentFrame->tree()->name() : "";
- String title = docLoader ? docLoader->title() : "";
+ String title = documentLoader ? documentLoader->title() : "";
RefPtr<HistoryItem> item = HistoryItem::create(url, m_frame->tree()->name(), parent, title);
item->setOriginalURLString(originalURL.string());
- if (!unreachableURL.isEmpty() || !docLoader || docLoader->response().httpStatusCode() >= 400)
+ if (!unreachableURL.isEmpty() || !documentLoader || documentLoader->response().httpStatusCode() >= 400)
item->setLastVisitWasFailure(true);
// Save form state if this is a POST
- if (docLoader) {
+ if (documentLoader) {
if (useOriginal)
- item->setFormInfoFromRequest(docLoader->originalRequest());
+ item->setFormInfoFromRequest(documentLoader->originalRequest());
else
- item->setFormInfoFromRequest(docLoader->request());
+ item->setFormInfoFromRequest(documentLoader->request());
}
// Set the item for which we will save document state
diff --git a/WebCore/loader/ImageLoader.cpp b/WebCore/loader/ImageLoader.cpp
index 242bf94..f6bc8d0 100644
--- a/WebCore/loader/ImageLoader.cpp
+++ b/WebCore/loader/ImageLoader.cpp
@@ -24,7 +24,7 @@
#include "CSSHelper.h"
#include "CachedImage.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "Element.h"
#include "HTMLNames.h"
@@ -161,15 +161,15 @@ void ImageLoader::updateFromElement()
CachedImage* newImage = 0;
if (!(attr.isNull() || (attr.isEmpty() && document->baseURI().isLocalFile()))) {
if (m_loadManually) {
- bool autoLoadOtherImages = document->docLoader()->autoLoadImages();
- document->docLoader()->setAutoLoadImages(false);
+ bool autoLoadOtherImages = document->cachedResourceLoader()->autoLoadImages();
+ document->cachedResourceLoader()->setAutoLoadImages(false);
newImage = new CachedImage(sourceURI(attr));
newImage->setLoading(true);
- newImage->setDocLoader(document->docLoader());
- document->docLoader()->m_documentResources.set(newImage->url(), newImage);
- document->docLoader()->setAutoLoadImages(autoLoadOtherImages);
+ newImage->setCachedResourceLoader(document->cachedResourceLoader());
+ document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage);
+ document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages);
} else
- newImage = document->docLoader()->requestImage(sourceURI(attr));
+ newImage = document->cachedResourceLoader()->requestImage(sourceURI(attr));
// If we do not have an image here, it means that a cross-site
// violation occurred.
diff --git a/WebCore/loader/PingLoader.cpp b/WebCore/loader/PingLoader.cpp
index 60c6f30..268e007 100644
--- a/WebCore/loader/PingLoader.cpp
+++ b/WebCore/loader/PingLoader.cpp
@@ -42,7 +42,7 @@ namespace WebCore {
void PingLoader::loadImage(Frame* frame, const KURL& url)
{
- if (SecurityOrigin::restrictAccessToLocal() && !SecurityOrigin::canLoad(url, String(), frame->document())) {
+ if (SecurityOrigin::restrictAccessToLocal() && !SecurityOrigin::canDisplay(url, String(), frame->document())) {
FrameLoader::reportLocalLoadFailed(frame, url);
return;
}
diff --git a/WebCore/loader/RedirectScheduler.cpp b/WebCore/loader/RedirectScheduler.cpp
index 461baf7..7cb6090 100644
--- a/WebCore/loader/RedirectScheduler.cpp
+++ b/WebCore/loader/RedirectScheduler.cpp
@@ -172,16 +172,19 @@ private:
class ScheduledFormSubmission : public ScheduledNavigation {
public:
- ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBackForwardList, bool duringLoad)
+ ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBackForwardList, bool duringLoad, bool wasUserGesture)
: ScheduledNavigation(0, submission->lockHistory(), lockBackForwardList, duringLoad, true)
, m_submission(submission)
, m_haveToldClient(false)
+ , m_wasUserGesture(wasUserGesture)
{
ASSERT(m_submission->state());
}
virtual void fire(Frame* frame)
{
+ UserGestureIndicator gestureIndicator(m_wasUserGesture ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
+
// The submitForm function will find a target frame before using the redirection timer.
// Now that the timer has fired, we need to repeat the security check which normally is done when
// selecting a target, in case conditions have changed. Other code paths avoid this by targeting
@@ -211,6 +214,7 @@ public:
private:
RefPtr<FormSubmission> m_submission;
bool m_haveToldClient;
+ bool m_wasUserGesture;
};
RedirectScheduler::RedirectScheduler(Frame* frame)
@@ -311,10 +315,10 @@ void RedirectScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submis
// If this is a child frame and the form submission was triggered by a script, lock the back/forward list
// to match IE and Opera.
// See https://bugs.webkit.org/show_bug.cgi?id=32383 for the original motivation for this.
+ bool isUserGesture = m_frame->loader()->isProcessingUserGesture();
+ bool lockBackForwardList = mustLockBackForwardList(m_frame, isUserGesture) || (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent());
- bool lockBackForwardList = mustLockBackForwardList(m_frame, UserGestureIndicator::processingUserGesture()) || (submission->state()->formSubmissionTrigger() == SubmittedByJavaScript && m_frame->tree()->parent());
-
- schedule(adoptPtr(new ScheduledFormSubmission(submission, lockBackForwardList, duringLoad)));
+ schedule(adoptPtr(new ScheduledFormSubmission(submission, lockBackForwardList, duringLoad, isUserGesture)));
}
void RedirectScheduler::scheduleRefresh(bool wasUserGesture)
diff --git a/WebCore/loader/Request.cpp b/WebCore/loader/Request.cpp
index 630a4bb..6ad6f9c 100644
--- a/WebCore/loader/Request.cpp
+++ b/WebCore/loader/Request.cpp
@@ -28,9 +28,9 @@
namespace WebCore {
-Request::Request(DocLoader* docLoader, CachedResource* object, bool incremental, SecurityCheckPolicy shouldDoSecurityCheck, bool sendResourceLoadCallbacks)
+Request::Request(CachedResourceLoader* cachedResourceLoader, CachedResource* object, bool incremental, SecurityCheckPolicy shouldDoSecurityCheck, bool sendResourceLoadCallbacks)
: m_object(object)
- , m_docLoader(docLoader)
+ , m_cachedResourceLoader(cachedResourceLoader)
, m_incremental(incremental)
, m_multipart(false)
, m_shouldDoSecurityCheck(shouldDoSecurityCheck)
diff --git a/WebCore/loader/Request.h b/WebCore/loader/Request.h
index 468f8ff..b6a9e90 100644
--- a/WebCore/loader/Request.h
+++ b/WebCore/loader/Request.h
@@ -29,16 +29,16 @@
namespace WebCore {
class CachedResource;
- class DocLoader;
+ class CachedResourceLoader;
class Request : public Noncopyable {
public:
- Request(DocLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
+ Request(CachedResourceLoader*, CachedResource*, bool incremental, SecurityCheckPolicy, bool sendResourceLoadCallbacks);
~Request();
Vector<char>& buffer() { return m_buffer; }
CachedResource* cachedResource() { return m_object; }
- DocLoader* docLoader() { return m_docLoader; }
+ CachedResourceLoader* cachedResourceLoader() { return m_cachedResourceLoader; }
bool isIncremental() { return m_incremental; }
void setIsIncremental(bool b = true) { m_incremental = b; }
@@ -52,7 +52,7 @@ namespace WebCore {
private:
Vector<char> m_buffer;
CachedResource* m_object;
- DocLoader* m_docLoader;
+ CachedResourceLoader* m_cachedResourceLoader;
bool m_incremental;
bool m_multipart;
SecurityCheckPolicy m_shouldDoSecurityCheck;
diff --git a/WebCore/loader/ResourceLoader.cpp b/WebCore/loader/ResourceLoader.cpp
index b679795..f66aa67 100644
--- a/WebCore/loader/ResourceLoader.cpp
+++ b/WebCore/loader/ResourceLoader.cpp
@@ -412,7 +412,7 @@ void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse&
{
#if ENABLE(INSPECTOR)
if (InspectorTimelineAgent::instanceCount()) {
- InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
+ InspectorTimelineAgent* timelineAgent = (m_frame && m_frame->page()) ? m_frame->page()->inspectorTimelineAgent() : 0;
if (timelineAgent)
timelineAgent->willReceiveResourceResponse(identifier(), response);
}
@@ -424,7 +424,7 @@ void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse&
didReceiveResponse(response);
#if ENABLE(INSPECTOR)
if (InspectorTimelineAgent::instanceCount()) {
- InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
+ InspectorTimelineAgent* timelineAgent = (m_frame && m_frame->page()) ? m_frame->page()->inspectorTimelineAgent() : 0;
if (timelineAgent)
timelineAgent->didReceiveResourceResponse();
}
@@ -435,7 +435,7 @@ void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int lengt
{
#if ENABLE(INSPECTOR)
if (InspectorTimelineAgent::instanceCount()) {
- InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
+ InspectorTimelineAgent* timelineAgent = (m_frame && m_frame->page()) ? m_frame->page()->inspectorTimelineAgent() : 0;
if (timelineAgent)
timelineAgent->willReceiveResourceData(identifier());
}
@@ -443,7 +443,7 @@ void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int lengt
didReceiveData(data, length, lengthReceived, false);
#if ENABLE(INSPECTOR)
if (InspectorTimelineAgent::instanceCount()) {
- InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
+ InspectorTimelineAgent* timelineAgent = (m_frame && m_frame->page()) ? m_frame->page()->inspectorTimelineAgent() : 0;
if (timelineAgent)
timelineAgent->didReceiveResourceData();
}
diff --git a/WebCore/loader/SubframeLoader.cpp b/WebCore/loader/SubframeLoader.cpp
index ceafb88..c25b37e 100644
--- a/WebCore/loader/SubframeLoader.cpp
+++ b/WebCore/loader/SubframeLoader.cpp
@@ -147,7 +147,7 @@ PassRefPtr<Widget> SubframeLoader::loadMediaPlayerProxyPlugin(Node* node, const
if (!url.isEmpty())
completedURL = completeURL(url);
- if (!SecurityOrigin::canLoad(completedURL, String(), m_frame->document())) {
+ if (!SecurityOrigin::canDisplay(completedURL, String(), m_frame->document())) {
FrameLoader::reportLocalLoadFailed(m_frame, completedURL.string());
return 0;
}
@@ -205,7 +205,7 @@ PassRefPtr<Widget> SubframeLoader::createJavaAppletWidget(const IntSize& size, H
if (!codeBaseURLString.isEmpty()) {
KURL codeBaseURL = completeURL(codeBaseURLString);
- if (!SecurityOrigin::canLoad(codeBaseURL, String(), element->document())) {
+ if (!SecurityOrigin::canDisplay(codeBaseURL, String(), element->document())) {
FrameLoader::reportLocalLoadFailed(m_frame, codeBaseURL.string());
return 0;
}
@@ -247,7 +247,7 @@ Frame* SubframeLoader::loadSubframe(HTMLFrameOwnerElement* ownerElement, const K
marginHeight = o->getMarginHeight();
}
- if (!SecurityOrigin::canLoad(url, String(), ownerElement->document())) {
+ if (!SecurityOrigin::canDisplay(url, String(), ownerElement->document())) {
FrameLoader::reportLocalLoadFailed(m_frame, url.string());
return 0;
}
@@ -336,7 +336,7 @@ bool SubframeLoader::loadPlugin(HTMLPlugInImageElement* pluginElement, const KUR
if (!renderer || useFallback)
return false;
- if (!SecurityOrigin::canLoad(url, String(), document())) {
+ if (!SecurityOrigin::canDisplay(url, String(), document())) {
FrameLoader::reportLocalLoadFailed(m_frame, url.string());
return false;
}
diff --git a/WebCore/loader/SubresourceLoader.cpp b/WebCore/loader/SubresourceLoader.cpp
index 1e22fb1..a389082 100644
--- a/WebCore/loader/SubresourceLoader.cpp
+++ b/WebCore/loader/SubresourceLoader.cpp
@@ -73,7 +73,7 @@ PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, Subresourc
if (securityCheck == DoSecurityCheck
&& SecurityOrigin::restrictAccessToLocal()
- && !SecurityOrigin::canLoad(request.url(), String(), frame->document())) {
+ && !SecurityOrigin::canDisplay(request.url(), String(), frame->document())) {
FrameLoader::reportLocalLoadFailed(frame, request.url().string());
return 0;
}
diff --git a/WebCore/loader/TextDocument.cpp b/WebCore/loader/TextDocument.cpp
deleted file mode 100644
index 4b09a9e..0000000
--- a/WebCore/loader/TextDocument.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "TextDocument.h"
-
-#include "DecodedDataDocumentParser.h"
-#include "Element.h"
-#include "HTMLNames.h"
-#include "HTMLViewSourceDocument.h"
-#include "SegmentedString.h"
-#include "Text.h"
-
-using namespace std;
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-// FIXME: TextDocumentParser could just be an HTMLDocumentParser
-// which started the Tokenizer in the PlainText state.
-class TextDocumentParser : public DecodedDataDocumentParser {
-public:
- static PassRefPtr<TextDocumentParser> create(Document* document)
- {
- return adoptRef(new TextDocumentParser(document));
- }
-
- static PassRefPtr<TextDocumentParser> create(HTMLViewSourceDocument* document)
- {
- return adoptRef(new TextDocumentParser(document));
- }
-
- virtual ~TextDocumentParser();
-
-private:
- TextDocumentParser(Document*);
- TextDocumentParser(HTMLViewSourceDocument*);
-
- virtual void insert(const SegmentedString&);
- virtual void append(const SegmentedString&);
- virtual void finish();
- virtual bool finishWasCalled();
-
- inline void checkBuffer(int len = 10)
- {
- if ((m_dest - m_buffer) > m_size - len) {
- // Enlarge buffer
- int newSize = std::max(m_size * 2, m_size + len);
- int oldOffset = m_dest - m_buffer;
- m_buffer = static_cast<UChar*>(fastRealloc(m_buffer, newSize * sizeof(UChar)));
- m_dest = m_buffer + oldOffset;
- m_size = newSize;
- }
- }
-
-private:
- Element* m_preElement;
-
- bool m_skipLF;
-
- int m_size;
- UChar* m_buffer;
- UChar* m_dest;
-};
-
-TextDocumentParser::TextDocumentParser(Document* document)
- : DecodedDataDocumentParser(document)
- , m_preElement(0)
- , m_skipLF(false)
-{
- // Allocate buffer
- m_size = 254;
- m_buffer = static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size));
- m_dest = m_buffer;
-}
-
-TextDocumentParser::TextDocumentParser(HTMLViewSourceDocument* document)
- : DecodedDataDocumentParser(document, true)
- , m_preElement(0)
- , m_skipLF(false)
-{
- // Allocate buffer
- m_size = 254;
- m_buffer = static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size));
- m_dest = m_buffer;
-}
-
-TextDocumentParser::~TextDocumentParser()
-{
- // finish() should have been called to prevent any leaks
- ASSERT(!m_buffer);
-}
-
-void TextDocumentParser::insert(const SegmentedString&)
-{
- ASSERT_NOT_REACHED();
-}
-
-void TextDocumentParser::append(const SegmentedString& s)
-{
- ExceptionCode ec;
-
- m_dest = m_buffer;
-
- SegmentedString str = s;
- while (!str.isEmpty()) {
- UChar c = *str;
-
- if (c == '\r') {
- *m_dest++ = '\n';
-
- // possibly skip an LF in the case of an CRLF sequence
- m_skipLF = true;
- } else if (c == '\n') {
- if (!m_skipLF)
- *m_dest++ = c;
- else
- m_skipLF = false;
- } else {
- *m_dest++ = c;
- m_skipLF = false;
- }
-
- str.advance();
-
- // Maybe enlarge the buffer
- checkBuffer();
- }
-
- if (!m_preElement && !inViewSourceMode()) {
- RefPtr<Element> rootElement = document()->createElement(htmlTag, false);
- document()->appendChild(rootElement, ec);
-
- RefPtr<Element> body = document()->createElement(bodyTag, false);
- rootElement->appendChild(body, ec);
-
- RefPtr<Element> preElement = document()->createElement(preTag, false);
- preElement->setAttribute("style", "word-wrap: break-word; white-space: pre-wrap;", ec);
-
- body->appendChild(preElement, ec);
-
- m_preElement = preElement.get();
- }
-
- String string = String(m_buffer, m_dest - m_buffer);
- if (inViewSourceMode()) {
- static_cast<HTMLViewSourceDocument*>(document())->addViewSourceText(string);
- return;
- }
-
- unsigned charsLeft = string.length();
- while (charsLeft) {
- // split large text to nodes of manageable size
- RefPtr<Text> text = Text::createWithLengthLimit(document(), string, charsLeft);
- m_preElement->appendChild(text, ec);
- }
-}
-
-void TextDocumentParser::finish()
-{
- if (!m_preElement)
- append(SegmentedString()); // Create document structure for an empty text document.
- m_preElement = 0;
- fastFree(m_buffer);
- m_buffer = 0;
- m_dest = 0;
-
- // FIXME: Should this call finishParsing even if m_parserStopped is true?
- // See equivalent implementation in RawDataDocumentParser.
- document()->finishedParsing();
-}
-
-bool TextDocumentParser::finishWasCalled()
-{
- // finish() always calls document()->finishedParsing() so we'll be deleted
- // after finish().
- return false;
-}
-
-TextDocument::TextDocument(Frame* frame, const KURL& url)
- : HTMLDocument(frame, url)
-{
- setCompatibilityMode(QuirksMode);
- lockCompatibilityMode();
-}
-
-PassRefPtr<DocumentParser> TextDocument::createParser()
-{
- return TextDocumentParser::create(this);
-}
-
-PassRefPtr<DocumentParser> createTextDocumentParser(HTMLViewSourceDocument* document)
-{
- return TextDocumentParser::create(document);
-}
-
-}
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index 345d881..3f6fad2 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -27,7 +27,7 @@
#include "Cache.h"
#include "CachedImage.h"
#include "CachedResource.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "InspectorTimelineAgent.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -121,10 +121,10 @@ Loader::Priority Loader::determinePriority(const CachedResource* resource) const
#endif
}
-void Loader::load(DocLoader* docLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
+void Loader::load(CachedResourceLoader* cachedResourceLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
{
- ASSERT(docLoader);
- Request* request = new Request(docLoader, resource, incremental, securityCheck, sendResourceLoadCallbacks);
+ ASSERT(cachedResourceLoader);
+ Request* request = new Request(cachedResourceLoader, resource, incremental, securityCheck, sendResourceLoadCallbacks);
RefPtr<Host> host;
KURL url(ParsedURLString, resource->url());
@@ -142,7 +142,7 @@ void Loader::load(DocLoader* docLoader, CachedResource* resource, bool increment
bool hadRequests = host->hasRequests();
Priority priority = determinePriority(resource);
host->addRequest(request, priority);
- docLoader->incrementRequestCount(request->cachedResource());
+ cachedResourceLoader->incrementRequestCount(request->cachedResource());
if (priority > Low || !url.protocolInHTTPFamily() || (priority == Low && !hadRequests)) {
// Try to request important resources immediately
@@ -151,7 +151,7 @@ void Loader::load(DocLoader* docLoader, CachedResource* resource, bool increment
// Handle asynchronously so early low priority requests don't get scheduled before later high priority ones
#if ENABLE(INSPECTOR)
if (InspectorTimelineAgent::instanceCount()) {
- InspectorTimelineAgent* agent = docLoader->doc()->inspectorTimelineAgent();
+ InspectorTimelineAgent* agent = cachedResourceLoader->doc()->inspectorTimelineAgent();
if (agent)
agent->didScheduleResourceRequest(resource->url());
}
@@ -243,12 +243,12 @@ void Loader::nonCacheRequestComplete(const KURL& url)
host->nonCacheRequestComplete();
}
-void Loader::cancelRequests(DocLoader* docLoader)
+void Loader::cancelRequests(CachedResourceLoader* cachedResourceLoader)
{
- docLoader->clearPendingPreloads();
+ cachedResourceLoader->clearPendingPreloads();
if (m_nonHTTPProtocolHost->hasRequests())
- m_nonHTTPProtocolHost->cancelRequests(docLoader);
+ m_nonHTTPProtocolHost->cancelRequests(cachedResourceLoader);
Vector<Host*> hostsToCancel;
m_hosts.checkConsistency();
@@ -260,12 +260,12 @@ void Loader::cancelRequests(DocLoader* docLoader)
for (unsigned n = 0; n < hostsToCancel.size(); ++n) {
Host* host = hostsToCancel[n];
if (host->hasRequests())
- host->cancelRequests(docLoader);
+ host->cancelRequests(cachedResourceLoader);
}
scheduleServePendingRequests();
- ASSERT(docLoader->requestCount() == (docLoader->loadInProgress() ? 1 : 0));
+ ASSERT(cachedResourceLoader->requestCount() == (cachedResourceLoader->loadInProgress() ? 1 : 0));
}
Loader::Host::Host(const AtomicString& name, unsigned maxRequestsInFlight)
@@ -326,13 +326,13 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
{
while (!requestsPending.isEmpty()) {
Request* request = requestsPending.first();
- DocLoader* docLoader = request->docLoader();
+ CachedResourceLoader* cachedResourceLoader = request->cachedResourceLoader();
bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();
// For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
// For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing
// and we don't know all stylesheets yet.
- bool shouldLimitRequests = !m_name.isNull() || docLoader->doc()->parsing() || !docLoader->doc()->haveStylesheetsLoaded();
+ bool shouldLimitRequests = !m_name.isNull() || cachedResourceLoader->doc()->parsing() || !cachedResourceLoader->doc()->haveStylesheetsLoaded();
if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) {
serveLowerPriority = false;
return;
@@ -354,8 +354,8 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
if (!lastModified.isEmpty() || !eTag.isEmpty()) {
- ASSERT(docLoader->cachePolicy() != CachePolicyReload);
- if (docLoader->cachePolicy() == CachePolicyRevalidate)
+ ASSERT(cachedResourceLoader->cachePolicy() != CachePolicyReload);
+ if (cachedResourceLoader->cachePolicy() == CachePolicyRevalidate)
resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
if (!lastModified.isEmpty())
resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
@@ -364,7 +364,7 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
}
}
- RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
+ RefPtr<SubresourceLoader> loader = SubresourceLoader::create(cachedResourceLoader->doc()->frame(),
this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
if (loader) {
m_requestsLoading.add(loader.release(), request);
@@ -373,10 +373,10 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser
printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
} else {
- docLoader->decrementRequestCount(request->cachedResource());
- docLoader->setLoadInProgress(true);
+ cachedResourceLoader->decrementRequestCount(request->cachedResource());
+ cachedResourceLoader->setLoadInProgress(true);
request->cachedResource()->error();
- docLoader->setLoadInProgress(false);
+ cachedResourceLoader->setLoadInProgress(false);
delete request;
}
}
@@ -392,12 +392,12 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader)
Request* request = i->second;
m_requestsLoading.remove(i);
- DocLoader* docLoader = request->docLoader();
+ CachedResourceLoader* cachedResourceLoader = request->cachedResourceLoader();
// Prevent the document from being destroyed before we are done with
- // the docLoader that it will delete when the document gets deleted.
- RefPtr<Document> protector(docLoader->doc());
+ // the cachedResourceLoader that it will delete when the document gets deleted.
+ RefPtr<Document> protector(cachedResourceLoader->doc());
if (!request->isMultipart())
- docLoader->decrementRequestCount(request->cachedResource());
+ cachedResourceLoader->decrementRequestCount(request->cachedResource());
CachedResource* resource = request->cachedResource();
ASSERT(!resource->resourceToRevalidate());
@@ -405,16 +405,16 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader)
// If we got a 4xx response, we're pretending to have received a network
// error, so we can't send the successful data() and finish() callbacks.
if (!resource->errorOccurred()) {
- docLoader->setLoadInProgress(true);
+ cachedResourceLoader->setLoadInProgress(true);
resource->data(loader->resourceData(), true);
resource->finish();
}
delete request;
- docLoader->setLoadInProgress(false);
+ cachedResourceLoader->setLoadInProgress(false);
- docLoader->checkForPendingPreloads();
+ cachedResourceLoader->checkForPendingPreloads();
#if REQUEST_DEBUG
KURL u(ParsedURLString, resource->url());
@@ -440,12 +440,12 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
Request* request = i->second;
m_requestsLoading.remove(i);
- DocLoader* docLoader = request->docLoader();
+ CachedResourceLoader* cachedResourceLoader = request->cachedResourceLoader();
// Prevent the document from being destroyed before we are done with
- // the docLoader that it will delete when the document gets deleted.
- RefPtr<Document> protector(docLoader->doc());
+ // the cachedResourceLoader that it will delete when the document gets deleted.
+ RefPtr<Document> protector(cachedResourceLoader->doc());
if (!request->isMultipart())
- docLoader->decrementRequestCount(request->cachedResource());
+ cachedResourceLoader->decrementRequestCount(request->cachedResource());
CachedResource* resource = request->cachedResource();
@@ -453,17 +453,17 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
cache()->revalidationFailed(resource);
if (!cancelled) {
- docLoader->setLoadInProgress(true);
+ cachedResourceLoader->setLoadInProgress(true);
resource->error();
}
- docLoader->setLoadInProgress(false);
+ cachedResourceLoader->setLoadInProgress(false);
if (cancelled || !resource->isPreloaded())
cache()->remove(resource);
delete request;
- docLoader->checkForPendingPreloads();
+ cachedResourceLoader->checkForPendingPreloads();
servePendingRequests();
}
@@ -490,13 +490,13 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR
// 304 Not modified / Use local copy
m_requestsLoading.remove(loader);
loader->clearClient();
- request->docLoader()->decrementRequestCount(request->cachedResource());
+ request->cachedResourceLoader()->decrementRequestCount(request->cachedResource());
// Existing resource is ok, just use it updating the expiration time.
cache()->revalidationSucceeded(resource, response);
- if (request->docLoader()->frame())
- request->docLoader()->frame()->loader()->checkCompleted();
+ if (request->cachedResourceLoader()->frame())
+ request->cachedResourceLoader()->frame()->loader()->checkCompleted();
delete request;
@@ -516,13 +516,13 @@ void Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceR
if (request->isMultipart()) {
ASSERT(resource->isImage());
static_cast<CachedImage*>(resource)->clear();
- if (request->docLoader()->frame())
- request->docLoader()->frame()->loader()->checkCompleted();
+ if (request->cachedResourceLoader()->frame())
+ request->cachedResourceLoader()->frame()->loader()->checkCompleted();
} else if (response.isMultipart()) {
request->setIsMultipart(true);
- // We don't count multiParts in a DocLoader's request count
- request->docLoader()->decrementRequestCount(request->cachedResource());
+ // We don't count multiParts in a CachedResourceLoader's request count
+ request->cachedResourceLoader()->decrementRequestCount(request->cachedResource());
// If we get a multipart response, we must have a handle
ASSERT(loader->handle());
@@ -574,15 +574,15 @@ void Loader::Host::didReceiveCachedMetadata(SubresourceLoader* loader, const cha
resource->setSerializedCachedMetadata(data, size);
}
-void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, DocLoader* docLoader)
+void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, CachedResourceLoader* cachedResourceLoader)
{
RequestQueue remaining;
RequestQueue::iterator end = requestsPending.end();
for (RequestQueue::iterator it = requestsPending.begin(); it != end; ++it) {
Request* request = *it;
- if (request->docLoader() == docLoader) {
+ if (request->cachedResourceLoader() == cachedResourceLoader) {
cache()->remove(request->cachedResource());
- docLoader->decrementRequestCount(request->cachedResource());
+ cachedResourceLoader->decrementRequestCount(request->cachedResource());
delete request;
} else
remaining.append(request);
@@ -590,17 +590,17 @@ void Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, DocLoade
requestsPending.swap(remaining);
}
-void Loader::Host::cancelRequests(DocLoader* docLoader)
+void Loader::Host::cancelRequests(CachedResourceLoader* cachedResourceLoader)
{
for (unsigned p = 0; p <= High; p++)
- cancelPendingRequests(m_requestsPending[p], docLoader);
+ cancelPendingRequests(m_requestsPending[p], cachedResourceLoader);
Vector<SubresourceLoader*, 256> loadersToCancel;
RequestMap::iterator end = m_requestsLoading.end();
for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) {
Request* r = i->second;
- if (r->docLoader() == docLoader)
+ if (r->cachedResourceLoader() == cachedResourceLoader)
loadersToCancel.append(i->first.get());
}
diff --git a/WebCore/loader/loader.h b/WebCore/loader/loader.h
index 52c61aa..4d353e0 100644
--- a/WebCore/loader/loader.h
+++ b/WebCore/loader/loader.h
@@ -35,7 +35,7 @@
namespace WebCore {
class CachedResource;
- class DocLoader;
+ class CachedResourceLoader;
class KURL;
class Request;
@@ -44,9 +44,9 @@ namespace WebCore {
Loader();
~Loader();
- void load(DocLoader*, CachedResource*, bool incremental = true, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true);
+ void load(CachedResourceLoader*, CachedResource*, bool incremental = true, SecurityCheckPolicy = DoSecurityCheck, bool sendResourceLoadCallbacks = true);
- void cancelRequests(DocLoader*);
+ void cancelRequests(CachedResourceLoader*);
enum Priority { VeryLow, Low, Medium, High };
void servePendingRequests(Priority minimumPriority = VeryLow);
@@ -77,7 +77,7 @@ namespace WebCore {
void nonCacheRequestInFlight();
void nonCacheRequestComplete();
void servePendingRequests(Priority minimumPriority = VeryLow);
- void cancelRequests(DocLoader*);
+ void cancelRequests(CachedResourceLoader*);
bool hasRequests() const;
bool processingResource() const { return m_numResourcesProcessing != 0 || m_nonCachedRequestsInFlight !=0; }
@@ -94,7 +94,7 @@ namespace WebCore {
typedef Deque<Request*> RequestQueue;
void servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority);
void didFail(SubresourceLoader*, bool cancelled = false);
- void cancelPendingRequests(RequestQueue& requestsPending, DocLoader*);
+ void cancelPendingRequests(RequestQueue& requestsPending, CachedResourceLoader*);
RequestQueue m_requestsPending[High + 1];
typedef HashMap<RefPtr<SubresourceLoader>, Request*> RequestMap;
diff --git a/WebCore/manual-tests/transition-accelerated.html b/WebCore/manual-tests/transition-accelerated.html
new file mode 100644
index 0000000..a898c29
--- /dev/null
+++ b/WebCore/manual-tests/transition-accelerated.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style type="text/css" media="screen">
+ .box {
+ position: relative;
+ height: 100px;
+ width: 100px;
+ margin: 10px;
+ background-color: blue;
+ }
+
+ .slow {
+ -webkit-animation: slow 2s infinite linear alternate;
+ }
+
+ .fast {
+ -webkit-animation: fast 2s infinite linear alternate;
+ }
+
+ @-webkit-keyframes slow {
+ from {
+ left: 0px;
+ }
+ to {
+ left: 400px;
+ }
+ }
+
+ @-webkit-keyframes fast {
+ from {
+ -webkit-transform: translateX(0);
+ }
+ to {
+ -webkit-transform: translateX(400px);
+ }
+ }
+ </style>
+</head>
+<body>
+ <p>The lower box should animate more smoothly than the upper one (on Mac).</p>
+ <div class="box slow"></div>
+ <div class="box fast"></div>
+</body>
+</html>
diff --git a/WebCore/mathml/RenderMathMLOperator.cpp b/WebCore/mathml/RenderMathMLOperator.cpp
index f9ff630..a6778a9 100644
--- a/WebCore/mathml/RenderMathMLOperator.cpp
+++ b/WebCore/mathml/RenderMathMLOperator.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,7 +48,7 @@ RenderMathMLOperator::RenderMathMLOperator(Node* container)
RenderMathMLOperator::RenderMathMLOperator(Node* container, UChar operatorChar)
: RenderMathMLBlock(container)
, m_stretchHeight(0)
- , m_operator(operatorChar)
+ , m_operator(convertHyphenMinusToMinusSign(operatorChar))
{
}
@@ -217,7 +218,7 @@ void RenderMathMLOperator::updateFromElement()
text = new (renderArena()) RenderText(node(), StringImpl::create(&m_operator, 1));
else if (node()->nodeType() == Node::ELEMENT_NODE)
if (Element* mo = static_cast<Element*>(node()))
- text = new (renderArena()) RenderText(node(), StringImpl::create(mo->textContent().characters(), mo->textContent().length()));
+ text = new (renderArena()) RenderText(node(), mo->textContent().replace(hyphenMinus, minusSign).impl());
// If we can't figure out the text, leave it blank.
if (text) {
RefPtr<RenderStyle> textStyle = RenderStyle::create();
diff --git a/WebCore/mathml/RenderMathMLOperator.h b/WebCore/mathml/RenderMathMLOperator.h
index cc183c3..99c5246 100644
--- a/WebCore/mathml/RenderMathMLOperator.h
+++ b/WebCore/mathml/RenderMathMLOperator.h
@@ -28,6 +28,7 @@
#if ENABLE(MATHML)
+#include "CharacterNames.h"
#include "RenderMathMLBlock.h"
namespace WebCore {
@@ -65,9 +66,17 @@ inline const RenderMathMLOperator* toRenderMathMLOperator(const RenderMathMLBloc
ASSERT(!block || block->isRenderMathMLOperator());
return static_cast<const RenderMathMLOperator*>(block);
}
+
+inline UChar convertHyphenMinusToMinusSign(UChar glyph)
+{
+ // When rendered as a mathematical operator, minus glyph should be larger.
+ if (glyph == hyphenMinus)
+ return minusSign;
+ return glyph;
}
+}
#endif // ENABLE(MATHML)
#endif // RenderMathMLOperator_h
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 224c8dc..f0aff33 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -57,6 +57,7 @@ namespace WebCore {
class Node;
class Page;
class SecurityOrigin;
+ class SharedGraphicsContext3D;
class PopupMenuClient;
class Widget;
@@ -230,6 +231,8 @@ namespace WebCore {
virtual bool allowsAcceleratedCompositing() const { return true; }
#endif
+ virtual SharedGraphicsContext3D* getSharedGraphicsContext3D() { return 0; }
+
virtual bool supportsFullscreenForNode(const Node*) { return false; }
virtual void enterFullscreenForNode(Node*) { }
virtual void exitFullscreenForNode(Node*) { }
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index d384b02..4ce17bd 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -226,7 +226,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
break;
#endif
case ContextMenuItemTagSpellingGuess:
- ASSERT(frame->selectedText().length());
+ ASSERT(frame->editor()->selectedText().length());
if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) {
Document* document = frame->document();
RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), true, false, true);
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index a3d8090..eeb57c4 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -60,7 +60,6 @@
#include "History.h"
#include "IDBFactory.h"
#include "IDBFactoryBackendInterface.h"
-#include "IDBKeyRange.h"
#include "InspectorController.h"
#include "InspectorTimelineAgent.h"
#include "KURL.h"
@@ -498,7 +497,6 @@ void DOMWindow::clear()
#if ENABLE(INDEXED_DATABASE)
m_idbFactory = 0;
- m_idbKeyRange = 0;
#endif
}
@@ -720,14 +718,6 @@ IDBFactory* DOMWindow::indexedDB() const
m_idbFactory = IDBFactory::create(page->group().idbFactory());
return m_idbFactory.get();
}
-
-IDBKeyRange* DOMWindow::iDBKeyRange() const
-{
- if (!m_idbKeyRange)
- m_idbKeyRange = IDBKeyRange::create(0, 0, 0);
-
- return m_idbKeyRange.get();
-}
#endif
#if ENABLE(FILE_SYSTEM)
@@ -1022,7 +1012,7 @@ bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, b
return false;
// FIXME (13016): Support wholeWord, searchInFrames and showDialog
- return m_frame->findString(string, !backwards, caseSensitive, wrap, false);
+ return m_frame->editor()->findString(string, !backwards, caseSensitive, wrap, false);
}
bool DOMWindow::offscreenBuffering() const
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 894aa08..1470628 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -57,7 +57,6 @@ namespace WebCore {
class Frame;
class History;
class IDBFactory;
- class IDBKeyRange;
class InspectorTimelineAgent;
class LocalFileSystem;
class Location;
@@ -238,7 +237,6 @@ namespace WebCore {
#if ENABLE(INDEXED_DATABASE)
IDBFactory* indexedDB() const;
- IDBKeyRange* iDBKeyRange() const;
#endif
#if ENABLE(FILE_SYSTEM)
@@ -445,7 +443,6 @@ namespace WebCore {
#endif
#if ENABLE(INDEXED_DATABASE)
mutable RefPtr<IDBFactory> m_idbFactory;
- mutable RefPtr<IDBKeyRange> m_idbKeyRange;
#endif
#if ENABLE(FILE_SYSTEM)
RefPtr<LocalFileSystem> m_localFileSystem;
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index 35b847c..29d12cc 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -44,7 +44,7 @@ module window {
LegacyParent=JSDOMWindowBase
] DOMWindow {
// DOM Level 0
- readonly attribute Screen screen;
+ attribute [Replaceable] Screen screen;
readonly attribute [DoNotCheckDomainSecurity, JSCCustomGetter] History history;
attribute [Replaceable] BarInfo locationbar;
attribute [Replaceable] BarInfo menubar;
@@ -174,7 +174,20 @@ module window {
#endif
#if defined(ENABLE_INDEXED_DATABASE) && ENABLE_INDEXED_DATABASE
readonly attribute [EnabledAtRuntime] IDBFactory indexedDB;
- readonly attribute [EnabledAtRuntime] IDBKeyRange IDBKeyRange;
+
+ attribute [EnabledAtRuntime] IDBCursorConstructor IDBCursor;
+ attribute [EnabledAtRuntime] IDBDatabaseConstructor IDBDatabase;
+ attribute [EnabledAtRuntime] IDBDatabaseErrorConstructor IDBDatabaseError;
+ attribute [EnabledAtRuntime] IDBDatabaseExceptionConstructor IDBDatabaseException;
+ attribute [EnabledAtRuntime] IDBErrorEventConstructor IDBErrorEvent;
+ attribute [EnabledAtRuntime] IDBEventConstructor IDBEvent;
+ attribute [EnabledAtRuntime] IDBFactoryConstructor IDBFactory;
+ attribute [EnabledAtRuntime] IDBIndexConstructor IDBIndex;
+ attribute [EnabledAtRuntime] IDBKeyRangeConstructor IDBKeyRange;
+ attribute [EnabledAtRuntime] IDBObjectStoreConstructor IDBObjectStore;
+ attribute [EnabledAtRuntime] IDBRequestConstructor IDBRequest;
+ attribute [EnabledAtRuntime] IDBSuccessEventConstructor IDBSuccessEvent;
+ attribute [EnabledAtRuntime] IDBTransactionConstructor IDBTransaction;
#endif
#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM
const unsigned short TEMPORARY = 0;
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index bbf4fed..c623bf6 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -30,7 +30,7 @@
#include "CSSStyleDeclaration.h"
#include "Clipboard.h"
#include "ClipboardAccessPolicy.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DragActions.h"
@@ -440,13 +440,13 @@ bool DragController::concludeEditDrag(DragData* dragData)
// manually controlling drag behaviour
if (!range)
return false;
- DocLoader* loader = range->ownerDocument()->docLoader();
- loader->setAllowStaleResources(true);
+ CachedResourceLoader* cachedResourceLoader = range->ownerDocument()->cachedResourceLoader();
+ cachedResourceLoader->setAllowStaleResources(true);
if (dragIsMove(innerFrame->selection()) || dragCaret.isContentRichlyEditable()) {
bool chosePlainText = false;
RefPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, range, true, chosePlainText);
if (!fragment || !innerFrame->editor()->shouldInsertFragment(fragment, range, EditorInsertActionDropped)) {
- loader->setAllowStaleResources(false);
+ cachedResourceLoader->setAllowStaleResources(false);
return false;
}
@@ -464,7 +464,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
} else {
String text = dragData->asPlainText();
if (text.isEmpty() || !innerFrame->editor()->shouldInsertText(text, range.get(), EditorInsertActionDropped)) {
- loader->setAllowStaleResources(false);
+ cachedResourceLoader->setAllowStaleResources(false);
return false;
}
@@ -472,7 +472,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point))
applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), createFragmentFromText(range.get(), text), true, false, true));
}
- loader->setAllowStaleResources(false);
+ cachedResourceLoader->setAllowStaleResources(false);
return true;
}
@@ -741,7 +741,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
if (!clipboard->hasData()) {
if (isNodeInTextFormControl(src->selection()->start().node()))
- clipboard->writePlainText(src->selectedText());
+ clipboard->writePlainText(src->editor()->selectedText());
else {
RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
ASSERT(selectionRange);
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 72cbe23..1464de6 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -2080,7 +2080,7 @@ bool EventHandler::sendContextMenuEventForKey()
if (start.node() && (selectionController->rootEditableElement() || selectionController->isRange())) {
RefPtr<Range> selection = selectionController->toNormalizedRange();
- IntRect firstRect = m_frame->firstRectForRange(selection.get());
+ IntRect firstRect = m_frame->editor()->firstRectForRange(selection.get());
int x = rightAligned ? firstRect.right() : firstRect.x();
location = IntPoint(x, firstRect.bottom());
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index a87d6a6..aeb4fa0 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -110,7 +110,7 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
m_isChangingFocusedFrame = false;
}
-Frame* FocusController::focusedOrMainFrame()
+Frame* FocusController::focusedOrMainFrame() const
{
if (Frame* frame = focusedFrame())
return frame;
diff --git a/WebCore/page/FocusController.h b/WebCore/page/FocusController.h
index 4410833..050a08f 100644
--- a/WebCore/page/FocusController.h
+++ b/WebCore/page/FocusController.h
@@ -46,7 +46,7 @@ public:
void setFocusedFrame(PassRefPtr<Frame>);
Frame* focusedFrame() const { return m_focusedFrame.get(); }
- Frame* focusedOrMainFrame();
+ Frame* focusedOrMainFrame() const;
bool setInitialFocus(FocusDirection, KeyboardEvent*);
bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 09cb8c3..3a03e9b 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -38,7 +38,7 @@
#include "Chrome.h"
#include "ChromeClient.h"
#include "DOMWindow.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "DocumentType.h"
#include "EditingText.h"
#include "EditorClient.h"
@@ -148,7 +148,6 @@ inline Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoader
#if ENABLE(ORIENTATION_EVENTS)
, m_orientation(0)
#endif
- , m_highlightTextMatches(false)
, m_inViewSourceMode(false)
, m_isDisconnected(false)
, m_excludeFromTextSearch(false)
@@ -291,58 +290,6 @@ Settings* Frame::settings() const
return m_page ? m_page->settings() : 0;
}
-String Frame::selectedText() const
-{
- return plainText(selection()->toNormalizedRange().get());
-}
-
-IntRect Frame::firstRectForRange(Range* range) const
-{
- int extraWidthToEndOfLine = 0;
- ASSERT(range->startContainer());
- ASSERT(range->endContainer());
-
- InlineBox* startInlineBox;
- int startCaretOffset;
- Position startPosition = VisiblePosition(range->startPosition()).deepEquivalent();
- if (startPosition.isNull())
- return IntRect();
- startPosition.getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
-
- RenderObject* startRenderer = startPosition.node()->renderer();
- ASSERT(startRenderer);
- IntRect startCaretRect = startRenderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
- if (startCaretRect != IntRect())
- startCaretRect = startRenderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();
-
- InlineBox* endInlineBox;
- int endCaretOffset;
- Position endPosition = VisiblePosition(range->endPosition()).deepEquivalent();
- if (endPosition.isNull())
- return IntRect();
- endPosition.getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
-
- RenderObject* endRenderer = endPosition.node()->renderer();
- ASSERT(endRenderer);
- IntRect endCaretRect = endRenderer->localCaretRect(endInlineBox, endCaretOffset);
- if (endCaretRect != IntRect())
- endCaretRect = endRenderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();
-
- if (startCaretRect.y() == endCaretRect.y()) {
- // start and end are on the same line
- return IntRect(min(startCaretRect.x(), endCaretRect.x()),
- startCaretRect.y(),
- abs(endCaretRect.x() - startCaretRect.x()),
- max(startCaretRect.height(), endCaretRect.height()));
- }
-
- // start and end aren't on the same line, so go from start to the end of its line
- return IntRect(startCaretRect.x(),
- startCaretRect.y(),
- startCaretRect.width() + extraWidthToEndOfLine,
- startCaretRect.height());
-}
-
TextGranularity Frame::selectionGranularity() const
{
return m_selectionController.granularity();
@@ -668,17 +615,6 @@ void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVe
}
}
-bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
-{
- return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
-}
-
-bool Frame::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
-{
- return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(),
- affinity, stillSelecting);
-}
-
bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const
{
return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
@@ -696,157 +632,6 @@ void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
m_typingStyle = style;
}
-void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
-{
- if (!style || !style->length()) {
- clearTypingStyle();
- return;
- }
-
- // Calculate the current typing style.
- RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
- if (typingStyle()) {
- typingStyle()->merge(mutableStyle.get());
- mutableStyle = typingStyle();
- }
-
- RefPtr<CSSValue> unicodeBidi;
- RefPtr<CSSValue> direction;
- if (editingAction == EditActionSetWritingDirection) {
- unicodeBidi = mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
- direction = mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
- }
-
- Node* node = selection()->selection().visibleStart().deepEquivalent().node();
- computedStyle(node)->diff(mutableStyle.get());
-
- if (editingAction == EditActionSetWritingDirection && unicodeBidi) {
- ASSERT(unicodeBidi->isPrimitiveValue());
- mutableStyle->setProperty(CSSPropertyUnicodeBidi, static_cast<CSSPrimitiveValue*>(unicodeBidi.get())->getIdent());
- if (direction) {
- ASSERT(direction->isPrimitiveValue());
- mutableStyle->setProperty(CSSPropertyDirection, static_cast<CSSPrimitiveValue*>(direction.get())->getIdent());
- }
- }
-
- // Handle block styles, substracting these from the typing style.
- RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
- blockStyle->diff(mutableStyle.get());
- if (blockStyle->length() > 0)
- applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
-
- // Set the remaining style as the typing style.
- m_typingStyle = mutableStyle.release();
-}
-
-PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nodeToRemove) const
-{
- nodeToRemove = 0;
-
- if (selection()->isNone())
- return 0;
-
- RefPtr<Range> range(selection()->toNormalizedRange());
- Position pos = range->editingStartPosition();
-
- Element *elem = pos.element();
- if (!elem)
- return 0;
-
- RefPtr<Element> styleElement = elem;
- ExceptionCode ec = 0;
-
- if (m_typingStyle) {
- styleElement = document()->createElement(spanTag, false);
-
- styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec);
- ASSERT(!ec);
-
- styleElement->appendChild(document()->createEditingTextNode(""), ec);
- ASSERT(!ec);
-
- if (elem->renderer() && elem->renderer()->canHaveChildren()) {
- elem->appendChild(styleElement, ec);
- } else {
- Node *parent = elem->parent();
- Node *next = elem->nextSibling();
-
- if (next)
- parent->insertBefore(styleElement, next, ec);
- else
- parent->appendChild(styleElement, ec);
- }
- ASSERT(!ec);
-
- nodeToRemove = styleElement.get();
- }
-
- return computedStyle(styleElement.release());
-}
-
-void Frame::textFieldDidBeginEditing(Element* e)
-{
- if (editor()->client())
- editor()->client()->textFieldDidBeginEditing(e);
-}
-
-void Frame::textFieldDidEndEditing(Element* e)
-{
- if (editor()->client())
- editor()->client()->textFieldDidEndEditing(e);
-}
-
-void Frame::textDidChangeInTextField(Element* e)
-{
- if (editor()->client())
- editor()->client()->textDidChangeInTextField(e);
-}
-
-bool Frame::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
-{
- if (editor()->client())
- return editor()->client()->doTextFieldCommandFromEvent(e, ke);
-
- return false;
-}
-
-void Frame::textWillBeDeletedInTextField(Element* input)
-{
- if (editor()->client())
- editor()->client()->textWillBeDeletedInTextField(input);
-}
-
-void Frame::textDidChangeInTextArea(Element* e)
-{
- if (editor()->client())
- editor()->client()->textDidChangeInTextArea(e);
-}
-
-void Frame::applyEditingStyleToBodyElement() const
-{
- RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
- unsigned len = list->length();
- for (unsigned i = 0; i < len; i++)
- applyEditingStyleToElement(static_cast<Element*>(list->item(i)));
-}
-
-void Frame::applyEditingStyleToElement(Element* element) const
-{
- if (!element)
- return;
-
- CSSStyleDeclaration* style = element->style();
- ASSERT(style);
-
- ExceptionCode ec = 0;
- style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);
- ASSERT(!ec);
- style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);
- ASSERT(!ec);
- style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
- ASSERT(!ec);
-}
-
#ifndef NDEBUG
static HashSet<Frame*>& keepAliveSet()
{
@@ -1072,40 +857,6 @@ void Frame::clearTimers()
clearTimers(m_view.get(), document());
}
-RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
-{
- nodeToRemove = 0;
-
- if (selection()->isNone())
- return 0;
-
- Position pos = selection()->selection().visibleStart().deepEquivalent();
- if (!pos.isCandidate())
- return 0;
- Node *node = pos.node();
- if (!node)
- return 0;
-
- if (!m_typingStyle)
- return node->renderer()->style();
-
- RefPtr<Element> styleElement = document()->createElement(spanTag, false);
-
- ExceptionCode ec = 0;
- String styleText = m_typingStyle->cssText() + " display: inline";
- styleElement->setAttribute(styleAttr, styleText.impl(), ec);
- ASSERT(!ec);
-
- styleElement->appendChild(document()->createEditingTextNode(""), ec);
- ASSERT(!ec);
-
- node->parentNode()->appendChild(styleElement, ec);
- ASSERT(!ec);
-
- nodeToRemove = styleElement.get();
- return styleElement->renderer() ? styleElement->renderer()->style() : 0;
-}
-
void Frame::setSelectionFromNone()
{
// Put a caret inside the body if the entire frame is editable (either the
@@ -1122,160 +873,6 @@ void Frame::setSelectionFromNone()
selection()->setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM));
}
-// Searches from the beginning of the document if nothing is selected.
-bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
-{
- if (target.isEmpty())
- return false;
-
- if (excludeFromTextSearch())
- return false;
-
- // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
- // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
- RefPtr<Range> searchRange(rangeOfContents(document()));
- VisibleSelection selection = this->selection()->selection();
-
- if (forward)
- setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
- else
- setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
-
- Node* shadowTreeRoot = selection.shadowTreeRootNode();
- if (shadowTreeRoot) {
- ExceptionCode ec = 0;
- if (forward)
- searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
- else
- searchRange->setStart(shadowTreeRoot, 0, ec);
- }
-
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
- // If we started in the selection and the found range exactly matches the existing selection, find again.
- // Build a selection with the found range to remove collapsed whitespace.
- // Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInSelection && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), selection.toNormalizedRange().get())) {
- searchRange = rangeOfContents(document());
- if (forward)
- setStart(searchRange.get(), selection.visibleEnd());
- else
- setEnd(searchRange.get(), selection.visibleStart());
-
- if (shadowTreeRoot) {
- ExceptionCode ec = 0;
- if (forward)
- searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
- else
- searchRange->setStart(shadowTreeRoot, 0, ec);
- }
-
- resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
- }
-
- ExceptionCode exception = 0;
-
- // If nothing was found in the shadow tree, search in main content following the shadow tree.
- if (resultRange->collapsed(exception) && shadowTreeRoot) {
- searchRange = rangeOfContents(document());
- if (forward)
- searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception);
- else
- searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
-
- resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
- }
-
- if (!editor()->insideVisibleArea(resultRange.get())) {
- resultRange = editor()->nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
- if (!resultRange)
- return false;
- }
-
- // If we didn't find anything and we're wrapping, search again in the entire document (this will
- // redundantly re-search the area already searched in some cases).
- if (resultRange->collapsed(exception) && wrapFlag) {
- searchRange = rangeOfContents(document());
- resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
- // We used to return false here if we ended up with the same range that we started with
- // (e.g., the selection was already the only instance of this text). But we decided that
- // this should be a success case instead, so we'll just fall through in that case.
- }
-
- if (resultRange->collapsed(exception))
- return false;
-
- this->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
- revealSelection();
- return true;
-}
-
-unsigned Frame::countMatchesForText(const String& target, bool caseFlag, unsigned limit, bool markMatches)
-{
- if (target.isEmpty())
- return 0;
-
- RefPtr<Range> searchRange(rangeOfContents(document()));
-
- ExceptionCode exception = 0;
- unsigned matchCount = 0;
- do {
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
- if (resultRange->collapsed(exception)) {
- if (!resultRange->startContainer()->isInShadowTree())
- break;
-
- searchRange = rangeOfContents(document());
- searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception);
- continue;
- }
-
- // Only treat the result as a match if it is visible
- if (editor()->insideVisibleArea(resultRange.get())) {
- ++matchCount;
- if (markMatches)
- document()->markers()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
- }
-
- // Stop looking if we hit the specified limit. A limit of 0 means no limit.
- if (limit > 0 && matchCount >= limit)
- break;
-
- // Set the new start for the search range to be the end of the previous
- // result range. There is no need to use a VisiblePosition here,
- // since findPlainText will use a TextIterator to go over the visible
- // text nodes.
- searchRange->setStart(resultRange->endContainer(exception), resultRange->endOffset(exception), exception);
-
- Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
- if (searchRange->collapsed(exception) && shadowTreeRoot)
- searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
- } while (true);
-
- if (markMatches) {
- // Do a "fake" paint in order to execute the code that computes the rendered rect for each text match.
- if (m_view && contentRenderer()) {
- document()->updateLayout(); // Ensure layout is up to date.
- IntRect visibleRect = m_view->visibleContentRect();
- if (!visibleRect.isEmpty()) {
- GraphicsContext context((PlatformGraphicsContext*)0);
- context.setPaintingDisabled(true);
- m_view->paintContents(&context, visibleRect);
- }
- }
- }
-
- return matchCount;
-}
-
-void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
-{
- if (flag == m_highlightTextMatches)
- return;
-
- m_highlightTextMatches = flag;
- document()->markers()->repaintMarkers(DocumentMarker::TextMatch);
-}
-
void Frame::setDOMWindow(DOMWindow* domWindow)
{
if (m_domWindow) {
@@ -1386,53 +983,9 @@ String Frame::documentTypeString() const
return String();
}
-void Frame::respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping)
+bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
{
- bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled();
- bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled();
- if (isContinuousSpellCheckingEnabled) {
- VisibleSelection newAdjacentWords;
- VisibleSelection newSelectedSentence;
- bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
- if (selection()->selection().isContentEditable() || caretBrowsing) {
- VisiblePosition newStart(selection()->selection().visibleStart());
- newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
- if (isContinuousGrammarCheckingEnabled)
- newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
- }
-
- // When typing we check spelling elsewhere, so don't redo it here.
- // If this is a change in selection resulting from a delete operation,
- // oldSelection may no longer be in the document.
- if (closeTyping && oldSelection.isContentEditable() && oldSelection.start().node() && oldSelection.start().node()->inDocument()) {
- VisiblePosition oldStart(oldSelection.visibleStart());
- VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
- if (oldAdjacentWords != newAdjacentWords) {
- if (isContinuousGrammarCheckingEnabled) {
- VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
- editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence);
- } else
- editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
- }
- }
-
- // This only erases markers that are in the first unit (word or sentence) of the selection.
- // Perhaps peculiar, but it matches AppKit.
- if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange()) {
- document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
- document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Replacement);
- }
- if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
- document()->markers()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
- }
-
- // When continuous spell checking is off, existing markers disappear after the selection changes.
- if (!isContinuousSpellCheckingEnabled)
- document()->markers()->removeMarkers(DocumentMarker::Spelling);
- if (!isContinuousGrammarCheckingEnabled)
- document()->markers()->removeMarkers(DocumentMarker::Grammar);
-
- editor()->respondToChangedSelection(oldSelection);
+ return editor()->shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
}
VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index eb3cdba..1e6b9b6 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -37,7 +37,6 @@
#include "FrameTree.h"
#include "ScriptController.h"
#include "ScrollBehavior.h"
-#include "SelectionController.h"
#include "UserScriptTypes.h"
#include "ZoomMode.h"
@@ -52,10 +51,8 @@
#if PLATFORM(MAC)
#ifndef __OBJC__
class NSArray;
-class NSDictionary;
class NSMutableDictionary;
class NSString;
-typedef int NSWritingDirection;
#endif
#endif
@@ -176,49 +173,17 @@ namespace WebCore {
}
#if ENABLE(TILED_BACKING_STORE)
+ // FIXME: This should be in FrameView, not Frame.
TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
void setTiledBackingStoreEnabled(bool);
#endif
- private:
- void lifeSupportTimerFired(Timer<Frame>*);
-
- // === to be moved into Editor
-
- public:
- String selectedText() const;
- bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
-
- const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
- void setMark(const VisibleSelection&);
-
- void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
- void applyEditingStyleToBodyElement() const;
- void applyEditingStyleToElement(Element*) const;
-
- IntRect firstRectForRange(Range*) const;
-
- void respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping);
- bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
-
- RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
-
- unsigned countMatchesForText(const String&, bool caseFlag, unsigned limit, bool markMatches);
- bool markedTextMatchesAreHighlighted() const;
- void setMarkedTextMatchesAreHighlighted(bool flag);
-
- PassRefPtr<CSSComputedStyleDeclaration> selectionComputedStyle(Node*& nodeToRemove) const;
-
- void textFieldDidBeginEditing(Element*);
- void textFieldDidEndEditing(Element*);
- void textDidChangeInTextField(Element*);
- bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
- void textWillBeDeletedInTextField(Element* input);
- void textDidChangeInTextArea(Element*);
-
DragImageRef nodeImage(Node*);
DragImageRef dragImageForSelection();
+ private:
+ void lifeSupportTimerFired(Timer<Frame>*);
+
// === to be moved into SelectionController
public:
@@ -256,6 +221,7 @@ namespace WebCore {
Document* documentAtPoint(const IntPoint& windowPoint);
#if ENABLE(TILED_BACKING_STORE)
+ // FIXME: This should be in FrameView, not Frame.
private:
// TiledBackingStoreClient interface
@@ -281,16 +247,8 @@ namespace WebCore {
NSImage* selectionImage(bool forceBlackText = false) const;
NSImage* snapshotDragImage(Node*, NSRect* imageRect, NSRect* elementRect) const;
-
- private:
NSImage* imageFromRect(NSRect) const;
- // === to be moved into Editor
-
- public:
- NSDictionary* fontAttributesForSelectionStart() const;
- NSWritingDirection baseWritingDirectionForSelectionStart() const;
-
#endif
private:
@@ -308,7 +266,6 @@ namespace WebCore {
ScriptController m_script;
- mutable VisibleSelection m_mark;
mutable Editor m_editor;
mutable SelectionController m_selectionController;
mutable EventHandler m_eventHandler;
@@ -322,7 +279,6 @@ namespace WebCore {
int m_orientation;
#endif
- bool m_highlightTextMatches;
bool m_inViewSourceMode;
bool m_isDisconnected;
bool m_excludeFromTextSearch;
@@ -377,21 +333,6 @@ namespace WebCore {
return &m_animationController;
}
- inline const VisibleSelection& Frame::mark() const
- {
- return m_mark;
- }
-
- inline void Frame::setMark(const VisibleSelection& s)
- {
- ASSERT(!s.base().node() || s.base().node()->document() == document());
- ASSERT(!s.extent().node() || s.extent().node()->document() == document());
- ASSERT(!s.start().node() || s.start().node()->document() == document());
- ASSERT(!s.end().node() || s.end().node()->document() == document());
-
- m_mark = s;
- }
-
inline CSSMutableStyleDeclaration* Frame::typingStyle() const
{
return m_typingStyle.get();
@@ -437,11 +378,6 @@ namespace WebCore {
m_inViewSourceMode = mode;
}
- inline bool Frame::markedTextMatchesAreHighlighted() const
- {
- return m_highlightTextMatches;
- }
-
inline FrameTree* Frame::tree() const
{
return &m_treeNode;
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index ac9341f..a808ab6 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -31,7 +31,7 @@
#include "CSSStyleSelector.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "EventHandler.h"
#include "FloatRect.h"
#include "FocusController.h"
@@ -44,6 +44,7 @@
#include "HTMLFrameElement.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
+#include "HTMLPlugInImageElement.h"
#include "InspectorTimelineAgent.h"
#include "OverflowEvent.h"
#include "RenderEmbeddedObject.h"
@@ -1300,7 +1301,7 @@ void FrameView::checkStopDelayingDeferredRepaints()
return;
Document* document = m_frame->document();
- if (document && (document->parsing() || document->docLoader()->requestCount()))
+ if (document && (document->parsing() || document->cachedResourceLoader()->requestCount()))
return;
m_deferredRepaintTimer.stop();
@@ -1335,7 +1336,7 @@ void FrameView::doDeferredRepaints()
void FrameView::updateDeferredRepaintDelay()
{
Document* document = m_frame->document();
- if (!document || (!document->parsing() && !document->docLoader()->requestCount())) {
+ if (!document || (!document->parsing() && !document->cachedResourceLoader()->requestCount())) {
m_deferredRepaintDelay = s_deferredRepaintDelay;
return;
}
@@ -1611,6 +1612,37 @@ void FrameView::scrollToAnchor()
m_maintainScrollPositionAnchor = anchorNode;
}
+void FrameView::updateWidget(RenderEmbeddedObject* object)
+{
+ ASSERT(!object->node() || object->node()->isElementNode());
+ Element* ownerElement = static_cast<Element*>(object->node());
+ // The object may have already been destroyed (thus node cleared),
+ // but FrameView holds a manual ref, so it won't have been deleted.
+ ASSERT(m_widgetUpdateSet->contains(object));
+ if (!ownerElement)
+ return;
+
+ // No need to update if it's already crashed or known to be missing.
+ if (object->pluginCrashedOrWasMissing())
+ return;
+
+ // FIXME: This could turn into a real virtual dispatch if we defined
+ // updateWidget(bool) on HTMLElement.
+ if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag))
+ static_cast<HTMLPlugInImageElement*>(ownerElement)->updateWidget(false);
+ // FIXME: It is not clear that Media elements need or want this updateWidget() call.
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (ownerElement->hasTagName(videoTag) || ownerElement->hasTagName(audioTag))
+ static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(false);
+#endif
+ else
+ ASSERT_NOT_REACHED();
+
+ // Caution: it's possible the object was destroyed again, since loading a
+ // plugin may run any arbitrary javascript.
+ object->updateWidgetPosition();
+}
+
bool FrameView::updateWidgets()
{
if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
@@ -1629,11 +1661,7 @@ bool FrameView::updateWidgets()
for (size_t i = 0; i < size; ++i) {
RenderEmbeddedObject* object = objects[i];
-
- // The object may have been destroyed, but our manual ref() keeps the object from being deleted.
- object->updateWidget(false);
- object->updateWidgetPosition();
-
+ updateWidget(object);
m_widgetUpdateSet->remove(object);
}
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 463020a..f9a4bf3 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -280,6 +280,7 @@ private:
double adjustedDeferredRepaintDelay() const;
bool updateWidgets();
+ void updateWidget(RenderEmbeddedObject*);
void scrollToAnchor();
void scrollPositionChanged();
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index b9eea6a..379d3f3 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -514,7 +514,7 @@ bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity,
Frame* frame = focusController()->focusedOrMainFrame();
Frame* startFrame = frame;
do {
- if (frame->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, false, true)) {
+ if (frame->editor()->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, false, true)) {
if (frame != startFrame)
startFrame->selection()->clear();
focusController()->setFocusedFrame(frame);
@@ -526,7 +526,7 @@ bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity,
// Search contents of startFrame, on the other side of the selection that we did earlier.
// We cheat a bit and just research with wrap on
if (shouldWrap && !startFrame->selection()->isNone()) {
- bool found = startFrame->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, true, true);
+ bool found = startFrame->editor()->findString(target, direction == FindDirectionForward, caseSensitivity == TextCaseSensitive, true, true);
focusController()->setFocusedFrame(frame);
return found;
}
@@ -543,8 +543,8 @@ unsigned int Page::markAllMatchesForText(const String& target, TextCaseSensitivi
Frame* frame = mainFrame();
do {
- frame->setMarkedTextMatchesAreHighlighted(shouldHighlight);
- matches += frame->countMatchesForText(target, caseSensitivity == TextCaseSensitive, (limit == 0) ? 0 : (limit - matches), true);
+ frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight);
+ matches += frame->editor()->countMatchesForText(target, caseSensitivity == TextCaseSensitive, limit ? (limit - matches) : 0, true);
frame = incrementFrame(frame, true, false);
} while (frame);
diff --git a/WebCore/page/PageGroupLoadDeferrer.cpp b/WebCore/page/PageGroupLoadDeferrer.cpp
index a01422f..79554cf 100644
--- a/WebCore/page/PageGroupLoadDeferrer.cpp
+++ b/WebCore/page/PageGroupLoadDeferrer.cpp
@@ -39,14 +39,15 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
Page* otherPage = *it;
if ((deferSelf || otherPage != page)) {
- if (!otherPage->defersLoading())
+ if (!otherPage->defersLoading()) {
m_deferredFrames.append(otherPage->mainFrame());
- // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
- // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
- for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- frame->document()->suspendActiveDOMObjects();
- frame->document()->asyncScriptRunner()->suspend();
+ // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
+ // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
+ for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ frame->document()->suspendActiveDOMObjects();
+ frame->document()->asyncScriptRunner()->suspend();
+ }
}
}
}
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index 6edf32a..b44a35e 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -284,7 +284,7 @@ bool SecurityOrigin::isAccessWhiteListed(const SecurityOrigin* targetOrigin) con
return false;
}
-bool SecurityOrigin::canLoad(const KURL& url, const String& referrer, Document* document)
+bool SecurityOrigin::canDisplay(const KURL& url, const String& referrer, Document* document)
{
#if ENABLE(BLOB)
if (url.protocolIs("blob") && document) {
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index 266ade0..132fa5f 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -84,10 +84,11 @@ public:
// drawing an image onto an HTML canvas element with the drawImage API.
bool taintsCanvas(const KURL&) const;
- // Returns true for any non-local URL. If document parameter is supplied,
- // its local load policy dictates, otherwise if referrer is non-empty and
- // represents a local file, then the local load is allowed.
- static bool canLoad(const KURL&, const String& referrer, Document* document);
+ // Returns true if |document| can display content from the given URL (e.g.,
+ // in an iframe or as an image). For example, web sites generally cannot
+ // display content from the user's files system. If |document| is 0,
+ // |referrer| is used to make this determination.
+ static bool canDisplay(const KURL&, const String& referrer, Document* document);
// Returns true if this SecurityOrigin can load local resources, such
// as images, iframes, and style sheets, and can link to local URLs.
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 47e764c..8b3a74c 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -28,7 +28,7 @@
#include "BackForwardList.h"
#include "Database.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Frame.h"
#include "FrameTree.h"
#include "FrameView.h"
@@ -51,7 +51,7 @@ static void setNeedsRecalcStyleInAllFrames(Page* page)
static void setLoadsImagesAutomaticallyInAllFrames(Page* page)
{
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
- frame->document()->docLoader()->setAutoLoadImages(page->settings()->loadsImagesAutomatically());
+ frame->document()->cachedResourceLoader()->setAutoLoadImages(page->settings()->loadsImagesAutomatically());
}
#if USE(SAFARI_THEME)
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index d4926ea..6efed8e 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -70,6 +70,13 @@ static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x
return bezier.solve(t, solveEpsilon(duration));
}
+static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t)
+{
+ if (stepAtStart)
+ return min(1.0, (floor(numSteps * t) + 1) / numSteps);
+ return floor(numSteps * t) / numSteps;
+}
+
static inline int blendFunc(const AnimationBase*, int from, int to, double progress)
{
return int(from + (to - from) * progress);
@@ -1249,18 +1256,20 @@ double AnimationBase::progress(double scale, double offset, const TimingFunction
fractionalTime = (fractionalTime - offset) * scale;
if (!tf)
- tf = &m_animation->timingFunction();
-
- if (tf->type() == LinearTimingFunction)
+ tf = m_animation->timingFunction().get();
+
+ if (tf->isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(tf);
+ return solveCubicBezierFunction(ctf->x1(),
+ ctf->y1(),
+ ctf->x2(),
+ ctf->y2(),
+ fractionalTime, m_animation->duration());
+ } else if (tf->isStepsTimingFunction()) {
+ const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(tf);
+ return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), fractionalTime);
+ } else
return fractionalTime;
-
- // Cubic bezier.
- double result = solveCubicBezierFunction(tf->x1(),
- tf->y1(),
- tf->x2(),
- tf->y2(),
- fractionalTime, m_animation->duration());
- return result;
}
void AnimationBase::getTimeToNextEvent(double& time, bool& isLooping) const
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
index 01ec2f1..df963fb 100644
--- a/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -39,6 +39,8 @@
#include "RenderStyle.h"
#include <wtf/UnusedParam.h>
+using namespace std;
+
namespace WebCore {
KeyframeAnimation::KeyframeAnimation(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compAnim, RenderStyle* unanimatedStyle)
@@ -66,6 +68,8 @@ void KeyframeAnimation::fetchIntervalEndpointsForProperty(int property, const Re
{
// Find the first key
double elapsedTime = getElapsedTime();
+ if (m_animation->duration() && m_animation->iterationCount() != Animation::IterationCountInfinite)
+ elapsedTime = min(elapsedTime, m_animation->duration() * m_animation->iterationCount());
double fractionalTime = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1;
@@ -75,6 +79,8 @@ void KeyframeAnimation::fetchIntervalEndpointsForProperty(int property, const Re
// FIXME: share this code with AnimationBase::progress().
int iteration = static_cast<int>(fractionalTime);
+ if (m_animation->iterationCount() != Animation::IterationCountInfinite)
+ iteration = min(iteration, m_animation->iterationCount() - 1);
fractionalTime -= iteration;
bool reversing = (m_animation->direction() == Animation::AnimationDirectionAlternate) && (iteration & 1);
@@ -127,7 +133,7 @@ void KeyframeAnimation::fetchIntervalEndpointsForProperty(int property, const Re
const TimingFunction* timingFunction = 0;
if (fromStyle->animations() && fromStyle->animations()->size() > 0) {
// We get the timing function from the first animation, because we've synthesized a RenderStyle for each keyframe.
- timingFunction = &(fromStyle->animations()->animation(0)->timingFunction());
+ timingFunction = fromStyle->animations()->animation(0)->timingFunction().get();
}
prog = progress(scale, offset, timingFunction);
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index 0365784..510cb96 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -32,8 +32,6 @@
#import "ColorMac.h"
#import "Cursor.h"
#import "DOMInternal.h"
-#import "DocumentLoader.h"
-#import "EditorClient.h"
#import "Event.h"
#import "FrameLoaderClient.h"
#import "FrameView.h"
@@ -54,7 +52,6 @@
#import "SimpleFontData.h"
#import "WebCoreViewFactory.h"
#import "visible_units.h"
-
#import <Carbon/Carbon.h>
#import <wtf/StdLibExtras.h>
@@ -398,105 +395,6 @@ DragImageRef Frame::nodeImage(Node* node)
return result;
}
-NSDictionary* Frame::fontAttributesForSelectionStart() const
-{
- Node* nodeToRemove;
- RenderStyle* style = styleForSelectionStart(nodeToRemove);
- if (!style)
- return nil;
-
- NSMutableDictionary* result = [NSMutableDictionary dictionary];
-
- if (style->visitedDependentColor(CSSPropertyBackgroundColor).isValid() && style->visitedDependentColor(CSSPropertyBackgroundColor).alpha() != 0)
- [result setObject:nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
-
- if (style->font().primaryFont()->getNSFont())
- [result setObject:style->font().primaryFont()->getNSFont() forKey:NSFontAttributeName];
-
- if (style->visitedDependentColor(CSSPropertyColor).isValid() && style->visitedDependentColor(CSSPropertyColor) != Color::black)
- [result setObject:nsColor(style->visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
-
- const ShadowData* shadow = style->textShadow();
- if (shadow) {
- NSShadow* s = [[NSShadow alloc] init];
- [s setShadowOffset:NSMakeSize(shadow->x(), shadow->y())];
- [s setShadowBlurRadius:shadow->blur()];
- [s setShadowColor:nsColor(shadow->color())];
- [result setObject:s forKey:NSShadowAttributeName];
- }
-
- int decoration = style->textDecorationsInEffect();
- if (decoration & LINE_THROUGH)
- [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName];
-
- int superscriptInt = 0;
- switch (style->verticalAlign()) {
- case BASELINE:
- case BOTTOM:
- case BASELINE_MIDDLE:
- case LENGTH:
- case MIDDLE:
- case TEXT_BOTTOM:
- case TEXT_TOP:
- case TOP:
- break;
- case SUB:
- superscriptInt = -1;
- break;
- case SUPER:
- superscriptInt = 1;
- break;
- }
- if (superscriptInt)
- [result setObject:[NSNumber numberWithInt:superscriptInt] forKey:NSSuperscriptAttributeName];
-
- if (decoration & UNDERLINE)
- [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName];
-
- if (nodeToRemove) {
- ExceptionCode ec = 0;
- nodeToRemove->remove(ec);
- ASSERT(ec == 0);
- }
-
- return result;
-}
-
-NSWritingDirection Frame::baseWritingDirectionForSelectionStart() const
-{
- NSWritingDirection result = NSWritingDirectionLeftToRight;
-
- Position pos = selection()->selection().visibleStart().deepEquivalent();
- Node* node = pos.node();
- if (!node)
- return result;
-
- RenderObject* renderer = node->renderer();
- if (!renderer)
- return result;
-
- if (!renderer->isBlockFlow()) {
- renderer = renderer->containingBlock();
- if (!renderer)
- return result;
- }
-
- RenderStyle* style = renderer->style();
- if (!style)
- return result;
-
- switch (style->direction()) {
- case LTR:
- result = NSWritingDirectionLeftToRight;
- break;
- case RTL:
- result = NSWritingDirectionRightToLeft;
- break;
- }
-
- return result;
-}
-
#if ENABLE(DASHBOARD_SUPPORT)
NSMutableDictionary* Frame::dashboardRegionsDictionary()
{
diff --git a/WebCore/platform/ScrollAnimator.cpp b/WebCore/platform/ScrollAnimator.cpp
new file mode 100644
index 0000000..c863c1d
--- /dev/null
+++ b/WebCore/platform/ScrollAnimator.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollAnimator.h"
+
+#include "ScrollbarClient.h"
+#include <algorithm>
+
+namespace WebCore {
+
+#if !OS(WINDOWS)
+ScrollAnimator* ScrollAnimator::create(ScrollbarClient* client)
+{
+ return new ScrollAnimator(client);
+}
+#endif
+
+ScrollAnimator::ScrollAnimator(ScrollbarClient* client)
+ : m_client(client)
+ , m_currentPosX(0)
+ , m_currentPosY(0)
+{
+}
+
+ScrollAnimator::~ScrollAnimator()
+{
+}
+
+bool ScrollAnimator::scroll(ScrollbarOrientation orientation, ScrollGranularity, float step, float multiplier)
+{
+ float* currentPos = (orientation == HorizontalScrollbar) ? &m_currentPosX : &m_currentPosY;
+ float newPos = std::max(std::min(*currentPos + (step * multiplier), static_cast<float>(m_client->scrollSize(orientation))), 0.0f);
+ if (*currentPos == newPos)
+ return false;
+ *currentPos = newPos;
+ m_client->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
+ return true;
+}
+
+void ScrollAnimator::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+{
+ if (orientation == HorizontalScrollbar)
+ m_currentPosX = pos;
+ else
+ m_currentPosY = pos;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/ScrollAnimator.h b/WebCore/platform/ScrollAnimator.h
new file mode 100644
index 0000000..e674339
--- /dev/null
+++ b/WebCore/platform/ScrollAnimator.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScrollAnimator_h
+#define ScrollAnimator_h
+
+#include "ScrollTypes.h"
+
+namespace WebCore {
+
+class ScrollbarClient;
+
+class ScrollAnimator {
+public:
+ static ScrollAnimator* create(ScrollbarClient*);
+
+ ScrollAnimator(ScrollbarClient* client);
+ virtual ~ScrollAnimator();
+
+ // Computes a scroll destination for the given parameters. Returns false if
+ // already at the destination. Otherwise, starts scrolling towards the
+ // destination and returns true. Scrolling may be immediate or animated.
+ // The base class implementation always scrolls immediately, never animates.
+ virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
+
+ // Stops any animation in the given direction and updates the ScrollAnimator
+ // with the current scroll position. This does not cause a callback to the
+ // ScrollbarClient.
+ virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float);
+
+protected:
+ ScrollbarClient* m_client;
+ float m_currentPosX; // We avoid using a FloatPoint in order to reduce
+ float m_currentPosY; // subclass code complexity.
+};
+
+} // namespace WebCore
+#endif
diff --git a/WebCore/platform/ScrollAnimatorWin.cpp b/WebCore/platform/ScrollAnimatorWin.cpp
new file mode 100644
index 0000000..8b7d0f6
--- /dev/null
+++ b/WebCore/platform/ScrollAnimatorWin.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollAnimatorWin.h"
+
+#include "ScrollbarClient.h"
+#include "ScrollbarTheme.h"
+#include <algorithm>
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+// static
+ScrollAnimator* ScrollAnimator::create(ScrollbarClient* client)
+{
+ return new ScrollAnimatorWin(client);
+}
+
+const double ScrollAnimatorWin::animationTimerDelay = 0.01;
+
+ScrollAnimatorWin::PerAxisData::PerAxisData(ScrollAnimatorWin* parent, float* currentPos)
+ : m_currentPos(currentPos)
+ , m_desiredPos(0)
+ , m_currentVelocity(0)
+ , m_desiredVelocity(0)
+ , m_lastAnimationTime(0)
+ , m_animationTimer(parent, &ScrollAnimatorWin::animationTimerFired)
+{
+}
+
+
+ScrollAnimatorWin::ScrollAnimatorWin(ScrollbarClient* client)
+ : ScrollAnimator(client)
+ , m_horizontalData(this, &m_currentPosX)
+ , m_verticalData(this, &m_currentPosY)
+{
+}
+
+ScrollAnimatorWin::~ScrollAnimatorWin()
+{
+ stopAnimationTimerIfNeeded(&m_horizontalData);
+ stopAnimationTimerIfNeeded(&m_verticalData);
+}
+
+bool ScrollAnimatorWin::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+{
+ // Don't animate jumping to the beginning or end of the document.
+ if (granularity == ScrollByDocument)
+ return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
+
+ // This is an animatable scroll. Calculate the scroll delta.
+ PerAxisData* data = (orientation == VerticalScrollbar) ? &m_verticalData : &m_horizontalData;
+ float newPos = std::max(std::min(data->m_desiredPos + (step * multiplier), static_cast<float>(m_client->scrollSize(orientation))), 0.0f);
+ if (newPos == data->m_desiredPos)
+ return false;
+ data->m_desiredPos = newPos;
+
+ // Calculate the animation velocity.
+ if (*data->m_currentPos == data->m_desiredPos)
+ return false;
+ bool alreadyAnimating = data->m_animationTimer.isActive();
+ // There are a number of different sources of scroll requests. We want to
+ // make both keyboard and wheel-generated scroll requests (which can come at
+ // unpredictable rates) and autoscrolling from holding down the mouse button
+ // on a scrollbar part (where the request rate can be obtained from the
+ // scrollbar theme) feel smooth, responsive, and similar.
+ //
+ // When autoscrolling, the scrollbar's autoscroll timer will call us to
+ // increment the desired position by |step| (with |multiplier| == 1) every
+ // ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() seconds. If we set
+ // the desired velocity to exactly this rate, smooth scrolling will neither
+ // race ahead (and then have to slow down) nor increasingly lag behind, but
+ // will be smooth and synchronized.
+ //
+ // Note that because of the acceleration period, the current position in
+ // this case would lag the desired one by a small, constant amount (see
+ // comments on animateScroll()); the exact amount is given by
+ // lag = |step| - v(0.5tA + tD)
+ // Where
+ // v = The steady-state velocity,
+ // |step| / ScrollbarTheme::nativeTheme()->autoscrollTimerDelay()
+ // tA = accelerationTime()
+ // tD = The time we pretend has already passed when starting to scroll,
+ // |animationTimerDelay|
+ //
+ // This lag provides some buffer against timer jitter so we're less likely
+ // to hit the desired position and stop (and thus have to re-accelerate,
+ // causing a visible hitch) while waiting for the next autoscroll increment.
+ //
+ // Thus, for autoscroll-timer-triggered requests, the ideal steady-state
+ // distance to travel in each time interval is:
+ // float animationStep = step;
+ // Note that when we're not already animating, this is exactly the same as
+ // the distance to the target position. We'll return to that in a moment.
+ //
+ // For keyboard and wheel scrolls, we don't know when the next increment
+ // will be requested. If we set the target velocity based on how far away
+ // from the target position we are, then for keyboard/wheel events that come
+ // faster than the autoscroll delay, we'll asymptotically approach the
+ // velocity needed to stay smoothly in sync with the user's actions; for
+ // events that come slower, we'll scroll one increment and then pause until
+ // the next event fires.
+ float animationStep = abs(newPos - *data->m_currentPos);
+ // If a key is held down (or the wheel continually spun), then once we have
+ // reached a velocity close to the steady-state velocity, we're likely to
+ // hit the desired position at around the same time we'd expect the next
+ // increment to occur -- bad because it leads to hitching as described above
+ // (if autoscroll-based requests didn't result in a small amount of constant
+ // lag). So if we're called again while already animating, we want to trim
+ // the animationStep slightly to maintain lag like what's described above.
+ // (I say "maintain" since we'll already be lagged due to the acceleration
+ // during the first scroll period.)
+ //
+ // Remember that trimming won't cause us to fall steadily further behind
+ // here, because the further behind we are, the larger the base step value
+ // above. Given the scrolling algorithm in animateScroll(), the practical
+ // effect will actually be that, assuming a constant trim factor, we'll lag
+ // by a constant amount depending on the rate at which increments occur
+ // compared to the autoscroll timer delay. The exact lag is given by
+ // lag = |step| * ((r / k) - 1)
+ // Where
+ // r = The ratio of the autoscroll repeat delay,
+ // ScrollbarTheme::nativeTheme()->autoscrollTimerDelay(), to the
+ // key/wheel repeat delay (i.e. > 1 when keys repeat faster)
+ // k = The velocity trim constant given below
+ //
+ // We want to choose the trim factor such that for calls that come at the
+ // autoscroll timer rate, we'll wind up with the same lag as in the
+ // "perfect" case described above (or, to put it another way, we'll end up
+ // with |animationStep| == |step| * |multiplier| despite the actual distance
+ // calculated above being larger than that). This will result in "perfect"
+ // behavior for autoscrolling without having to special-case it.
+ if (alreadyAnimating)
+ animationStep /= (2.0 - ((1.0 / ScrollbarTheme::nativeTheme()->autoscrollTimerDelay()) * (0.5 * accelerationTime() + animationTimerDelay)));
+ // The result of all this is that single keypresses or wheel flicks will
+ // scroll in the same time period as single presses of scrollbar elements;
+ // holding the mouse down on a scrollbar part will scroll as fast as
+ // possible without hitching; and other repeated scroll events will also
+ // scroll with the same time lag as holding down the mouse on a scrollbar
+ // part.
+ data->m_desiredVelocity = animationStep / ScrollbarTheme::nativeTheme()->autoscrollTimerDelay();
+
+ // If we're not already scrolling, start.
+ if (!alreadyAnimating)
+ animateScroll(data);
+ return true;
+}
+
+void ScrollAnimatorWin::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+{
+ PerAxisData* data = (orientation == HorizontalScrollbar) ? &m_horizontalData : &m_verticalData;
+ stopAnimationTimerIfNeeded(data);
+ *data->m_currentPos = pos;
+ data->m_desiredPos = pos;
+ data->m_currentVelocity = 0;
+ data->m_desiredVelocity = 0;
+}
+
+// static
+double ScrollAnimatorWin::accelerationTime()
+{
+ // We elect to use ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() as
+ // the length of time we'll take to accelerate from 0 to our target
+ // velocity. Choosing a larger value would produce a more pronounced
+ // acceleration effect.
+ return ScrollbarTheme::nativeTheme()->autoscrollTimerDelay();
+}
+
+void ScrollAnimatorWin::animationTimerFired(Timer<ScrollAnimatorWin>* timer)
+{
+ animateScroll((timer == &m_horizontalData.m_animationTimer) ? &m_horizontalData : &m_verticalData);
+}
+
+void ScrollAnimatorWin::stopAnimationTimerIfNeeded(PerAxisData* data)
+{
+ if (data->m_animationTimer.isActive())
+ data->m_animationTimer.stop();
+}
+
+void ScrollAnimatorWin::animateScroll(PerAxisData* data)
+{
+ // Note on smooth scrolling perf versus non-smooth scrolling perf:
+ // The total time to perform a complete scroll is given by
+ // t = t0 + 0.5tA - tD + tS
+ // Where
+ // t0 = The time to perform the scroll without smooth scrolling
+ // tA = The acceleration time,
+ // ScrollbarTheme::nativeTheme()->autoscrollTimerDelay() (see below)
+ // tD = |animationTimerDelay|
+ // tS = A value less than or equal to the time required to perform a
+ // single scroll increment, i.e. the work done due to calling
+ // client()->valueChanged() (~0 for simple pages, larger for complex
+ // pages).
+ //
+ // Because tA and tD are fairly small, the total lag (as users perceive it)
+ // is negligible for simple pages and roughly tS for complex pages. Without
+ // knowing in advance how large tS is it's hard to do better than this.
+ // Perhaps we could try to remember previous values and forward-compensate.
+
+
+ // We want to update the scroll position based on the time it's been since
+ // our last update. This may be longer than our ideal time, especially if
+ // the page is complex or the system is slow.
+ //
+ // To avoid feeling laggy, if we've just started smooth scrolling we pretend
+ // we've already accelerated for one ideal interval, so that we'll scroll at
+ // least some distance immediately.
+ double lastScrollInterval = data->m_currentVelocity ? (WTF::currentTime() - data->m_lastAnimationTime) : animationTimerDelay;
+
+ // Figure out how far we've actually traveled and update our current
+ // velocity.
+ float distanceTraveled;
+ if (data->m_currentVelocity < data->m_desiredVelocity) {
+ // We accelerate at a constant rate until we reach the desired velocity.
+ float accelerationRate = data->m_desiredVelocity / accelerationTime();
+
+ // Figure out whether contant acceleration has caused us to reach our
+ // target velocity.
+ float potentialVelocityChange = accelerationRate * lastScrollInterval;
+ float potentialNewVelocity = data->m_currentVelocity + potentialVelocityChange;
+ if (potentialNewVelocity > data->m_desiredVelocity) {
+ // We reached the target velocity at some point between our last
+ // update and now. The distance traveled can be calculated in two
+ // pieces: the distance traveled while accelerating, and the
+ // distance traveled after reaching the target velocity.
+ float actualVelocityChange = data->m_desiredVelocity - data->m_currentVelocity;
+ float accelerationInterval = actualVelocityChange / accelerationRate;
+ // The distance traveled under constant acceleration is the area
+ // under a line segment with a constant rising slope. Break this
+ // into a triangular portion atop a rectangular portion and sum.
+ distanceTraveled = ((data->m_currentVelocity + (actualVelocityChange / 2)) * accelerationInterval);
+ // The distance traveled at the target velocity is simply
+ // (target velocity) * (remaining time after accelerating).
+ distanceTraveled += (data->m_desiredVelocity * (lastScrollInterval - accelerationInterval));
+ data->m_currentVelocity = data->m_desiredVelocity;
+ } else {
+ // Constant acceleration through the entire time interval.
+ distanceTraveled = (data->m_currentVelocity + (potentialVelocityChange / 2)) * lastScrollInterval;
+ data->m_currentVelocity = potentialNewVelocity;
+ }
+ } else {
+ // We've already reached the target velocity, so the distance we've
+ // traveled is simply (current velocity) * (elapsed time).
+ distanceTraveled = data->m_currentVelocity * lastScrollInterval;
+ // If our desired velocity has decreased, drop the current velocity too.
+ data->m_currentVelocity = data->m_desiredVelocity;
+ }
+
+ // Now update the scroll position based on the distance traveled.
+ if (distanceTraveled >= abs(data->m_desiredPos - *data->m_currentPos)) {
+ // We've traveled far enough to reach the desired position. Stop smooth
+ // scrolling.
+ *data->m_currentPos = data->m_desiredPos;
+ data->m_currentVelocity = 0;
+ data->m_desiredVelocity = 0;
+ } else {
+ // Not yet at the target position. Travel towards it and set up the
+ // next update.
+ if (*data->m_currentPos > data->m_desiredPos)
+ distanceTraveled = -distanceTraveled;
+ *data->m_currentPos += distanceTraveled;
+ data->m_animationTimer.startOneShot(animationTimerDelay);
+ data->m_lastAnimationTime = WTF::currentTime();
+ }
+ m_client->setScrollOffsetFromAnimation(IntPoint(*m_horizontalData.m_currentPos, *m_verticalData.m_currentPos));
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/ScrollAnimatorWin.h b/WebCore/platform/ScrollAnimatorWin.h
new file mode 100644
index 0000000..002a454
--- /dev/null
+++ b/WebCore/platform/ScrollAnimatorWin.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 ScrollAnimatorWin_h
+#define ScrollAnimatorWin_h
+
+#include "ScrollAnimator.h"
+#include "Timer.h"
+
+namespace WebCore {
+
+class ScrollAnimatorWin : public ScrollAnimator {
+public:
+ ScrollAnimatorWin(ScrollbarClient*);
+ virtual ~ScrollAnimatorWin();
+
+ virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier);
+ virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float);
+
+private:
+ struct PerAxisData {
+ PerAxisData(ScrollAnimatorWin* parent, float* currentPos);
+
+ float* m_currentPos;
+ float m_desiredPos;
+ float m_currentVelocity;
+ float m_desiredVelocity;
+ double m_lastAnimationTime;
+ Timer<ScrollAnimatorWin> m_animationTimer;
+ };
+
+ static double accelerationTime();
+ static const double animationTimerDelay;
+
+ void animationTimerFired(Timer<ScrollAnimatorWin>*);
+ void stopAnimationTimerIfNeeded(PerAxisData*);
+ void animateScroll(PerAxisData*);
+
+ PerAxisData m_horizontalData;
+ PerAxisData m_verticalData;
+};
+
+}
+#endif
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 854fef5..43badd0 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -303,6 +303,20 @@ IntPoint ScrollView::maximumScrollPosition() const
return IntPoint(maximumOffset.width(), maximumOffset.height());
}
+int ScrollView::scrollSize(ScrollbarOrientation orientation) const
+{
+ Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalScrollbar : m_verticalScrollbar).get();
+ return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
+}
+
+void ScrollView::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+ if (m_horizontalScrollbar)
+ m_horizontalScrollbar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
+ if (m_verticalScrollbar)
+ m_verticalScrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void ScrollView::valueChanged(Scrollbar* scrollbar)
{
// Figure out if we really moved.
@@ -471,7 +485,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
m_horizontalScrollbar->setSuppressInvalidation(true);
m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
- m_horizontalScrollbar->setValue(scroll.width());
+ m_horizontalScrollbar->setValue(scroll.width(), Scrollbar::NotFromScrollAnimator);
if (m_scrollbarsSuppressed)
m_horizontalScrollbar->setSuppressInvalidation(false);
}
@@ -493,7 +507,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
m_verticalScrollbar->setSuppressInvalidation(true);
m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_verticalScrollbar->setProportion(clientHeight, contentsHeight());
- m_verticalScrollbar->setValue(scroll.height());
+ m_verticalScrollbar->setValue(scroll.height(), Scrollbar::NotFromScrollAnimator);
if (m_scrollbarsSuppressed)
m_verticalScrollbar->setSuppressInvalidation(false);
}
@@ -703,7 +717,12 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
if (negative)
deltaY = -deltaY;
}
- scrollBy(IntSize(-deltaX, -deltaY));
+
+ // Should we fall back on scrollBy() if there is no scrollbar for a non-zero delta?
+ if (deltaY && m_verticalScrollbar)
+ m_verticalScrollbar->scroll(ScrollUp, ScrollByPixel, deltaY);
+ if (deltaX && m_horizontalScrollbar)
+ m_horizontalScrollbar->scroll(ScrollLeft, ScrollByPixel, deltaX);
}
}
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 5624d70..a55fed4 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -40,6 +40,7 @@
#endif
#if PLATFORM(GTK)
+#include "GRefPtrGtk.h"
typedef struct _GtkAdjustment GtkAdjustment;
#endif
@@ -57,7 +58,9 @@ class ScrollView : public Widget, public ScrollbarClient {
public:
~ScrollView();
- // ScrollbarClient function. FrameView overrides the others.
+ // ScrollbarClient functions. FrameView overrides the others.
+ virtual int scrollSize(ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&);
virtual void valueChanged(Scrollbar*);
// The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
@@ -347,9 +350,11 @@ private:
#if PLATFORM(GTK)
public:
void setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, bool resetValues = true);
- GtkAdjustment* m_horizontalAdjustment;
- GtkAdjustment* m_verticalAdjustment;
void setScrollOffset(const IntSize& offset) { m_scrollOffset = offset; }
+
+private:
+ PlatformRefPtr<GtkAdjustment> m_horizontalAdjustment;
+ PlatformRefPtr<GtkAdjustment> m_verticalAdjustment;
#endif
#if PLATFORM(WX)
diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp
index ff8f66f..398584a 100644
--- a/WebCore/platform/Scrollbar.cpp
+++ b/WebCore/platform/Scrollbar.cpp
@@ -40,7 +40,7 @@
using namespace std;
-#if PLATFORM(CHROMIUM) && OS(LINUX)
+#if PLATFORM(CHROMIUM) && OS(LINUX) || PLATFORM(GTK)
// The position of the scrollbar thumb affects the appearance of the steppers, so
// when the thumb moves, we have to invalidate them for painting.
#define THUMB_POSITION_AFFECTS_BUTTONS
@@ -48,7 +48,7 @@ using namespace std;
namespace WebCore {
-#if !PLATFORM(GTK) && !PLATFORM(EFL)
+#if !PLATFORM(EFL)
PassRefPtr<Scrollbar> Scrollbar::createNativeScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size)
{
return adoptRef(new Scrollbar(client, orientation, size));
@@ -101,12 +101,12 @@ Scrollbar::~Scrollbar()
m_theme->unregisterScrollbar(this);
}
-bool Scrollbar::setValue(int v)
+bool Scrollbar::setValue(int v, ScrollSource source)
{
v = max(min(v, m_totalSize - m_visibleSize), 0);
if (value() == v)
return false; // Our value stayed the same.
- setCurrentPos(v);
+ setCurrentPos(v, source);
return true;
}
@@ -154,8 +154,10 @@ bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity,
}
if (direction == ScrollUp || direction == ScrollLeft)
multiplier = -multiplier;
+ if (client())
+ return client()->scroll(m_orientation, granularity, step, multiplier);
- return setCurrentPos(max(min(m_currentPos + (step * multiplier), static_cast<float>(m_totalSize - m_visibleSize)), 0.0f));
+ return setCurrentPos(max(min(m_currentPos + (step * multiplier), static_cast<float>(m_totalSize - m_visibleSize)), 0.0f), NotFromScrollAnimator);
}
void Scrollbar::updateThumb()
@@ -287,11 +289,14 @@ void Scrollbar::moveThumb(int pos)
else if (delta < 0)
delta = max(-thumbPos, delta);
if (delta)
- setCurrentPos(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen));
+ setCurrentPos(static_cast<float>(thumbPos + delta) * maximum() / (trackLen - thumbLen), NotFromScrollAnimator);
}
-bool Scrollbar::setCurrentPos(float pos)
+bool Scrollbar::setCurrentPos(float pos, ScrollSource source)
{
+ if ((source != FromScrollAnimator) && client())
+ client()->setScrollPositionAndStopAnimation(m_orientation, pos);
+
if (pos == m_currentPos)
return false;
@@ -336,7 +341,7 @@ bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
{
if (m_pressedPart == ThumbPart) {
if (theme()->shouldSnapBackToDragOrigin(this, evt))
- setCurrentPos(m_dragOrigin);
+ setCurrentPos(m_dragOrigin, NotFromScrollAnimator);
else {
moveThumb(m_orientation == HorizontalScrollbar ?
convertFromContainingWindow(evt.pos()).x() :
diff --git a/WebCore/platform/Scrollbar.h b/WebCore/platform/Scrollbar.h
index f8ef96d..276bf60 100644
--- a/WebCore/platform/Scrollbar.h
+++ b/WebCore/platform/Scrollbar.h
@@ -42,6 +42,11 @@ class PlatformMouseEvent;
class Scrollbar : public Widget {
public:
+ enum ScrollSource {
+ FromScrollAnimator,
+ NotFromScrollAnimator,
+ };
+
virtual ~Scrollbar();
// Must be implemented by platforms that can't simply use the Scrollbar base class. Right now the only platform that is not using the base class is GTK.
@@ -75,7 +80,7 @@ public:
virtual void setPressedPart(ScrollbarPart);
void setSteps(int lineStep, int pageStep, int pixelsPerStep = 1);
- bool setValue(int);
+ bool setValue(int, ScrollSource source);
void setProportion(int visibleSize, int totalSize);
void setPressedPos(int p) { m_pressedPos = p; }
@@ -167,7 +172,7 @@ protected:
private:
virtual bool isScrollbar() const { return true; }
- bool setCurrentPos(float pos);
+ bool setCurrentPos(float pos, ScrollSource source);
};
}
diff --git a/WebCore/platform/ScrollbarClient.cpp b/WebCore/platform/ScrollbarClient.cpp
new file mode 100644
index 0000000..2f81a93
--- /dev/null
+++ b/WebCore/platform/ScrollbarClient.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollbarClient.h"
+
+#include "ScrollAnimator.h"
+
+namespace WebCore {
+
+ScrollbarClient::ScrollbarClient()
+ : m_scrollAnimator(ScrollAnimator::create(this))
+{
+}
+
+ScrollbarClient::~ScrollbarClient()
+{
+}
+
+bool ScrollbarClient::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+{
+ return m_scrollAnimator->scroll(orientation, granularity, step, multiplier);
+}
+
+void ScrollbarClient::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos)
+{
+ m_scrollAnimator->setScrollPositionAndStopAnimation(orientation, pos);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/ScrollbarClient.h b/WebCore/platform/ScrollbarClient.h
index fa94ecc..ab3b10e 100644
--- a/WebCore/platform/ScrollbarClient.h
+++ b/WebCore/platform/ScrollbarClient.h
@@ -26,21 +26,28 @@
#ifndef ScrollbarClient_h
#define ScrollbarClient_h
+#include "IntPoint.h"
#include "IntRect.h"
#include "Scrollbar.h"
#include <wtf/Vector.h>
namespace WebCore {
+class ScrollAnimator;
+
class ScrollbarClient {
public:
- virtual ~ScrollbarClient() { }
- virtual void valueChanged(Scrollbar*) = 0;
+ ScrollbarClient();
+ virtual ~ScrollbarClient();
- virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
+ bool scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier);
+ void setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos);
+ virtual int scrollSize(ScrollbarOrientation orientation) const = 0;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&) = 0;
+ virtual void valueChanged(Scrollbar*) = 0;
+ virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
virtual bool isActive() const = 0;
-
virtual bool scrollbarCornerPresent() const = 0;
virtual void getTickmarks(Vector<IntRect>&) const { }
@@ -52,21 +59,21 @@ public:
{
return scrollbar->Widget::convertToContainingView(scrollbarRect);
}
-
virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
{
return scrollbar->Widget::convertFromContainingView(parentRect);
}
-
virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
{
return scrollbar->Widget::convertToContainingView(scrollbarPoint);
}
-
virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
{
return scrollbar->Widget::convertFromContainingView(parentPoint);
}
+
+private:
+ OwnPtr<ScrollAnimator> m_scrollAnimator;
};
}
diff --git a/WebCore/platform/ScrollbarThemeComposite.cpp b/WebCore/platform/ScrollbarThemeComposite.cpp
index d28e1c3..fdac14d 100644
--- a/WebCore/platform/ScrollbarThemeComposite.cpp
+++ b/WebCore/platform/ScrollbarThemeComposite.cpp
@@ -296,10 +296,9 @@ void ScrollbarThemeComposite::paintScrollCorner(ScrollView* view, GraphicsContex
{
FrameView* frameView = static_cast<FrameView*>(view);
Page* page = frameView->frame() ? frameView->frame()->page() : 0;
- if (page && page->settings()->shouldPaintCustomScrollbars()) {
- if (!page->chrome()->client()->paintCustomScrollCorner(context, cornerRect))
- context->fillRect(cornerRect, Color::white, DeviceColorSpace);
- }
+ if (page && page->settings()->shouldPaintCustomScrollbars() && page->chrome()->client()->paintCustomScrollCorner(context, cornerRect))
+ return;
+ context->fillRect(cornerRect, Color::white, DeviceColorSpace);
}
}
diff --git a/WebCore/platform/UUID.cpp b/WebCore/platform/UUID.cpp
index 852e3ae..fdbf601 100644
--- a/WebCore/platform/UUID.cpp
+++ b/WebCore/platform/UUID.cpp
@@ -84,10 +84,11 @@ String createCanonicalUUIDString()
FILE* fptr = fopen("/proc/sys/kernel/random/uuid", "r");
if (!fptr)
return String();
- char uuidStr[37] = {0};
- if (!fgets(uuidStr, sizeof(uuidStr) - 1, fptr))
- return String();
+ char uuidStr[37];
+ char* result = fgets(uuidStr, sizeof(uuidStr), fptr);
fclose(fptr);
+ if (!result)
+ return String();
String canonicalUuidStr = String(uuidStr).lower(); // make it lower.
ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired);
return canonicalUuidStr;
diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp
index bedb91b..3c5c8b4 100644
--- a/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -104,7 +104,7 @@ namespace WebCore {
// This function tells the bridge that a resource was loaded from the cache and thus
// the app may update progress with the amount of data loaded.
-void CheckCacheObjectStatus(DocLoader*, CachedResource*)
+void CheckCacheObjectStatus(CachedResourceLoader*, CachedResource*)
{
ASSERT_NOT_REACHED();
notImplemented();
diff --git a/WebCore/platform/animation/Animation.cpp b/WebCore/platform/animation/Animation.cpp
index bc33a9e..112ee36 100644
--- a/WebCore/platform/animation/Animation.cpp
+++ b/WebCore/platform/animation/Animation.cpp
@@ -106,23 +106,23 @@ bool Animation::animationsMatch(const Animation* o, bool matchPlayStates) const
if (!o)
return false;
- bool result = m_name == o->m_name &&
- m_property == o->m_property &&
- m_iterationCount == o->m_iterationCount &&
- m_delay == o->m_delay &&
- m_duration == o->m_duration &&
- m_timingFunction == o->m_timingFunction &&
- m_direction == o->m_direction &&
- m_fillMode == o->m_fillMode &&
- m_delaySet == o->m_delaySet &&
- m_directionSet == o->m_directionSet &&
- m_durationSet == o->m_durationSet &&
- m_fillModeSet == o->m_fillModeSet &&
- m_iterationCountSet == o->m_iterationCountSet &&
- m_nameSet == o->m_nameSet &&
- m_propertySet == o->m_propertySet &&
- m_timingFunctionSet == o->m_timingFunctionSet &&
- m_isNone == o->m_isNone;
+ bool result = m_name == o->m_name
+ && m_property == o->m_property
+ && m_iterationCount == o->m_iterationCount
+ && m_delay == o->m_delay
+ && m_duration == o->m_duration
+ && *(m_timingFunction.get()) == *(o->m_timingFunction.get())
+ && m_direction == o->m_direction
+ && m_fillMode == o->m_fillMode
+ && m_delaySet == o->m_delaySet
+ && m_directionSet == o->m_directionSet
+ && m_durationSet == o->m_durationSet
+ && m_fillModeSet == o->m_fillModeSet
+ && m_iterationCountSet == o->m_iterationCountSet
+ && m_nameSet == o->m_nameSet
+ && m_propertySet == o->m_propertySet
+ && m_timingFunctionSet == o->m_timingFunctionSet
+ && m_isNone == o->m_isNone;
if (!result)
return false;
diff --git a/WebCore/platform/animation/Animation.h b/WebCore/platform/animation/Animation.h
index cabb0eb..9130415 100644
--- a/WebCore/platform/animation/Animation.h
+++ b/WebCore/platform/animation/Animation.h
@@ -26,6 +26,7 @@
#define Animation_h
#include "PlatformString.h"
+#include "RenderStyleConstants.h"
#include "TimingFunction.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -94,7 +95,7 @@ public:
const String& name() const { return m_name; }
unsigned playState() const { return m_playState; }
int property() const { return m_property; }
- const TimingFunction& timingFunction() const { return m_timingFunction; }
+ const PassRefPtr<TimingFunction> timingFunction() const { return m_timingFunction; }
void setDelay(double c) { m_delay = c; m_delaySet = true; }
void setDirection(AnimationDirection d) { m_direction = d; m_directionSet = true; }
@@ -104,7 +105,7 @@ public:
void setName(const String& n) { m_name = n; m_nameSet = true; }
void setPlayState(unsigned d) { m_playState = d; m_playStateSet = true; }
void setProperty(int t) { m_property = t; m_propertySet = true; }
- void setTimingFunction(const TimingFunction& f) { m_timingFunction = f; m_timingFunctionSet = true; }
+ void setTimingFunction(PassRefPtr<TimingFunction> f) { m_timingFunction = f; m_timingFunctionSet = true; }
void setIsNoneAnimation(bool n) { m_isNone = n; }
@@ -129,7 +130,7 @@ private:
int m_iterationCount;
double m_delay;
double m_duration;
- TimingFunction m_timingFunction;
+ RefPtr<TimingFunction> m_timingFunction;
AnimationDirection m_direction : 1;
unsigned m_fillMode : 2;
@@ -156,7 +157,7 @@ public:
static String initialAnimationName() { return String("none"); }
static unsigned initialAnimationPlayState() { return AnimPlayStatePlaying; }
static int initialAnimationProperty() { return cAnimateAll; }
- static TimingFunction initialAnimationTimingFunction() { return TimingFunction(); }
+ static PassRefPtr<TimingFunction> initialAnimationTimingFunction() { return CubicBezierTimingFunction::create(); }
};
} // namespace WebCore
diff --git a/WebCore/platform/animation/TimingFunction.h b/WebCore/platform/animation/TimingFunction.h
index d3f71ff..8ef2d8f 100644
--- a/WebCore/platform/animation/TimingFunction.h
+++ b/WebCore/platform/animation/TimingFunction.h
@@ -25,53 +25,87 @@
#ifndef TimingFunction_h
#define TimingFunction_h
-#include "RenderStyleConstants.h"
+#include <wtf/RefCounted.h>
namespace WebCore {
-struct TimingFunction : FastAllocBase {
- TimingFunction()
- : m_type(CubicBezierTimingFunction)
- , m_x1(0.25)
- , m_y1(0.1)
- , m_x2(0.25)
- , m_y2(1.0)
+class TimingFunction : public RefCounted<TimingFunction> {
+public:
+
+ enum TimingFunctionType {
+ LinearFunction, CubicBezierFunction, StepsFunction
+ };
+
+ virtual ~TimingFunction() { }
+
+ bool isLinearTimingFunction() const { return m_type == LinearFunction; }
+ bool isCubicBezierTimingFunction() const { return m_type == CubicBezierFunction; }
+ bool isStepsTimingFunction() const { return m_type == StepsFunction; }
+
+ virtual bool operator==(const TimingFunction& other) = 0;
+
+protected:
+ TimingFunction(TimingFunctionType type)
+ : m_type(type)
{
}
+
+ TimingFunctionType m_type;
+};
- // This explicit copy constructor works around an inlining bug in GCC 4.2 (only reproed on mac, but may exist on other platforms).
- TimingFunction(const TimingFunction& that)
- : m_type(that.m_type)
- , m_x1(that.m_x1)
- , m_y1(that.m_y1)
- , m_x2(that.m_x2)
- , m_y2(that.m_y2)
+class LinearTimingFunction : public TimingFunction {
+public:
+ static PassRefPtr<LinearTimingFunction> create()
{
+ return adoptRef(new LinearTimingFunction);
}
-
- TimingFunction(ETimingFunctionType timingFunction, double x1 = 0.0, double y1 = 0.0, double x2 = 1.0, double y2 = 1.0)
- : m_type(timingFunction)
- , m_x1(x1)
- , m_y1(y1)
- , m_x2(x2)
- , m_y2(y2)
+
+ ~LinearTimingFunction() { }
+
+ virtual bool operator==(const TimingFunction& other)
{
+ return other.isLinearTimingFunction();
+ }
+
+private:
+ LinearTimingFunction()
+ : TimingFunction(LinearFunction)
+ {
+ }
+};
+
+class CubicBezierTimingFunction : public TimingFunction {
+public:
+ static PassRefPtr<CubicBezierTimingFunction> create(double x1 = 0.25, double y1 = 0.1, double x2 = 0.25, double y2 = 1.0)
+ {
+ return adoptRef(new CubicBezierTimingFunction(x1, y1, x2, y2));
}
- bool operator==(const TimingFunction& o) const
+ ~CubicBezierTimingFunction() { }
+
+ virtual bool operator==(const TimingFunction& other)
{
- return m_type == o.m_type && m_x1 == o.m_x1 && m_y1 == o.m_y1 && m_x2 == o.m_x2 && m_y2 == o.m_y2;
+ if (other.isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(&other);
+ return m_x1 == ctf->m_x1 && m_y1 == ctf->m_y1 && m_x2 == ctf->m_x2 && m_y2 == ctf->m_y2;
+ }
+ return false;
}
double x1() const { return m_x1; }
double y1() const { return m_y1; }
double x2() const { return m_x2; }
double y2() const { return m_y2; }
-
- ETimingFunctionType type() const { return m_type; }
-
+
private:
- ETimingFunctionType m_type;
+ CubicBezierTimingFunction(double x1, double y1, double x2, double y2)
+ : TimingFunction(CubicBezierFunction)
+ , m_x1(x1)
+ , m_y1(y1)
+ , m_x2(x2)
+ , m_y2(y2)
+ {
+ }
double m_x1;
double m_y1;
@@ -79,6 +113,39 @@ private:
double m_y2;
};
+class StepsTimingFunction : public TimingFunction {
+public:
+ static PassRefPtr<StepsTimingFunction> create(int steps, bool stepAtStart)
+ {
+ return adoptRef(new StepsTimingFunction(steps, stepAtStart));
+ }
+
+ ~StepsTimingFunction() { }
+
+ virtual bool operator==(const TimingFunction& other)
+ {
+ if (other.isStepsTimingFunction()) {
+ const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(&other);
+ return m_steps == stf->m_steps && m_stepAtStart == stf->m_stepAtStart;
+ }
+ return false;
+ }
+
+ int numberOfSteps() const { return m_steps; }
+ bool stepAtStart() const { return m_stepAtStart; }
+
+private:
+ StepsTimingFunction(int steps, bool stepAtStart)
+ : TimingFunction(StepsFunction)
+ , m_steps(steps)
+ , m_stepAtStart(stepAtStart)
+ {
+ }
+
+ int m_steps;
+ bool m_stepAtStart;
+};
+
} // namespace WebCore
#endif // TimingFunction_h
diff --git a/WebCore/platform/audio/AudioArray.h b/WebCore/platform/audio/AudioArray.h
new file mode 100644
index 0000000..9c25b0f
--- /dev/null
+++ b/WebCore/platform/audio/AudioArray.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioArray_h
+#define AudioArray_h
+
+#include <string.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+template<typename T>
+class AudioArray : public Vector<T> {
+public:
+ AudioArray() : Vector<T>(0) { }
+ explicit AudioArray(size_t n) : Vector<T>(n, 0) { }
+
+ void zero() { memset(this->data(), 0, sizeof(T) * this->size()); }
+
+ void zeroRange(unsigned start, unsigned end)
+ {
+ bool isSafe = (start <= end) && (end <= this->size());
+ ASSERT(isSafe);
+ if (!isSafe)
+ return;
+
+ memset(this->data() + start, 0, sizeof(T) * (end - start));
+ }
+
+ void copyToRange(T* sourceData, unsigned start, unsigned end)
+ {
+ bool isSafe = (start <= end) && (end <= this->size());
+ ASSERT(isSafe);
+ if (!isSafe)
+ return;
+
+ memcpy(this->data() + start, sourceData, sizeof(T) * (end - start));
+ }
+};
+
+typedef AudioArray<float> AudioFloatArray;
+typedef AudioArray<double> AudioDoubleArray;
+
+} // WebCore
+
+#endif // AudioArray_h
diff --git a/WebCore/platform/audio/AudioBus.cpp b/WebCore/platform/audio/AudioBus.cpp
new file mode 100644
index 0000000..6b7ec3f
--- /dev/null
+++ b/WebCore/platform/audio/AudioBus.cpp
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "AudioBus.h"
+
+#include "Accelerate.h"
+#include <algorithm>
+#include <assert.h>
+#include <math.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+AudioBus::AudioBus(unsigned numberOfChannels, size_t length, bool allocate)
+ : m_length(length)
+ , m_busGain(1.0)
+ , m_isFirstTime(true)
+ , m_sampleRate(0.0)
+{
+ m_channels.reserveInitialCapacity(numberOfChannels);
+
+ for (unsigned i = 0; i < numberOfChannels; ++i) {
+ PassOwnPtr<AudioChannel> channel = allocate ? adoptPtr(new AudioChannel(length)) : adoptPtr(new AudioChannel(0, length));
+ m_channels.append(channel);
+ }
+
+ m_layout = LayoutCanonical; // for now this is the only layout we define
+}
+
+void AudioBus::setChannelMemory(unsigned channelIndex, float* storage, size_t length)
+{
+ if (channelIndex < m_channels.size()) {
+ channel(channelIndex)->set(storage, length);
+ m_length = length; // FIXME: verify that this length matches all the other channel lengths
+ }
+}
+
+void AudioBus::zero()
+{
+ for (unsigned i = 0; i < m_channels.size(); ++i)
+ m_channels[i]->zero();
+}
+
+AudioChannel* AudioBus::channelByType(unsigned channelType)
+{
+ // For now we only support canonical channel layouts...
+ if (m_layout != LayoutCanonical)
+ return 0;
+
+ switch (numberOfChannels()) {
+ case 1: // mono
+ if (channelType == ChannelMono || channelType == ChannelLeft)
+ return channel(0);
+ return 0;
+
+ case 2: // stereo
+ switch (channelType) {
+ case ChannelLeft: return channel(0);
+ case ChannelRight: return channel(1);
+ default: return 0;
+ }
+
+ case 4: // quad
+ switch (channelType) {
+ case ChannelLeft: return channel(0);
+ case ChannelRight: return channel(1);
+ case ChannelSurroundLeft: return channel(2);
+ case ChannelSurroundRight: return channel(3);
+ default: return 0;
+ }
+
+ case 5: // 5.0
+ switch (channelType) {
+ case ChannelLeft: return channel(0);
+ case ChannelRight: return channel(1);
+ case ChannelCenter: return channel(2);
+ case ChannelSurroundLeft: return channel(3);
+ case ChannelSurroundRight: return channel(4);
+ default: return 0;
+ }
+
+ case 6: // 5.1
+ switch (channelType) {
+ case ChannelLeft: return channel(0);
+ case ChannelRight: return channel(1);
+ case ChannelCenter: return channel(2);
+ case ChannelLFE: return channel(3);
+ case ChannelSurroundLeft: return channel(4);
+ case ChannelSurroundRight: return channel(5);
+ default: return 0;
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+// Returns true if the channel count and frame-size match.
+bool AudioBus::topologyMatches(const AudioBus& bus) const
+{
+ if (numberOfChannels() != bus.numberOfChannels())
+ return false; // channel mismatch
+
+ // Make sure source bus has enough frames.
+ if (length() > bus.length())
+ return false; // frame-size mismatch
+
+ return true;
+}
+
+PassOwnPtr<AudioBus> AudioBus::createBufferFromRange(AudioBus* sourceBuffer, unsigned startFrame, unsigned endFrame)
+{
+ size_t numberOfSourceFrames = sourceBuffer->length();
+ unsigned numberOfChannels = sourceBuffer->numberOfChannels();
+
+ // Sanity checking
+ bool isRangeSafe = startFrame < endFrame && endFrame <= numberOfSourceFrames;
+ ASSERT(isRangeSafe);
+ if (!isRangeSafe)
+ return 0;
+
+ size_t rangeLength = endFrame - startFrame;
+
+ OwnPtr<AudioBus> audioBus = adoptPtr(new AudioBus(numberOfChannels, rangeLength));
+ audioBus->setSampleRate(sourceBuffer->sampleRate());
+
+ for (unsigned i = 0; i < numberOfChannels; ++i)
+ audioBus->channel(i)->copyFromRange(sourceBuffer->channel(i), startFrame, endFrame);
+
+ return audioBus.release();
+}
+
+float AudioBus::maxAbsValue() const
+{
+ float max = 0.0f;
+ for (unsigned i = 0; i < numberOfChannels(); ++i) {
+ const AudioChannel* channel = this->channel(i);
+ max = std::max(max, channel->maxAbsValue());
+ }
+
+ return max;
+}
+
+void AudioBus::normalize()
+{
+ float max = maxAbsValue();
+ if (max)
+ scale(1.0f / max);
+}
+
+void AudioBus::scale(double scale)
+{
+ for (unsigned i = 0; i < numberOfChannels(); ++i)
+ channel(i)->scale(scale);
+}
+
+// Just copies the samples from the source bus to this one.
+// This is just a simple copy if the number of channels match, otherwise a mixup or mixdown is done.
+// For now, we just support a mixup from mono -> stereo.
+void AudioBus::copyFrom(const AudioBus& sourceBus)
+{
+ if (&sourceBus == this)
+ return;
+
+ if (numberOfChannels() == sourceBus.numberOfChannels()) {
+ for (unsigned i = 0; i < numberOfChannels(); ++i)
+ channel(i)->copyFrom(sourceBus.channel(i));
+ } else if (numberOfChannels() == 2 && sourceBus.numberOfChannels() == 1) {
+ // Handle mono -> stereo case (for now simply copy mono channel into both left and right)
+ // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
+ const AudioChannel* sourceChannel = sourceBus.channel(0);
+ channel(0)->copyFrom(sourceChannel);
+ channel(1)->copyFrom(sourceChannel);
+ } else {
+ // Case not handled
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void AudioBus::sumFrom(const AudioBus &sourceBus)
+{
+ if (numberOfChannels() == sourceBus.numberOfChannels()) {
+ for (unsigned i = 0; i < numberOfChannels(); ++i)
+ channel(i)->sumFrom(sourceBus.channel(i));
+ } else if (numberOfChannels() == 2 && sourceBus.numberOfChannels() == 1) {
+ // Handle mono -> stereo case (for now simply sum mono channel into both left and right)
+ // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
+ const AudioChannel* sourceChannel = sourceBus.channel(0);
+ channel(0)->sumFrom(sourceChannel);
+ channel(1)->sumFrom(sourceChannel);
+ } else {
+ // Case not handled
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void AudioBus::processWithGainFromMonoStereo(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus)
+{
+ // We don't want to suddenly change the gain from mixing one time slice to the next,
+ // so we "de-zipper" by slowly changing the gain each sample-frame until we've achieved the target gain.
+
+ // FIXME: optimize this method (SSE, etc.)
+ // FIXME: Need fast path here when gain has converged on targetGain. In this case, de-zippering is no longer needed.
+ // FIXME: Need fast path when this==sourceBus && lastMixGain==targetGain==1.0 && sumToBus==false (this is a NOP)
+
+ // Take master bus gain into account as well as the targetGain.
+ double totalDesiredGain = m_busGain * targetGain;
+
+ // First time, snap directly to totalDesiredGain.
+ double gain = m_isFirstTime ? totalDesiredGain : *lastMixGain;
+ m_isFirstTime = false;
+
+ int numberOfSourceChannels = sourceBus.numberOfChannels();
+ int numberOfDestinationChannels = numberOfChannels();
+
+ AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus);
+ const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data();
+ const float* sourceR = numberOfSourceChannels > 1 ? sourceBusSafe.channelByType(ChannelRight)->data() : 0;
+
+ float* destinationL = channelByType(ChannelLeft)->data();
+ float* destinationR = numberOfDestinationChannels > 1 ? channelByType(ChannelRight)->data() : 0;
+
+ const double DezipperRate = 0.005;
+ int framesToProcess = length();
+
+ if (sumToBus) {
+ // Sum to our bus
+ if (sourceR && destinationR) {
+ // Stereo
+ while (framesToProcess--) {
+ float sampleL = *sourceL++;
+ float sampleR = *sourceR++;
+ *destinationL++ += static_cast<float>(gain * sampleL);
+ *destinationR++ += static_cast<float>(gain * sampleR);
+
+ // Slowly change gain to desired gain.
+ gain += (totalDesiredGain - gain) * DezipperRate;
+ }
+ } else if (destinationR) {
+ // Mono -> stereo (mix equally into L and R)
+ // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
+ while (framesToProcess--) {
+ float sample = *sourceL++;
+ *destinationL++ += static_cast<float>(gain * sample);
+ *destinationR++ += static_cast<float>(gain * sample);
+
+ // Slowly change gain to desired gain.
+ gain += (totalDesiredGain - gain) * DezipperRate;
+ }
+ } else {
+ // Mono
+ while (framesToProcess--) {
+ float sampleL = *sourceL++;
+ *destinationL++ += static_cast<float>(gain * sampleL);
+
+ // Slowly change gain to desired gain.
+ gain += (totalDesiredGain - gain) * DezipperRate;
+ }
+ }
+ } else {
+ // Process directly (without summing) to our bus
+ if (sourceR && destinationR) {
+ // Stereo
+ while (framesToProcess--) {
+ float sampleL = *sourceL++;
+ float sampleR = *sourceR++;
+ *destinationL++ = static_cast<float>(gain * sampleL);
+ *destinationR++ = static_cast<float>(gain * sampleR);
+
+ // Slowly change gain to desired gain.
+ gain += (totalDesiredGain - gain) * DezipperRate;
+ }
+ } else if (destinationR) {
+ // Mono -> stereo (mix equally into L and R)
+ // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center...
+ while (framesToProcess--) {
+ float sample = *sourceL++;
+ *destinationL++ = static_cast<float>(gain * sample);
+ *destinationR++ = static_cast<float>(gain * sample);
+
+ // Slowly change gain to desired gain.
+ gain += (totalDesiredGain - gain) * DezipperRate;
+ }
+ } else {
+ // Mono
+ while (framesToProcess--) {
+ float sampleL = *sourceL++;
+ *destinationL++ = static_cast<float>(gain * sampleL);
+
+ // Slowly change gain to desired gain.
+ gain += (totalDesiredGain - gain) * DezipperRate;
+ }
+ }
+ }
+
+ // Save the target gain as the starting point for next time around.
+ *lastMixGain = gain;
+}
+
+void AudioBus::processWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus)
+{
+ // Make sure we're summing from same type of bus.
+ // We *are* able to sum from mono -> stereo
+ if (sourceBus.numberOfChannels() != 1 && !topologyMatches(sourceBus))
+ return;
+
+ // Dispatch for different channel layouts
+ switch (numberOfChannels()) {
+ case 1: // mono
+ case 2: // stereo
+ processWithGainFromMonoStereo(sourceBus, lastMixGain, targetGain, sumToBus);
+ break;
+ case 4: // FIXME: implement quad
+ case 5: // FIXME: implement 5.0
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void AudioBus::copyWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain)
+{
+ processWithGainFrom(sourceBus, lastMixGain, targetGain, false);
+}
+
+void AudioBus::sumWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain)
+{
+ processWithGainFrom(sourceBus, lastMixGain, targetGain, true);
+}
+
+} // WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/AudioBus.h b/WebCore/platform/audio/AudioBus.h
new file mode 100644
index 0000000..72357e8
--- /dev/null
+++ b/WebCore/platform/audio/AudioBus.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioBus_h
+#define AudioBus_h
+
+#include "AudioChannel.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// An AudioBus represents a collection of one or more AudioChannels.
+// The data layout is "planar" as opposed to "interleaved".
+// An AudioBus with one channel is mono, an AudioBus with two channels is stereo, etc.
+class AudioBus : public Noncopyable {
+public:
+ enum {
+ ChannelLeft = 0,
+ ChannelRight = 1,
+ ChannelCenter = 2, // center and mono are the same
+ ChannelMono = 2,
+ ChannelLFE = 3,
+ ChannelSurroundLeft = 4,
+ ChannelSurroundRight = 5,
+ };
+
+ enum {
+ LayoutCanonical = 0
+ // Can define non-standard layouts here
+ };
+
+ // allocate indicates whether or not to initially have the AudioChannels created with managed storage.
+ // Normal usage is to pass true here, in which case the AudioChannels will memory-manage their own storage.
+ // If allocate is false then setChannelMemory() has to be called later on for each channel before the AudioBus is useable...
+ AudioBus(unsigned numberOfChannels, size_t length, bool allocate = true);
+
+ // Tells the given channel to use an externally allocated buffer.
+ void setChannelMemory(unsigned channelIndex, float* storage, size_t length);
+
+ // Channels
+ unsigned numberOfChannels() const { return m_channels.size(); }
+
+ AudioChannel* channel(unsigned channel) { return m_channels[channel].get(); }
+ const AudioChannel* channel(unsigned channel) const { return const_cast<AudioBus*>(this)->m_channels[channel].get(); }
+ AudioChannel* channelByType(unsigned type);
+
+ // Number of sample-frames
+ size_t length() const { return m_length; }
+
+ // Sample-rate : 0.0 if unknown or "don't care"
+ double sampleRate() const { return m_sampleRate; }
+ void setSampleRate(double sampleRate) { m_sampleRate = sampleRate; }
+
+ // Zeroes all channels.
+ void zero();
+
+ // Returns true if the channel count and frame-size match.
+ bool topologyMatches(const AudioBus &sourceBus) const;
+
+ // Creates a new buffer from a range in the source buffer.
+ // 0 may be returned if the range does not fit in the sourceBuffer
+ static PassOwnPtr<AudioBus> createBufferFromRange(AudioBus* sourceBuffer, unsigned startFrame, unsigned endFrame);
+
+ // Scales all samples by the same amount.
+ void scale(double scale);
+
+ // Master gain for this bus - used with sumWithGainFrom() below
+ void setGain(double gain) { m_busGain = gain; }
+ double gain() { return m_busGain; }
+
+ void reset() { m_isFirstTime = true; } // for de-zippering
+
+ // Assuming sourceBus has the same topology, copies sample data from each channel of sourceBus to our corresponding channel.
+ void copyFrom(const AudioBus &sourceBus);
+
+ // Sums the sourceBus into our bus with unity gain.
+ // Our own internal gain m_busGain is ignored.
+ void sumFrom(const AudioBus &sourceBus);
+
+ // Copy or sum each channel from sourceBus into our corresponding channel.
+ // We scale by targetGain (and our own internal gain m_busGain), performing "de-zippering" to smoothly change from *lastMixGain to (targetGain*m_busGain).
+ // The caller is responsible for setting up lastMixGain to point to storage which is unique for every "stream" which will be summed to this bus.
+ // This represents the dezippering memory.
+ void copyWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain);
+ void sumWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain);
+
+ // Returns maximum absolute value across all channels (useful for normalization).
+ float maxAbsValue() const;
+
+ // Makes maximum absolute value == 1.0 (if possible).
+ void normalize();
+
+protected:
+ AudioBus() { };
+
+ void processWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus);
+ void processWithGainFromMonoStereo(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus);
+
+ size_t m_length;
+
+ Vector<OwnPtr<AudioChannel> > m_channels;
+
+ int m_layout;
+
+ double m_busGain;
+ bool m_isFirstTime;
+ double m_sampleRate; // 0.0 if unknown or N/A
+};
+
+} // WebCore
+
+#endif // AudioBus_h
diff --git a/WebCore/platform/audio/AudioChannel.cpp b/WebCore/platform/audio/AudioChannel.cpp
new file mode 100644
index 0000000..ad38219
--- /dev/null
+++ b/WebCore/platform/audio/AudioChannel.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "AudioChannel.h"
+
+#include "Accelerate.h"
+#include <algorithm>
+#include <math.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+void AudioChannel::scale(double scale)
+{
+ float s = static_cast<float>(scale);
+ vsmul(data(), 1, &s, data(), 1, length());
+}
+
+void AudioChannel::copyFrom(const AudioChannel* sourceChannel)
+{
+ bool isSafe = (sourceChannel && sourceChannel->length() >= length());
+ ASSERT(isSafe);
+ if (!isSafe)
+ return;
+
+ memcpy(data(), sourceChannel->data(), sizeof(float) * length());
+}
+
+void AudioChannel::copyFromRange(const AudioChannel* sourceChannel, unsigned startFrame, unsigned endFrame)
+{
+ // Check that range is safe for reading from sourceChannel.
+ bool isRangeSafe = sourceChannel && startFrame < endFrame && endFrame <= sourceChannel->length();
+ ASSERT(isRangeSafe);
+ if (!isRangeSafe)
+ return;
+
+ // Check that this channel has enough space.
+ size_t rangeLength = endFrame - startFrame;
+ bool isRangeLengthSafe = rangeLength <= length();
+ ASSERT(isRangeLengthSafe);
+ if (!isRangeLengthSafe)
+ return;
+
+ const float* source = sourceChannel->data();
+ float* destination = data();
+ memcpy(destination, source + startFrame, sizeof(float) * rangeLength);
+}
+
+void AudioChannel::sumFrom(const AudioChannel* sourceChannel)
+{
+ bool isSafe = sourceChannel && sourceChannel->length() >= length();
+ ASSERT(isSafe);
+ if (!isSafe)
+ return;
+
+ vadd(data(), 1, sourceChannel->data(), 1, data(), 1, length());
+}
+
+float AudioChannel::maxAbsValue() const
+{
+ const float* p = data();
+ int n = length();
+
+ float max = 0.0f;
+ while (n--)
+ max = std::max(max, fabsf(*p++));
+
+ return max;
+}
+
+} // WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/AudioChannel.h b/WebCore/platform/audio/AudioChannel.h
new file mode 100644
index 0000000..511048c
--- /dev/null
+++ b/WebCore/platform/audio/AudioChannel.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioChannel_h
+#define AudioChannel_h
+
+#include "AudioFloatArray.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+// An AudioChannel represents a buffer of non-interleaved floating-point audio samples.
+// The PCM samples are normally assumed to be in a nominal range -1.0 -> +1.0
+class AudioChannel : public Noncopyable {
+public:
+ // Memory can be externally referenced, or can be internally allocated with an AudioFloatArray.
+
+ // Reference an external buffer.
+ AudioChannel(float* storage, size_t length)
+ : m_length(length), m_rawPointer(storage) { }
+
+ // Manage storage for us.
+ explicit AudioChannel(size_t length)
+ : m_length(length)
+ , m_rawPointer(0)
+ {
+ m_memBuffer = adoptPtr(new AudioFloatArray(length));
+ }
+
+ // A "blank" audio channel -- must call set() before it's useful...
+ AudioChannel()
+ : m_length(0)
+ , m_rawPointer(0)
+ {
+ }
+
+ // Redefine the memory for this channel.
+ // storage represents external memory not managed by this object.
+ void set(float* storage, size_t length)
+ {
+ m_memBuffer.clear(); // cleanup managed storage
+ m_rawPointer = storage;
+ m_length = length;
+ }
+
+ // How many sample-frames do we contain?
+ size_t length() const { return m_length; }
+
+ // Direct access to PCM sample data
+ float* data() { return m_rawPointer ? m_rawPointer : m_memBuffer->data(); }
+ const float* data() const { return m_rawPointer ? m_rawPointer : m_memBuffer->data(); }
+
+ // Zeroes out all sample values in buffer.
+ void zero()
+ {
+ if (m_memBuffer.get())
+ m_memBuffer->zero();
+ else
+ memset(m_rawPointer, 0, sizeof(float) * m_length);
+ }
+
+ // Scales all samples by the same amount.
+ void scale(double scale);
+
+ // A simple memcpy() from the source channel
+ void copyFrom(const AudioChannel* sourceChannel);
+
+ // Copies the given range from the source channel.
+ void copyFromRange(const AudioChannel* sourceChannel, unsigned startFrame, unsigned endFrame);
+
+ // Sums (with unity gain) from the source channel.
+ void sumFrom(const AudioChannel* sourceChannel);
+
+ // Returns maximum absolute value (useful for normalization).
+ float maxAbsValue() const;
+
+private:
+ size_t m_length;
+
+ float* m_rawPointer;
+ OwnPtr<AudioFloatArray> m_memBuffer;
+};
+
+} // WebCore
+
+#endif // AudioChannel_h
diff --git a/WebCore/platform/audio/AudioDSPKernel.h b/WebCore/platform/audio/AudioDSPKernel.h
new file mode 100644
index 0000000..d9be6dc
--- /dev/null
+++ b/WebCore/platform/audio/AudioDSPKernel.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioDSPKernel_h
+#define AudioDSPKernel_h
+
+#include "AudioDSPKernelProcessor.h"
+
+namespace WebCore {
+
+// AudioDSPKernel does the processing for one channel of an AudioDSPKernelProcessor.
+
+class AudioDSPKernel {
+public:
+ AudioDSPKernel(AudioDSPKernelProcessor* kernelProcessor)
+ : m_kernelProcessor(kernelProcessor)
+ {
+ }
+
+ virtual ~AudioDSPKernel() { };
+
+ // Subclasses must override process() to do the processing and reset() to reset DSP state.
+ virtual void process(const float* source, float* destination, size_t framesToProcess) = 0;
+ virtual void reset() = 0;
+
+ double sampleRate() const { return processor()->sampleRate(); }
+ double nyquist() const { return 0.5 * sampleRate(); }
+
+ AudioDSPKernelProcessor* processor() { return m_kernelProcessor; }
+ const AudioDSPKernelProcessor* processor() const { return m_kernelProcessor; }
+
+protected:
+ AudioDSPKernelProcessor* m_kernelProcessor;
+};
+
+} // namespace WebCore
+
+#endif // AudioDSPKernel_h
diff --git a/WebCore/platform/audio/AudioDSPKernelProcessor.cpp b/WebCore/platform/audio/AudioDSPKernelProcessor.cpp
new file mode 100644
index 0000000..d79afd5
--- /dev/null
+++ b/WebCore/platform/audio/AudioDSPKernelProcessor.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "AudioDSPKernelProcessor.h"
+
+#include "AudioDSPKernel.h"
+
+namespace WebCore {
+
+// setNumberOfChannels() may later be called if the object is not yet in an "initialized" state.
+AudioDSPKernelProcessor::AudioDSPKernelProcessor(double sampleRate, unsigned numberOfChannels)
+ : AudioProcessor(sampleRate)
+ , m_numberOfChannels(numberOfChannels)
+ , m_hasJustReset(true)
+{
+}
+
+void AudioDSPKernelProcessor::initialize()
+{
+ if (isInitialized())
+ return;
+
+ ASSERT(!m_kernels.size());
+
+ // Create processing kernels, one per channel.
+ for (unsigned i = 0; i < numberOfChannels(); ++i)
+ m_kernels.append(createKernel());
+
+ m_initialized = true;
+}
+
+void AudioDSPKernelProcessor::uninitialize()
+{
+ if (!isInitialized())
+ return;
+
+ m_kernels.clear();
+
+ m_initialized = false;
+}
+
+void AudioDSPKernelProcessor::process(AudioBus* source, AudioBus* destination, size_t framesToProcess)
+{
+ ASSERT(source && destination);
+ if (!source || !destination)
+ return;
+
+ if (!isInitialized()) {
+ destination->zero();
+ return;
+ }
+
+ bool channelCountMatches = source->numberOfChannels() == destination->numberOfChannels() && source->numberOfChannels() == m_kernels.size();
+ ASSERT(channelCountMatches);
+ if (!channelCountMatches)
+ return;
+
+ for (unsigned i = 0; i < m_kernels.size(); ++i)
+ m_kernels[i]->process(source->channel(i)->data(), destination->channel(i)->data(), framesToProcess);
+}
+
+// Resets filter state
+void AudioDSPKernelProcessor::reset()
+{
+ if (!isInitialized())
+ return;
+
+ // Forces snap to parameter values - first time.
+ // Any processing depending on this value must set it to false at the appropriate time.
+ m_hasJustReset = true;
+
+ for (unsigned i = 0; i < m_kernels.size(); ++i)
+ m_kernels[i]->reset();
+}
+
+void AudioDSPKernelProcessor::setNumberOfChannels(unsigned numberOfChannels)
+{
+ ASSERT(!isInitialized());
+ if (!isInitialized())
+ m_numberOfChannels = numberOfChannels;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/AudioDSPKernelProcessor.h b/WebCore/platform/audio/AudioDSPKernelProcessor.h
new file mode 100644
index 0000000..e87a810
--- /dev/null
+++ b/WebCore/platform/audio/AudioDSPKernelProcessor.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioDSPKernelProcessor_h
+#define AudioDSPKernelProcessor_h
+
+#include "AudioBus.h"
+#include "AudioProcessor.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioBus;
+class AudioDSPKernel;
+class AudioProcessor;
+
+// AudioDSPKernelProcessor processes one input -> one output (N channels each)
+// It uses one AudioDSPKernel object per channel to do the processing, thus there is no cross-channel processing.
+// Despite this limitation it turns out to be a very common and useful type of processor.
+
+class AudioDSPKernelProcessor : public AudioProcessor {
+public:
+ // numberOfChannels may be later changed if object is not yet in an "initialized" state
+ AudioDSPKernelProcessor(double sampleRate, unsigned numberOfChannels);
+
+ // Subclasses create the appropriate type of processing kernel here.
+ // We'll call this to create a kernel for each channel.
+ virtual PassOwnPtr<AudioDSPKernel> createKernel() = 0;
+
+ // AudioProcessor methods
+ virtual void initialize();
+ virtual void uninitialize();
+ virtual void process(AudioBus* source, AudioBus* destination, size_t framesToProcess);
+ virtual void reset();
+ virtual void setNumberOfChannels(unsigned numberOfChannels);
+
+ unsigned numberOfChannels() const { return m_numberOfChannels; }
+
+protected:
+ unsigned m_numberOfChannels;
+ Vector<OwnPtr<AudioDSPKernel> > m_kernels;
+ bool m_hasJustReset;
+};
+
+} // namespace WebCore
+
+#endif // AudioDSPKernelProcessor_h
diff --git a/WebCore/platform/audio/AudioProcessor.h b/WebCore/platform/audio/AudioProcessor.h
new file mode 100644
index 0000000..69ba40f
--- /dev/null
+++ b/WebCore/platform/audio/AudioProcessor.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 AudioProcessor_h
+#define AudioProcessor_h
+
+namespace WebCore {
+
+class AudioBus;
+
+// AudioProcessor is an abstract base class representing an audio signal processing object with a single input and a single output,
+// where the number of input channels equals the number of output channels. It can be used as one part of a complex DSP algorithm,
+// or as the processor for a basic (one input - one output) AudioNode.
+
+class AudioProcessor {
+public:
+ AudioProcessor(double sampleRate)
+ : m_initialized(false)
+ , m_sampleRate(sampleRate)
+ {
+ }
+
+ virtual ~AudioProcessor() { }
+
+ // Full initialization can be done here instead of in the constructor.
+ virtual void initialize() = 0;
+ virtual void uninitialize() = 0;
+
+ // Processes the source to destination bus. The number of channels must match in source and destination.
+ virtual void process(AudioBus* source, AudioBus* destination, size_t framesToProcess) = 0;
+
+ // Resets filter state
+ virtual void reset() = 0;
+
+ virtual void setNumberOfChannels(unsigned) = 0;
+
+ bool isInitialized() const { return m_initialized; }
+
+ double sampleRate() const { return m_sampleRate; }
+
+protected:
+ bool m_initialized;
+ double m_sampleRate;
+};
+
+} // namespace WebCore
+
+#endif // AudioProcessor_h
diff --git a/WebCore/platform/audio/AudioSourceProvider.h b/WebCore/platform/audio/AudioSourceProvider.h
new file mode 100644
index 0000000..773546a
--- /dev/null
+++ b/WebCore/platform/audio/AudioSourceProvider.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioSourceProvider_h
+#define AudioSourceProvider_h
+
+namespace WebCore {
+
+class AudioBus;
+
+// Abstract base-class for a pull-model client.
+// provideInput() gets called repeatedly to render time-slices of a continuous audio stream.
+class AudioSourceProvider {
+public:
+ virtual void provideInput(AudioBus* bus, size_t framesToProcess) = 0;
+ virtual ~AudioSourceProvider() { }
+};
+
+} // WebCore
+
+#endif // AudioSourceProvider_h
diff --git a/WebCore/platform/audio/Biquad.cpp b/WebCore/platform/audio/Biquad.cpp
new file mode 100644
index 0000000..6918dd6
--- /dev/null
+++ b/WebCore/platform/audio/Biquad.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "Biquad.h"
+
+#include "Accelerate.h"
+#include <algorithm>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+namespace WebCore {
+
+const int kBufferSize = 1024;
+
+Biquad::Biquad()
+{
+#if OS(DARWIN)
+ // Allocate two samples more for filter history
+ m_inputBuffer.resize(kBufferSize + 2);
+ m_outputBuffer.resize(kBufferSize + 2);
+#endif
+
+ // Initialize as pass-thru (straight-wire, no filter effect)
+ m_a0 = 1.0;
+ m_a1 = 0.0;
+ m_a2 = 0.0;
+ m_b1 = 0.0;
+ m_b2 = 0.0;
+
+ m_g = 1.0;
+
+ reset(); // clear filter memory
+}
+
+void Biquad::process(const float* sourceP, float* destP, size_t framesToProcess)
+{
+#if OS(DARWIN)
+ // Use vecLib if available
+ processFast(sourceP, destP, framesToProcess);
+#else
+ int n = framesToProcess;
+
+ // Create local copies of member variables
+ double x1 = m_x1;
+ double x2 = m_x2;
+ double y1 = m_y1;
+ double y2 = m_y2;
+
+ double a0 = m_a0;
+ double a1 = m_a1;
+ double a2 = m_a2;
+ double b1 = m_b1;
+ double b2 = m_b2;
+
+ while (n--) {
+ // FIXME: this can be optimized by pipelining the multiply adds...
+ float x = *sourceP++;
+ float y = a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2;
+
+ y *= m_g;
+
+ *destP++ = y;
+
+ // Update state variables
+ x2 = x1;
+ x1 = x;
+ y2 = y1;
+ y1 = y;
+ }
+
+ // Local variables back to member
+ m_x1 = x1;
+ m_x2 = x2;
+ m_y1 = y1;
+ m_y2 = y2;
+
+ m_a0 = a0;
+ m_a1 = a1;
+ m_a2 = a2;
+ m_b1 = b1;
+ m_b2 = b2;
+#endif
+}
+
+#if OS(DARWIN)
+
+// Here we have optimized version using Accelerate.framework
+
+void Biquad::processFast(const float* sourceP, float* destP, size_t framesToProcess)
+{
+ // Filter coefficients
+ double B[5];
+ B[0] = m_a0;
+ B[1] = m_a1;
+ B[2] = m_a2;
+ B[3] = m_b1;
+ B[4] = m_b2;
+
+ double* inputP = m_inputBuffer.data();
+ double* outputP = m_outputBuffer.data();
+
+ double* input2P = inputP + 2;
+ double* output2P = outputP + 2;
+
+ // Break up processing into smaller slices (kBufferSize) if necessary.
+
+ int n = framesToProcess;
+
+ while (n > 0) {
+ int framesThisTime = n < kBufferSize ? n : kBufferSize;
+
+ // Copy input to input buffer
+ for (int i = 0; i < framesThisTime; ++i)
+ input2P[i] = *sourceP++;
+
+ processSliceFast(inputP, outputP, B, framesThisTime);
+
+ // Copy output buffer to output (converts float -> double).
+ for (int i = 0; i < framesThisTime; ++i)
+ *destP++ = static_cast<float>(output2P[i]);
+
+ n -= framesThisTime;
+ }
+}
+
+void Biquad::processSliceFast(double* sourceP, double* destP, double* coefficientsP, size_t framesToProcess)
+{
+ // Use double-precision for filter stability
+ vDSP_deq22D(sourceP, 1, coefficientsP, destP, 1, framesToProcess);
+
+ // Save history. Note that sourceP and destP reference m_inputBuffer and m_outputBuffer respectively.
+ // These buffers are allocated (in the constructor) with space for two extra samples so it's OK to access
+ // array values two beyond framesToProcess.
+ sourceP[0] = sourceP[framesToProcess - 2 + 2];
+ sourceP[1] = sourceP[framesToProcess - 1 + 2];
+ destP[0] = destP[framesToProcess - 2 + 2];
+ destP[1] = destP[framesToProcess - 1 + 2];
+}
+
+#endif // OS(DARWIN)
+
+
+void Biquad::reset()
+{
+ m_x1 = m_x2 = m_y1 = m_y2 = 0.0;
+
+#if OS(DARWIN)
+ // Two extra samples for filter history
+ double* inputP = m_inputBuffer.data();
+ inputP[0] = 0.0;
+ inputP[1] = 0.0;
+
+ double* outputP = m_outputBuffer.data();
+ outputP[0] = 0.0;
+ outputP[1] = 0.0;
+#endif
+}
+
+void Biquad::setLowpassParams(double cutoff, double resonance)
+{
+ resonance = std::max(0.0, resonance); // can't go negative
+
+ double g = pow(10.0, 0.05 * resonance);
+ double d = sqrt((4.0 - sqrt(16.0 - 16.0 / (g * g))) / 2.0);
+
+ // Compute biquad coefficients for lopass filter
+ double theta = M_PI * cutoff;
+ double sn = 0.5 * d * sin(theta);
+ double beta = 0.5 * (1.0 - sn) / (1.0 + sn);
+ double gamma = (0.5 + beta) * cos(theta);
+ double alpha = 0.25 * (0.5 + beta - gamma);
+
+ m_a0 = 2.0 * alpha;
+ m_a1 = 2.0 * 2.0*alpha;
+ m_a2 = 2.0 * alpha;
+ m_b1 = 2.0 * -gamma;
+ m_b2 = 2.0 * beta;
+}
+
+void Biquad::setHighpassParams(double cutoff, double resonance)
+{
+ resonance = std::max(0.0, resonance); // can't go negative
+
+ double g = pow(10.0, 0.05 * resonance);
+ double d = sqrt((4.0 - sqrt(16.0 - 16.0 / (g * g))) / 2.0);
+
+ // Compute biquad coefficients for highpass filter
+ double theta = M_PI * cutoff;
+ double sn = 0.5 * d * sin(theta);
+ double beta = 0.5 * (1.0 - sn) / (1.0 + sn);
+ double gamma = (0.5 + beta) * cos(theta);
+ double alpha = 0.25 * (0.5 + beta + gamma);
+
+ m_a0 = 2.0 * alpha;
+ m_a1 = 2.0 * -2.0*alpha;
+ m_a2 = 2.0 * alpha;
+ m_b1 = 2.0 * -gamma;
+ m_b2 = 2.0 * beta;
+}
+
+void Biquad::setLowShelfParams(double cutoff, double dbGain)
+{
+ double theta = M_PI * cutoff;
+
+ double A = pow(10.0, dbGain / 40.0);
+ double S = 1.0; // filter slope (1.0 is max value)
+ double alpha = 0.5 * sin(theta) * sqrt((A + 1.0 / A) * (1.0 / S - 1.0) + 2.0);
+
+ double k = cos(theta);
+ double k2 = 2.0 * sqrt(A) * alpha;
+
+ double b0 = A * ((A + 1.0) - (A - 1.0) * k + k2);
+ double b1 = 2.0 * A * ((A - 1.0) - (A + 1.0) * k);
+ double b2 = A * ((A + 1.0) - (A - 1.0) * k - k2);
+ double a0 = (A + 1.0) + (A - 1.0) * k + k2;
+ double a1 = -2.0 * ((A - 1.0) + (A + 1.0) * k);
+ double a2 = (A + 1.0) + (A - 1.0) * k - k2;
+
+ double a0Inverse = 1.0 / a0;
+
+ m_a0 = b0 * a0Inverse;
+ m_a1 = b1 * a0Inverse;
+ m_a2 = b2 * a0Inverse;
+ m_b1 = a1 * a0Inverse;
+ m_b2 = a2 * a0Inverse;
+}
+
+void Biquad::setZeroPolePairs(const Complex &zero, const Complex &pole)
+{
+ m_a0 = 1.0;
+ m_a1 = -2.0 * zero.real();
+
+ double zeroMag = abs(zero);
+ m_a2 = zeroMag * zeroMag;
+
+ m_b1 = -2.0 * pole.real();
+
+ double poleMag = abs(pole);
+ m_b2 = poleMag * poleMag;
+}
+
+void Biquad::setAllpassPole(const Complex &pole)
+{
+ Complex zero = Complex(1.0, 0.0) / pole;
+ setZeroPolePairs(zero, pole);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/Biquad.h b/WebCore/platform/audio/Biquad.h
new file mode 100644
index 0000000..d68bf4e
--- /dev/null
+++ b/WebCore/platform/audio/Biquad.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Biquad_h
+#define Biquad_h
+
+#include "AudioArray.h"
+#include <sys/types.h>
+#include <wtf/Complex.h>
+#include <wtf/Platform.h>
+
+namespace WebCore {
+
+// A basic biquad (two-zero / two-pole digital filter)
+//
+// It can be configured to a number of common and very useful filters:
+// lowpass, highpass, shelving, parameteric, notch, allpass, ...
+
+class Biquad {
+public:
+ Biquad();
+ virtual ~Biquad() { }
+
+ void process(const float* sourceP, float* destP, size_t framesToProcess);
+
+ // cutoff is 0-1 normalized, resonance is in dB >= 0.0
+ void setLowpassParams(double cutoff, double resonance);
+ void setHighpassParams(double cutoff, double resonance);
+
+ void setLowShelfParams(double cutoff, double dbGain);
+
+ // FIXME: need to implement a few more common filters
+ // void setHighShelfParams(double cutoff, double dbGain);
+ // void setParametricEQParams(double cutoff, double resonance);
+
+ // Set the biquad coefficients given a single zero (other zero will be conjugate)
+ // and a single pole (other pole will be conjugate)
+ void setZeroPolePairs(const Complex& zero, const Complex& pole);
+
+ // Set the biquad coefficients given a single pole (other pole will be conjugate)
+ // (The zeroes will be the inverse of the poles)
+ void setAllpassPole(const Complex& pole);
+
+ // Resets filter state
+ void reset();
+
+private:
+ // Filter coefficients
+ double m_a0;
+ double m_a1;
+ double m_a2;
+ double m_b1;
+ double m_b2;
+
+ double m_g;
+
+ // Filter memory
+ double m_x1; // input delayed by 1 sample
+ double m_x2; // input delayed by 2 samples
+ double m_y1; // output delayed by 1 sample
+ double m_y2; // output delayed by 2 samples
+
+#if OS(DARWIN)
+ void processFast(const float* sourceP, float* destP, size_t framesToProcess);
+ void processSliceFast(double* sourceP, double* destP, double* coefficientsP, size_t framesToProcess);
+
+ AudioDoubleArray m_inputBuffer;
+ AudioDoubleArray m_outputBuffer;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // Biquad_h
diff --git a/WebCore/platform/audio/Distance.cpp b/WebCore/platform/audio/Distance.cpp
new file mode 100644
index 0000000..0f1b005
--- /dev/null
+++ b/WebCore/platform/audio/Distance.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "Distance.h"
+
+#include <algorithm>
+#include <math.h>
+
+using namespace std;
+
+namespace WebCore {
+
+DistanceEffect::DistanceEffect()
+ : m_model(ModelInverse)
+ , m_isClamped(true)
+ , m_refDistance(1.0)
+ , m_maxDistance(10000.0)
+ , m_rolloffFactor(1.0)
+{
+}
+
+double DistanceEffect::gain(double distance)
+{
+ // don't go beyond maximum distance
+ distance = min(distance, m_maxDistance);
+
+ // if clamped, don't get closer than reference distance
+ if (m_isClamped)
+ distance = max(distance, m_refDistance);
+
+ switch (m_model) {
+ case ModelLinear:
+ return linearGain(distance);
+ break;
+ case ModelInverse:
+ return inverseGain(distance);
+ break;
+ case ModelExponential:
+ return exponentialGain(distance);
+ break;
+
+ default:
+ return 0.0;
+ }
+}
+
+double DistanceEffect::linearGain(double distance)
+{
+ return (1.0 - m_rolloffFactor * (distance - m_refDistance)) / (m_maxDistance - m_refDistance);
+}
+
+double DistanceEffect::inverseGain(double distance)
+{
+ return m_refDistance / (m_refDistance + m_rolloffFactor * (distance - m_refDistance));
+}
+
+double DistanceEffect::exponentialGain(double distance)
+{
+ return pow(distance / m_refDistance, -m_rolloffFactor);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/Distance.h b/WebCore/platform/audio/Distance.h
new file mode 100644
index 0000000..c7edded
--- /dev/null
+++ b/WebCore/platform/audio/Distance.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Distance_h
+#define Distance_h
+
+namespace WebCore {
+
+// Distance models are defined according to the OpenAL specification
+
+class DistanceEffect {
+public:
+ enum ModelType {
+ ModelLinear = 0,
+ ModelInverse = 1,
+ ModelExponential = 2
+ };
+
+ DistanceEffect();
+
+ // Returns scalar gain for the given distance the current distance model is used
+ double gain(double distance);
+
+ ModelType model() { return m_model; }
+
+ void setModel(ModelType model, bool clamped)
+ {
+ m_model = model;
+ m_isClamped = clamped;
+ }
+
+ // Distance params
+ void setRefDistance(double refDistance) { m_refDistance = refDistance; }
+ void setMaxDistance(double maxDistance) { m_maxDistance = maxDistance; }
+ void setRolloffFactor(double rolloffFactor) { m_rolloffFactor = rolloffFactor; }
+
+ double refDistance() const { return m_refDistance; }
+ double maxDistance() const { return m_maxDistance; }
+ double rolloffFactor() const { return m_rolloffFactor; }
+
+protected:
+ double linearGain(double distance);
+ double inverseGain(double distance);
+ double exponentialGain(double distance);
+
+ ModelType m_model;
+ bool m_isClamped;
+ double m_refDistance;
+ double m_maxDistance;
+ double m_rolloffFactor;
+};
+
+} // namespace WebCore
+
+#endif // Distance_h
diff --git a/WebCore/platform/audio/FFTFrame.cpp b/WebCore/platform/audio/FFTFrame.cpp
new file mode 100644
index 0000000..17292b6
--- /dev/null
+++ b/WebCore/platform/audio/FFTFrame.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "FFTFrame.h"
+
+#include <wtf/Complex.h>
+#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+void FFTFrame::doPaddedFFT(float* data, size_t dataSize)
+{
+ // Zero-pad the impulse response
+ AudioFloatArray paddedResponse(fftSize()); // zero-initialized
+ paddedResponse.copyToRange(data, 0, dataSize);
+
+ // Get the frequency-domain version of padded response
+ doFFT(paddedResponse.data());
+}
+
+PassOwnPtr<FFTFrame> FFTFrame::createInterpolatedFrame(const FFTFrame& frame1, const FFTFrame& frame2, double x)
+{
+ OwnPtr<FFTFrame> newFrame = adoptPtr(new FFTFrame(frame1.fftSize()));
+
+ newFrame->interpolateFrequencyComponents(frame1, frame2, x);
+
+ // In the time-domain, the 2nd half of the response must be zero, to avoid circular convolution aliasing...
+ int fftSize = newFrame->fftSize();
+ AudioFloatArray buffer(fftSize);
+ newFrame->doInverseFFT(buffer.data());
+ buffer.zeroRange(fftSize / 2, fftSize);
+
+ // Put back into frequency domain.
+ newFrame->doFFT(buffer.data());
+
+ return newFrame.release();
+}
+
+void FFTFrame::interpolateFrequencyComponents(const FFTFrame& frame1, const FFTFrame& frame2, double interp)
+{
+ // FIXME : with some work, this method could be optimized
+
+ float* realP = realData();
+ float* imagP = imagData();
+
+ const float* realP1 = frame1.realData();
+ const float* imagP1 = frame1.imagData();
+ const float* realP2 = frame2.realData();
+ const float* imagP2 = frame2.imagData();
+
+ m_FFTSize = frame1.fftSize();
+ m_log2FFTSize = frame1.log2FFTSize();
+
+ double s1base = (1.0 - interp);
+ double s2base = interp;
+
+ double phaseAccum = 0.0;
+ double lastPhase1 = 0.0;
+ double lastPhase2 = 0.0;
+
+ realP[0] = static_cast<float>(s1base * realP1[0] + s2base * realP2[0]);
+ imagP[0] = static_cast<float>(s1base * imagP1[0] + s2base * imagP2[0]);
+
+ int n = m_FFTSize / 2;
+
+ for (int i = 1; i < n; ++i) {
+ Complex c1(realP1[i], imagP1[i]);
+ Complex c2(realP2[i], imagP2[i]);
+
+ double mag1 = abs(c1);
+ double mag2 = abs(c2);
+
+ // Interpolate magnitudes in decibels
+ double mag1db = 20.0 * log10(mag1);
+ double mag2db = 20.0 * log10(mag2);
+
+ double s1 = s1base;
+ double s2 = s2base;
+
+ double magdbdiff = mag1db - mag2db;
+
+ // Empirical tweak to retain higher-frequency zeroes
+ double threshold = (i > 16) ? 5.0 : 2.0;
+
+ if (magdbdiff < -threshold && mag1db < 0.0) {
+ s1 = pow(s1, 0.75);
+ s2 = 1.0 - s1;
+ } else if (magdbdiff > threshold && mag2db < 0.0) {
+ s2 = pow(s2, 0.75);
+ s1 = 1.0 - s2;
+ }
+
+ // Average magnitude by decibels instead of linearly
+ double magdb = s1 * mag1db + s2 * mag2db;
+ double mag = pow(10.0, 0.05 * magdb);
+
+ // Now, deal with phase
+ double phase1 = arg(c1);
+ double phase2 = arg(c2);
+
+ double deltaPhase1 = phase1 - lastPhase1;
+ double deltaPhase2 = phase2 - lastPhase2;
+ lastPhase1 = phase1;
+ lastPhase2 = phase2;
+
+ // Unwrap phase deltas
+ if (deltaPhase1 > M_PI)
+ deltaPhase1 -= 2.0 * M_PI;
+ if (deltaPhase1 < -M_PI)
+ deltaPhase1 += 2.0 * M_PI;
+ if (deltaPhase2 > M_PI)
+ deltaPhase2 -= 2.0 * M_PI;
+ if (deltaPhase2 < -M_PI)
+ deltaPhase2 += 2.0 * M_PI;
+
+ // Blend group-delays
+ double deltaPhaseBlend;
+
+ if (deltaPhase1 - deltaPhase2 > M_PI)
+ deltaPhaseBlend = s1 * deltaPhase1 + s2 * (2.0 * M_PI + deltaPhase2);
+ else if (deltaPhase2 - deltaPhase1 > M_PI)
+ deltaPhaseBlend = s1 * (2.0 * M_PI + deltaPhase1) + s2 * deltaPhase2;
+ else
+ deltaPhaseBlend = s1 * deltaPhase1 + s2 * deltaPhase2;
+
+ phaseAccum += deltaPhaseBlend;
+
+ // Unwrap
+ if (phaseAccum > M_PI)
+ phaseAccum -= 2.0 * M_PI;
+ if (phaseAccum < -M_PI)
+ phaseAccum += 2.0 * M_PI;
+
+ Complex c = complexFromMagnitudePhase(mag, phaseAccum);
+
+ realP[i] = static_cast<float>(c.real());
+ imagP[i] = static_cast<float>(c.imag());
+ }
+}
+
+double FFTFrame::extractAverageGroupDelay()
+{
+ float* realP = realData();
+ float* imagP = imagData();
+
+ double aveSum = 0.0;
+ double weightSum = 0.0;
+ double lastPhase = 0.0;
+
+ int halfSize = fftSize() / 2;
+
+ const double kSamplePhaseDelay = (2.0 * M_PI) / double(fftSize());
+
+ // Calculate weighted average group delay
+ for (int i = 0; i < halfSize; i++) {
+ Complex c(realP[i], imagP[i]);
+ double mag = abs(c);
+ double phase = arg(c);
+
+ double deltaPhase = phase - lastPhase;
+ lastPhase = phase;
+
+ // Unwrap
+ if (deltaPhase < -M_PI)
+ deltaPhase += 2.0 * M_PI;
+ if (deltaPhase > M_PI)
+ deltaPhase -= 2.0 * M_PI;
+
+ aveSum += mag * deltaPhase;
+ weightSum += mag;
+ }
+
+ // Note how we invert the phase delta wrt frequency since this is how group delay is defined
+ double ave = aveSum / weightSum;
+ double aveSampleDelay = -ave / kSamplePhaseDelay;
+
+ // Leave 20 sample headroom (for leading edge of impulse)
+ if (aveSampleDelay > 20.0)
+ aveSampleDelay -= 20.0;
+
+ // Remove average group delay (minus 20 samples for headroom)
+ addConstantGroupDelay(-aveSampleDelay);
+
+ // Remove DC offset
+ realP[0] = 0.0f;
+
+ return aveSampleDelay;
+}
+
+void FFTFrame::addConstantGroupDelay(double sampleFrameDelay)
+{
+ int halfSize = fftSize() / 2;
+
+ float* realP = realData();
+ float* imagP = imagData();
+
+ const double kSamplePhaseDelay = (2.0 * M_PI) / double(fftSize());
+
+ double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay;
+
+ // Add constant group delay
+ for (int i = 1; i < halfSize; i++) {
+ Complex c(realP[i], imagP[i]);
+ double mag = abs(c);
+ double phase = arg(c);
+
+ phase += i * phaseAdj;
+
+ Complex c2 = complexFromMagnitudePhase(mag, phase);
+
+ realP[i] = static_cast<float>(c2.real());
+ imagP[i] = static_cast<float>(c2.imag());
+ }
+}
+
+#ifndef NDEBUG
+void FFTFrame::print()
+{
+ FFTFrame& frame = *this;
+ float* realP = frame.realData();
+ float* imagP = frame.imagData();
+ printf("**** \n");
+ printf("DC = %f : nyquist = %f\n", realP[0], imagP[0]);
+
+ int n = m_FFTSize / 2;
+
+ for (int i = 1; i < n; i++) {
+ double mag = sqrt(realP[i] * realP[i] + imagP[i] * imagP[i]);
+ double phase = atan2(realP[i], imagP[i]);
+
+ printf("[%d] (%f %f)\n", i, mag, phase);
+ }
+ printf("****\n");
+}
+#endif // NDEBUG
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/FFTFrame.h b/WebCore/platform/audio/FFTFrame.h
new file mode 100644
index 0000000..6147fc1
--- /dev/null
+++ b/WebCore/platform/audio/FFTFrame.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FFTFrame_h
+#define FFTFrame_h
+
+#include "AudioArray.h"
+
+#if OS(DARWIN)
+#include <Accelerate/Accelerate.h>
+#endif
+
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Platform.h>
+
+namespace WebCore {
+
+// Defines the interface for an "FFT frame", an object which is able to perform a forward
+// and reverse FFT, internally storing the resultant frequency-domain data.
+
+class FFTFrame {
+public:
+ // The constructors, destructor, and methods up to the CROSS-PLATFORM section have platform-dependent implementations.
+
+ FFTFrame(unsigned fftSize);
+ FFTFrame(); // creates a blank/empty frame for later use with createInterpolatedFrame()
+ FFTFrame(const FFTFrame& frame);
+ ~FFTFrame();
+
+ static void cleanup();
+ void doFFT(float* data);
+ void doInverseFFT(float* data);
+ void multiply(const FFTFrame& frame); // multiplies ourself with frame : effectively operator*=()
+
+ float* realData() const;
+ float* imagData() const;
+
+ void print(); // for debugging
+
+ // CROSS-PLATFORM
+ // The remaining public methods have cross-platform implementations:
+
+ // Interpolates from frame1 -> frame2 as x goes from 0.0 -> 1.0
+ static PassOwnPtr<FFTFrame> createInterpolatedFrame(const FFTFrame& frame1, const FFTFrame& frame2, double x);
+
+ void doPaddedFFT(float* data, size_t dataSize); // zero-padding with dataSize <= fftSize
+ double extractAverageGroupDelay();
+ void addConstantGroupDelay(double sampleFrameDelay);
+
+ unsigned fftSize() const { return m_FFTSize; }
+ unsigned log2FFTSize() const { return m_log2FFTSize; }
+
+private:
+ unsigned m_FFTSize;
+ unsigned m_log2FFTSize;
+
+ void interpolateFrequencyComponents(const FFTFrame& frame1, const FFTFrame& frame2, double x);
+
+#if OS(DARWIN)
+ DSPSplitComplex& dspSplitComplex() { return m_frame; }
+ DSPSplitComplex dspSplitComplex() const { return m_frame; }
+
+ static FFTSetup fftSetupForSize(unsigned fftSize);
+
+ static FFTSetup* fftSetups;
+
+ FFTSetup m_FFTSetup;
+
+ DSPSplitComplex m_frame;
+ AudioFloatArray m_realData;
+ AudioFloatArray m_imagData;
+#endif // OS(DARWIN)
+};
+
+} // namespace WebCore
+
+#endif // FFTFrame_h
diff --git a/WebCore/platform/audio/Panner.cpp b/WebCore/platform/audio/Panner.cpp
new file mode 100644
index 0000000..29a1fbe
--- /dev/null
+++ b/WebCore/platform/audio/Panner.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "Panner.h"
+
+#include "EqualPowerPanner.h"
+#include "HRTFPanner.h"
+#include "PassThroughPanner.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+PassOwnPtr<Panner> Panner::create(PanningModel model, double sampleRate)
+{
+ OwnPtr<Panner> panner;
+
+ switch (model) {
+ case PanningModelEqualPower:
+ panner = adoptPtr(new EqualPowerPanner());
+ break;
+
+ case PanningModelHRTF:
+ panner = adoptPtr(new HRTFPanner(sampleRate));
+ break;
+
+ case PanningModelPassthrough:
+ panner = adoptPtr(new PassThroughPanner());
+ break;
+
+ // FIXME: sound field panning is not yet implemented...
+ case PanningModelSoundField:
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+ return panner.release();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/Panner.h b/WebCore/platform/audio/Panner.h
new file mode 100644
index 0000000..c8e219b
--- /dev/null
+++ b/WebCore/platform/audio/Panner.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Panner_h
+#define Panner_h
+
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class AudioBus;
+
+// Abstract base class for panning a mono or stereo source.
+
+class Panner {
+public:
+ enum {
+ PanningModelPassthrough = 0,
+ PanningModelEqualPower = 1,
+ PanningModelHRTF = 2,
+ PanningModelSoundField = 3
+ };
+
+ typedef unsigned PanningModel;
+
+ static PassOwnPtr<Panner> create(PanningModel model, double sampleRate);
+
+ virtual ~Panner() { };
+
+ PanningModel panningModel() const { return m_panningModel; }
+
+ virtual void pan(double azimuth, double elevation, AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess) = 0;
+
+ virtual void reset() = 0;
+
+protected:
+ Panner(PanningModel model) : m_panningModel(model) { }
+
+ PanningModel m_panningModel;
+};
+
+} // namespace WebCore
+
+#endif // Panner_h
diff --git a/WebCore/platform/audio/mac/FFTFrameMac.cpp b/WebCore/platform/audio/mac/FFTFrameMac.cpp
new file mode 100644
index 0000000..0f7efb7
--- /dev/null
+++ b/WebCore/platform/audio/mac/FFTFrameMac.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Mac OS X - specific FFTFrame implementation
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "FFTFrame.h"
+
+namespace WebCore {
+
+const int kMaxFFTPow2Size = 24;
+
+FFTSetup* FFTFrame::fftSetups = 0;
+
+// Normal constructor: allocates for a given fftSize
+FFTFrame::FFTFrame(unsigned fftSize)
+ : m_realData(fftSize)
+ , m_imagData(fftSize)
+{
+ m_FFTSize = fftSize;
+ m_log2FFTSize = static_cast<unsigned>(log2(fftSize));
+
+ // We only allow power of two
+ ASSERT(1UL << m_log2FFTSize == m_FFTSize);
+
+ // Lazily create and share fftSetup with other frames
+ m_FFTSetup = fftSetupForSize(fftSize);
+
+ // Setup frame data
+ m_frame.realp = m_realData.data();
+ m_frame.imagp = m_imagData.data();
+}
+
+// Creates a blank/empty frame (interpolate() must later be called)
+FFTFrame::FFTFrame()
+ : m_realData(0)
+ , m_imagData(0)
+{
+ // Later will be set to correct values when interpolate() is called
+ m_frame.realp = 0;
+ m_frame.imagp = 0;
+
+ m_FFTSize = 0;
+ m_log2FFTSize = 0;
+}
+
+// Copy constructor
+FFTFrame::FFTFrame(const FFTFrame& frame)
+ : m_FFTSize(frame.m_FFTSize)
+ , m_log2FFTSize(frame.m_log2FFTSize)
+ , m_FFTSetup(frame.m_FFTSetup)
+ , m_realData(frame.m_FFTSize)
+ , m_imagData(frame.m_FFTSize)
+{
+ // Setup frame data
+ m_frame.realp = m_realData.data();
+ m_frame.imagp = m_imagData.data();
+
+ // Copy/setup frame data
+ unsigned nbytes = sizeof(float) * m_FFTSize;
+ memcpy(realData(), frame.m_frame.realp, nbytes);
+ memcpy(imagData(), frame.m_frame.imagp, nbytes);
+}
+
+FFTFrame::~FFTFrame()
+{
+}
+
+void FFTFrame::multiply(const FFTFrame& frame)
+{
+ FFTFrame& frame1 = *this;
+ const FFTFrame& frame2 = frame;
+
+ float* realP1 = frame1.realData();
+ float* imagP1 = frame1.imagData();
+ const float* realP2 = frame2.realData();
+ const float* imagP2 = frame2.imagData();
+
+ // Scale accounts for vecLib's peculiar scaling
+ // This ensures the right scaling all the way back to inverse FFT
+ float scale = 0.5f;
+
+ // Multiply packed DC/nyquist component
+ realP1[0] *= scale * realP2[0];
+ imagP1[0] *= scale * imagP2[0];
+
+ // Multiply the rest, skipping packed DC/Nyquist components
+ DSPSplitComplex sc1 = frame1.dspSplitComplex();
+ sc1.realp++;
+ sc1.imagp++;
+
+ DSPSplitComplex sc2 = frame2.dspSplitComplex();
+ sc2.realp++;
+ sc2.imagp++;
+
+ unsigned halfSize = m_FFTSize / 2;
+
+ // Complex multiply
+ vDSP_zvmul(&sc1, 1, &sc2, 1, &sc1, 1, halfSize - 1, 1 /* normal multiplication */);
+
+ // We've previously scaled the packed part, now scale the rest.....
+ vDSP_vsmul(sc1.realp, 1, &scale, sc1.realp, 1, halfSize - 1);
+ vDSP_vsmul(sc1.imagp, 1, &scale, sc1.imagp, 1, halfSize - 1);
+}
+
+void FFTFrame::doFFT(float* data)
+{
+ vDSP_ctoz((DSPComplex*)data, 2, &m_frame, 1, m_FFTSize / 2);
+ vDSP_fft_zrip(m_FFTSetup, &m_frame, 1, m_log2FFTSize, FFT_FORWARD);
+}
+
+void FFTFrame::doInverseFFT(float* data)
+{
+ vDSP_fft_zrip(m_FFTSetup, &m_frame, 1, m_log2FFTSize, FFT_INVERSE);
+ vDSP_ztoc(&m_frame, 1, (DSPComplex*)data, 2, m_FFTSize / 2);
+
+ // Do final scaling so that x == IFFT(FFT(x))
+ float scale = 0.5f / m_FFTSize;
+ vDSP_vsmul(data, 1, &scale, data, 1, m_FFTSize);
+}
+
+FFTSetup FFTFrame::fftSetupForSize(unsigned fftSize)
+{
+ if (!fftSetups) {
+ fftSetups = (FFTSetup*)malloc(sizeof(FFTSetup) * kMaxFFTPow2Size);
+ memset(fftSetups, 0, sizeof(FFTSetup) * kMaxFFTPow2Size);
+ }
+
+ int pow2size = static_cast<int>(log2(fftSize));
+ ASSERT(pow2size < kMaxFFTPow2Size);
+ if (!fftSetups[pow2size])
+ fftSetups[pow2size] = vDSP_create_fftsetup(pow2size, FFT_RADIX2);
+
+ return fftSetups[pow2size];
+}
+
+void FFTFrame::cleanup()
+{
+ if (!fftSetups)
+ return;
+
+ for (int i = 0; i < kMaxFFTPow2Size; ++i) {
+ if (fftSetups[i])
+ vDSP_destroy_fftsetup(fftSetups[i]);
+ }
+
+ free(fftSetups);
+ fftSetups = 0;
+}
+
+float* FFTFrame::realData() const
+{
+ return m_frame.realp;
+}
+
+float* FFTFrame::imagData() const
+{
+ return m_frame.imagp;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index bc86de2..894799c 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -190,6 +190,9 @@ namespace WebCore {
// That is committed size for Windows and virtual memory size for POSIX
static int memoryUsageMB();
+ // Same as above, but always returns actual value, without any caches.
+ static int actualMemoryUsageMB();
+
// MimeType -----------------------------------------------------------
static bool isSupportedImageMIMEType(const String& mimeType);
static bool isSupportedJavaScriptMIMEType(const String& mimeType);
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index 23508a6..aff1466 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -533,7 +533,7 @@ void ClipboardChromium::writeRange(Range* selectedRange, Frame* frame)
m_dataObject->textHtml = createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs);
m_dataObject->htmlBaseUrl = frame->document()->url();
- String str = frame->selectedText();
+ String str = frame->editor()->selectedText();
#if OS(WINDOWS)
replaceNewlinesWithWindowsStyleNewlines(str);
#endif
diff --git a/WebCore/platform/chromium/PasteboardChromium.cpp b/WebCore/platform/chromium/PasteboardChromium.cpp
index 58373b1..ba69b00 100644
--- a/WebCore/platform/chromium/PasteboardChromium.cpp
+++ b/WebCore/platform/chromium/PasteboardChromium.cpp
@@ -84,7 +84,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
String html = createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs);
ExceptionCode ec = 0;
KURL url = selectedRange->startContainer(ec)->document()->url();
- String plainText = frame->selectedText();
+ String plainText = frame->editor()->selectedText();
#if OS(WINDOWS)
replaceNewlinesWithWindowsStyleNewlines(plainText);
#endif
diff --git a/WebCore/platform/efl/ScrollbarEfl.cpp b/WebCore/platform/efl/ScrollbarEfl.cpp
index e413260..6b00a37 100644
--- a/WebCore/platform/efl/ScrollbarEfl.cpp
+++ b/WebCore/platform/efl/ScrollbarEfl.cpp
@@ -84,7 +84,7 @@ static void scrollbarEflEdjeMessage(void* data, Evas_Object* o, Edje_Message_Typ
m = static_cast<Edje_Message_Float*>(msg);
v = m->val * (that->totalSize() - that->visibleSize());
- that->setValue(v);
+ that->setValue(v, Scrollbar::NotFromScrollAnimator);
}
void ScrollbarEfl::setParent(ScrollView* view)
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 0e93d4f..a0cf5a4 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -277,6 +277,8 @@ Font::CodePath Font::codePath(const TextRun& run) const
return Complex;
#endif
+ CodePath result = Simple;
+
// Start from 0 since drawing and highlighting also measure the characters before run->from
for (int i = 0; i < run.length(); i++) {
const UChar c = run[i];
@@ -312,8 +314,10 @@ Font::CodePath Font::codePath(const TextRun& run) const
if (c < 0x1E00) // U+1E00 through U+2000 characters with diacritics and stacked diacritics
continue;
- if (c <= 0x2000)
- return SimpleWithGlyphOverflow;
+ if (c <= 0x2000) {
+ result = SimpleWithGlyphOverflow;
+ continue;
+ }
if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols
continue;
@@ -329,7 +333,7 @@ Font::CodePath Font::codePath(const TextRun& run) const
if (typesettingFeatures())
return Complex;
- return Simple;
+ return result;
}
}
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index 94f3424..3dfdb20 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -467,7 +467,7 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS
{
if (paintingDisabled() || !image)
return;
-
+
float tsw = src.width();
float tsh = src.height();
float tw = dest.width();
@@ -489,7 +489,7 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS
}
image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
-
+
if (useLowQualityScale)
restore();
}
@@ -571,6 +571,21 @@ void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle&)
}
#endif
+#if !PLATFORM(SKIA)
+void GraphicsContext::setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&)
+{
+}
+
+void GraphicsContext::syncSoftwareCanvas()
+{
+}
+
+void GraphicsContext::markDirtyRect(const IntRect&)
+{
+}
+#endif
+
+
void GraphicsContext::adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, const StrokeStyle& penStyle)
{
// For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
@@ -600,14 +615,4 @@ void GraphicsContext::adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2
}
}
-#if !PLATFORM(SKIA)
-void GraphicsContext::setGraphicsContext3D(GraphicsContext3D*, const IntSize&)
-{
-}
-
-void GraphicsContext::syncSoftwareCanvas()
-{
-}
-#endif
-
}
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index c5440f3..7863b95 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -21,7 +21,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GraphicsContext_h
@@ -131,16 +131,17 @@ namespace WebCore {
const int cMisspellingLinePatternGapWidth = 1;
class AffineTransform;
+ class DrawingBuffer;
class Font;
class Generator;
class Gradient;
- class GraphicsContext3D;
class GraphicsContextPlatformPrivate;
class GraphicsContextPrivate;
class ImageBuffer;
class KURL;
class Path;
class Pattern;
+ class SharedGraphicsContext3D;
class TextRun;
// These bits can be ORed together for a total of 8 possible text drawing modes.
@@ -456,8 +457,9 @@ namespace WebCore {
pattern getHaikuStrokeStyle();
#endif
- void setGraphicsContext3D(GraphicsContext3D*, const IntSize&);
+ void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
void syncSoftwareCanvas();
+ void markDirtyRect(const IntRect&); // Hints that a portion of the backing store is dirty.
private:
void savePlatformState();
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 0f74cd5..68a580e 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -85,18 +85,18 @@ class FloatPoint3D;
class GraphicsContext;
class Image;
class TextStream;
-struct TimingFunction;
+class TimingFunction;
// Base class for animation values (also used for transitions). Here to
// represent values for properties being animated via the GraphicsLayer,
// without pulling in style-related data from outside of the platform directory.
class AnimationValue : public Noncopyable {
public:
- AnimationValue(float keyTime, const TimingFunction* timingFunction = 0)
+ AnimationValue(float keyTime, PassRefPtr<TimingFunction> timingFunction = 0)
: m_keyTime(keyTime)
{
if (timingFunction)
- m_timingFunction = adoptPtr(new TimingFunction(*timingFunction));
+ m_timingFunction = timingFunction;
}
virtual ~AnimationValue() { }
@@ -106,13 +106,13 @@ public:
private:
float m_keyTime;
- OwnPtr<TimingFunction> m_timingFunction;
+ RefPtr<TimingFunction> m_timingFunction;
};
// Used to store one float value of an animation.
class FloatAnimationValue : public AnimationValue {
public:
- FloatAnimationValue(float keyTime, float value, const TimingFunction* timingFunction = 0)
+ FloatAnimationValue(float keyTime, float value, PassRefPtr<TimingFunction> timingFunction = 0)
: AnimationValue(keyTime, timingFunction)
, m_value(value)
{
@@ -127,7 +127,7 @@ private:
// Used to store one transform value in a keyframe list.
class TransformAnimationValue : public AnimationValue {
public:
- TransformAnimationValue(float keyTime, const TransformOperations* value = 0, const TimingFunction* timingFunction = 0)
+ TransformAnimationValue(float keyTime, const TransformOperations* value = 0, PassRefPtr<TimingFunction> timingFunction = 0)
: AnimationValue(keyTime, timingFunction)
{
if (value)
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index a5db85f..2588d8d 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -699,6 +699,12 @@ void MediaPlayer::rateChanged()
m_mediaPlayerClient->mediaPlayerRateChanged(this);
}
+void MediaPlayer::playbackStateChanged()
+{
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerPlaybackStateChanged(this);
+}
+
}
#endif
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index 643f17f..bf445e3 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -70,6 +70,7 @@ struct PlatformMedia {
QTMovieVisualContextType,
GStreamerGWorldType,
ChromiumMediaPlayerType,
+ QtMediaPlayerType,
} type;
union {
@@ -78,6 +79,7 @@ struct PlatformMedia {
QTMovieVisualContext* qtMovieVisualContext;
GStreamerGWorld* gstreamerGWorld;
MediaPlayerPrivateInterface* chromiumMediaPlayer;
+ MediaPlayerPrivateInterface* qtMediaPlayer;
} media;
};
@@ -119,6 +121,9 @@ public:
// the playback rate has changed
virtual void mediaPlayerRateChanged(MediaPlayer*) { }
+ // the play/pause status changed
+ virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*) { }
+
// The MediaPlayer has found potentially problematic media content.
// This is used internally to trigger swapping from a <video>
// element to an <embed> in standalone documents
@@ -244,6 +249,7 @@ public:
void timeChanged();
void sizeChanged();
void rateChanged();
+ void playbackStateChanged();
void durationChanged();
void repaint();
diff --git a/WebCore/platform/graphics/Path.cpp b/WebCore/platform/graphics/Path.cpp
index 333afcb..4e2de53 100644
--- a/WebCore/platform/graphics/Path.cpp
+++ b/WebCore/platform/graphics/Path.cpp
@@ -39,7 +39,7 @@ static const float QUARTER = 0.552f; // approximation of control point positions
// to simulate a quarter of a circle.
namespace WebCore {
-#if !PLATFORM(OPENVG)
+#if !PLATFORM(OPENVG) && !PLATFORM(QT)
static void pathLengthApplierFunction(void* info, const PathElement* element)
{
PathTraversalState& traversalState = *static_cast<PathTraversalState*>(info);
diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h
index 61ea328..9896713 100644
--- a/WebCore/platform/graphics/Path.h
+++ b/WebCore/platform/graphics/Path.h
@@ -133,6 +133,11 @@ namespace WebCore {
void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);
void addArcTo(const FloatPoint&, const FloatPoint&, float radius);
void closeSubpath();
+#if PLATFORM(QT)
+ void closeCanvasSubpath();
+#else
+ void closeCanvasSubpath() { closeSubpath(); }
+#endif
void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
void addRect(const FloatRect&);
diff --git a/WebCore/platform/graphics/cairo/FontCacheCairo.cpp b/WebCore/platform/graphics/cairo/FontCacheCairo.cpp
index cb54549..5d3263e 100644
--- a/WebCore/platform/graphics/cairo/FontCacheCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCacheCairo.cpp
@@ -23,7 +23,7 @@
#include "CString.h"
#include "Font.h"
-#include "GOwnPtrCairo.h"
+#include "OwnPtrCairo.h"
#include "SimpleFontData.h"
#include <wtf/Assertions.h>
@@ -115,15 +115,15 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
CString familyNameString = family.string().utf8();
const char* fcfamily = familyNameString.data();
- GOwnPtr<FcPattern> pattern(FcPatternCreate());
+ OwnPtr<FcPattern> pattern(FcPatternCreate());
if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
return 0;
- GOwnPtr<FcObjectSet> objectSet(FcObjectSetCreate());
+ OwnPtr<FcObjectSet> objectSet(FcObjectSetCreate());
if (!FcObjectSetAdd(objectSet.get(), FC_FAMILY))
return 0;
- GOwnPtr<FcFontSet> fontSet(FcFontList(0, pattern.get(), objectSet.get()));
+ OwnPtr<FcFontSet> fontSet(FcFontList(0, pattern.get(), objectSet.get()));
if (!fontSet)
return 0;
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 19cc518..283e75a 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -562,7 +562,7 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin
cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
cairo_antialias_t savedAntialiasRule = cairo_get_antialias(cr);
- cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);
+ cairo_set_antialias(cr, antialiased ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
addConvexPolygonToContext(cr, numPoints, points);
cairo_clip(cr);
diff --git a/WebCore/platform/graphics/cairo/GOwnPtrCairo.cpp b/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp
index 12df3cf..9be8670 100644
--- a/WebCore/platform/graphics/cairo/GOwnPtrCairo.cpp
+++ b/WebCore/platform/graphics/cairo/OwnPtrCairo.cpp
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "GOwnPtrCairo.h"
+#include "OwnPtrCairo.h"
#if defined(USE_FREETYPE)
#include <cairo-ft.h>
@@ -28,19 +28,19 @@
namespace WTF {
#if defined(USE_FREETYPE)
-template <> void freeOwnedGPtr<FcPattern>(FcPattern* ptr)
+template <> void deleteOwnedPtr<FcPattern>(FcPattern* ptr)
{
if (ptr)
FcPatternDestroy(ptr);
}
-template <> void freeOwnedGPtr<FcObjectSet>(FcObjectSet* ptr)
+template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet* ptr)
{
if (ptr)
FcObjectSetDestroy(ptr);
}
-template <> void freeOwnedGPtr<FcFontSet>(FcFontSet* ptr)
+template <> void deleteOwnedPtr<FcFontSet>(FcFontSet* ptr)
{
if (ptr)
FcFontSetDestroy(ptr);
diff --git a/WebCore/platform/graphics/cairo/GOwnPtrCairo.h b/WebCore/platform/graphics/cairo/OwnPtrCairo.h
index b099707..29f4562 100644
--- a/WebCore/platform/graphics/cairo/GOwnPtrCairo.h
+++ b/WebCore/platform/graphics/cairo/OwnPtrCairo.h
@@ -17,10 +17,10 @@
* Boston, MA 02110-1301 USA
*/
-#ifndef GOwnPtrCairo_h
-#define GOwnPtrCairo_h
+#ifndef OwnPtrCairo_h
+#define OwnPtrCairo_h
-#include "GOwnPtr.h"
+#include "OwnPtr.h"
#if defined(USE_FREETYPE)
typedef struct _FcPattern FcPattern;
@@ -31,9 +31,9 @@ typedef struct _FcFontSet FcFontSet;
namespace WTF {
#if defined(USE_FREETYPE)
-template <> void freeOwnedGPtr<FcPattern>(FcPattern*);
-template <> void freeOwnedGPtr<FcObjectSet>(FcObjectSet*);
-template <> void freeOwnedGPtr<FcFontSet>(FcFontSet*);
+template <> void deleteOwnedPtr<FcPattern>(FcPattern*);
+template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet*);
+template <> void deleteOwnedPtr<FcFontSet>(FcFontSet*);
#endif
} // namespace WTF
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index c4008cc..fadc385 100644
--- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -119,6 +119,7 @@ bool GraphicsContext3D::getImageData(Image* image,
default:
return false;
}
+ break;
case kCGImageAlphaNone:
switch (componentsPerPixel) {
case 1:
diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
new file mode 100644
index 0000000..9826c3e
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "Canvas2DLayerChromium.h"
+
+#include "DrawingBuffer.h"
+
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+PassRefPtr<Canvas2DLayerChromium> Canvas2DLayerChromium::create(DrawingBuffer* drawingBuffer, GraphicsLayerChromium* owner)
+{
+ return adoptRef(new Canvas2DLayerChromium(drawingBuffer, owner));
+}
+
+Canvas2DLayerChromium::Canvas2DLayerChromium(DrawingBuffer* drawingBuffer, GraphicsLayerChromium* owner)
+ : CanvasLayerChromium(owner)
+ , m_drawingBuffer(drawingBuffer)
+{
+}
+
+Canvas2DLayerChromium::~Canvas2DLayerChromium()
+{
+ if (m_textureId)
+ glDeleteTextures(1, &m_textureId);
+}
+
+void Canvas2DLayerChromium::updateContents()
+{
+ if (!m_drawingBuffer)
+ return;
+ if (m_textureChanged) { // We have to generate a new backing texture.
+ if (m_textureId)
+ glDeleteTextures(1, &m_textureId);
+ glGenTextures(1, &m_textureId);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureId);
+ IntSize size = m_drawingBuffer->size();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE
+ // to get around NPOT texture limitations of GLES.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ m_textureChanged = false;
+ // FIXME: The glFinish() here is required because we have to make sure that the texture created in this
+ // context (the compositor context) is actually created by the service side before the child context
+ // attempts to use it (in publishToPlatformLayer). glFinish() is currently the only call with strong
+ // enough semantics to promise this, but is actually much stronger. Ideally we'd do something like
+ // inserting a fence here and waiting for it before trying to publish.
+ glFinish();
+ }
+ // Update the contents of the texture used by the compositor.
+ if (m_contentsDirty) {
+ m_drawingBuffer->publishToPlatformLayer();
+ m_contentsDirty = false;
+ }
+}
+
+void Canvas2DLayerChromium::setTextureChanged()
+{
+ m_textureChanged = true;
+}
+
+unsigned Canvas2DLayerChromium::textureId() const
+{
+ return m_textureId;
+}
+
+void Canvas2DLayerChromium::setDrawingBuffer(DrawingBuffer* drawingBuffer)
+{
+ if (drawingBuffer != m_drawingBuffer) {
+ m_drawingBuffer = drawingBuffer;
+ m_textureChanged = true;
+ }
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
new file mode 100644
index 0000000..0031229
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef Canvas2DLayerChromium_h
+#define Canvas2DLayerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "CanvasLayerChromium.h"
+
+namespace WebCore {
+
+class DrawingBuffer;
+
+// A layer containing an accelerated 2d canvas
+class Canvas2DLayerChromium : public CanvasLayerChromium {
+public:
+ static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner);
+ virtual ~Canvas2DLayerChromium();
+ virtual bool drawsContent() { return true; }
+ virtual void updateContents();
+
+ void setTextureChanged();
+ unsigned textureId() const;
+ void setDrawingBuffer(DrawingBuffer*);
+
+private:
+ explicit Canvas2DLayerChromium(DrawingBuffer*, GraphicsLayerChromium* owner);
+ DrawingBuffer* m_drawingBuffer;
+
+ static unsigned m_shaderProgramId;
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
index bbf091c..56a7262 100644
--- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
@@ -34,12 +34,14 @@
#include "CanvasLayerChromium.h"
-#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
+
#include <GLES2/gl2.h>
namespace WebCore {
+unsigned CanvasLayerChromium::m_shaderProgramId = 0;
+
CanvasLayerChromium::SharedValues::SharedValues()
: m_canvasShaderProgram(0)
, m_shaderSamplerLocation(-1)
@@ -93,49 +95,15 @@ CanvasLayerChromium::SharedValues::~SharedValues()
GLC(glDeleteProgram(m_canvasShaderProgram));
}
-PassRefPtr<CanvasLayerChromium> CanvasLayerChromium::create(GraphicsLayerChromium* owner)
-{
- return adoptRef(new CanvasLayerChromium(owner));
-}
-
CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
- , m_context(0)
+ , m_textureChanged(true)
, m_textureId(0)
- , m_textureChanged(false)
-{
-}
-
-void CanvasLayerChromium::updateContents()
{
- ASSERT(m_context);
- if (m_textureChanged) {
- glBindTexture(GL_TEXTURE_2D, m_textureId);
- // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE
- // to get around NPOT texture limitations of GLES.
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- m_textureChanged = false;
- }
- // Update the contents of the texture used by the compositor.
- if (m_contentsDirty) {
- if (m_prepareTextureCallback)
- m_prepareTextureCallback->willPrepareTexture();
- m_context->prepareTexture();
- m_contentsDirty = false;
- }
}
-void CanvasLayerChromium::setContext(const GraphicsContext3D* context)
+CanvasLayerChromium::~CanvasLayerChromium()
{
- m_context = const_cast<GraphicsContext3D*>(context);
-
- unsigned int textureId = m_context->platformTexture();
- if (textureId != m_textureId)
- m_textureChanged = true;
- m_textureId = textureId;
}
void CanvasLayerChromium::draw()
@@ -150,6 +118,7 @@ void CanvasLayerChromium::draw()
drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
bounds().width(), bounds().height(), drawOpacity(),
sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
+
}
}
diff --git a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
index 053efff..d591c73 100644
--- a/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
@@ -38,17 +38,12 @@
namespace WebCore {
-class GraphicsContext3D;
-
-// A Layer containing a WebGL or accelerated 2d canvas
+// Base class for WebGL and accelerated 2d canvases.
class CanvasLayerChromium : public LayerChromium {
public:
- static PassRefPtr<CanvasLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual bool drawsContent() { return m_context; }
- virtual void updateContents();
- virtual void draw();
+ virtual ~CanvasLayerChromium();
- void setContext(const GraphicsContext3D* context);
+ virtual void draw();
class SharedValues {
public:
@@ -69,21 +64,16 @@ public:
bool m_initialized;
};
- class PrepareTextureCallback : public Noncopyable {
- public:
- virtual void willPrepareTexture() = 0;
- };
- void setPrepareTextureCallback(PassOwnPtr<PrepareTextureCallback> callback) { m_prepareTextureCallback = callback; }
-
-private:
+protected:
explicit CanvasLayerChromium(GraphicsLayerChromium* owner);
- GraphicsContext3D* m_context;
- unsigned m_textureId;
bool m_textureChanged;
- OwnPtr<PrepareTextureCallback> m_prepareTextureCallback;
+ unsigned m_textureId;
+
+private:
+ static unsigned m_shaderProgramId;
};
}
#endif // USE(ACCELERATED_COMPOSITING)
-#endif
+#endif // CanvasLayerChromium_h
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
index 974933d..48119bb 100644
--- a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -42,6 +42,8 @@
#include "PlatformContextSkia.h"
#include "skia/ext/platform_canvas.h"
#elif PLATFORM(CG)
+#include "LocalCurrentGraphicsContext.h"
+
#include <CoreGraphics/CGBitmapContext.h>
#endif
@@ -152,12 +154,6 @@ void ContentLayerChromium::updateContents()
IntSize requiredTextureSize;
IntSize bitmapSize;
-#if PLATFORM(SKIA)
- const SkBitmap* skiaBitmap = 0;
- OwnPtr<skia::PlatformCanvas> canvas;
- OwnPtr<PlatformContextSkia> skiaContext;
- OwnPtr<GraphicsContext> graphicsContext;
-
requiredTextureSize = m_bounds;
IntRect boundsRect(IntPoint(0, 0), m_bounds);
@@ -171,17 +167,18 @@ void ContentLayerChromium::updateContents()
dirtyRect.intersect(boundsRect);
}
+#if PLATFORM(SKIA)
+ const SkBitmap* skiaBitmap = 0;
+ OwnPtr<skia::PlatformCanvas> canvas;
+ OwnPtr<PlatformContextSkia> skiaContext;
+ OwnPtr<GraphicsContext> graphicsContext;
+
canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
skiaContext.set(new PlatformContextSkia(canvas.get()));
-#if OS(WINDOWS)
- // This is needed to get text to show up correctly. Without it,
- // GDI renders with zero alpha and the text becomes invisible.
- // Unfortunately, setting this to true disables cleartype.
+ // This is needed to get text to show up correctly.
// FIXME: Does this take us down a very slow text rendering path?
- // FIXME: why is this is a windows-only call ?
skiaContext->setDrawingToImageBuffer(true);
-#endif
graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));
@@ -201,19 +198,6 @@ void ContentLayerChromium::updateContents()
bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
}
#elif PLATFORM(CG)
- requiredTextureSize = m_bounds;
- IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
- // If the texture needs to be reallocated then we must redraw the entire
- // contents of the layer.
- if (requiredTextureSize != m_allocatedTextureSize)
- dirtyRect = boundsRect;
- else {
- // Clip the dirtyRect to the size of the layer to avoid drawing outside
- // the bounds of the backing texture.
- dirtyRect.intersect(boundsRect);
- }
-
Vector<uint8_t> tempVector;
int rowBytes = 4 * dirtyRect.width();
tempVector.resize(rowBytes * dirtyRect.height());
@@ -225,6 +209,7 @@ void ContentLayerChromium::updateContents()
kCGImageAlphaPremultipliedLast));
GraphicsContext graphicsContext(contextCG.get());
+ LocalCurrentGraphicsContext scopedNSGraphicsContext(&graphicsContext);
// Translate the graphics contxt into the coordinate system of the dirty rect.
graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());
diff --git a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
new file mode 100644
index 0000000..64981ee
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "DrawingBuffer.h"
+
+#include "GraphicsContext3D.h"
+#include "SharedGraphicsContext3D.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "Canvas2DLayerChromium.h"
+#endif
+
+#include <GLES2/gl2.h>
+#ifndef GL_GLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES 1
+#endif
+#include <GLES2/gl2ext.h>
+
+namespace WebCore {
+
+struct DrawingBufferInternal {
+ unsigned offscreenColorTexture;
+#if USE(ACCELERATED_COMPOSITING)
+ RefPtr<Canvas2DLayerChromium> platformLayer;
+#endif
+};
+
+static unsigned generateColorTexture(SharedGraphicsContext3D* context, const IntSize& size)
+{
+ unsigned offscreenColorTexture = context->createTexture();
+ if (!offscreenColorTexture)
+ return 0;
+
+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, offscreenColorTexture);
+ context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
+ context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
+ context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
+ context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, offscreenColorTexture, 0);
+
+ return offscreenColorTexture;
+}
+
+
+DrawingBuffer::DrawingBuffer(SharedGraphicsContext3D* context, const IntSize& size, unsigned framebuffer)
+ : m_context(context)
+ , m_size(size)
+ , m_framebuffer(framebuffer)
+ , m_internal(new DrawingBufferInternal)
+{
+ context->bindFramebuffer(framebuffer);
+ m_internal->offscreenColorTexture = generateColorTexture(context, size);
+}
+
+DrawingBuffer::~DrawingBuffer()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_internal->platformLayer)
+ m_internal->platformLayer->setDrawingBuffer(0);
+#endif
+ m_context->bindFramebuffer(m_framebuffer);
+ m_context->deleteTexture(m_internal->offscreenColorTexture);
+ m_context->deleteFramebuffer(m_framebuffer);
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+void DrawingBuffer::publishToPlatformLayer()
+{
+ if (m_callback)
+ m_callback->willPublish();
+ unsigned parentTexture = m_internal->platformLayer->textureId();
+ // FIXME: We do the copy in the canvas' (child) context so that it executes in the correct order relative to
+ // other commands in the child context. This ensures that the parent texture always contains a complete
+ // frame and not some intermediate result. However, there is no synchronization to ensure that this copy
+ // happens before the compositor draws. This means we might draw stale frames sometimes. Ideally this
+ // would insert a fence into the child command stream that the compositor could wait for.
+ m_context->makeContextCurrent();
+ glCopyTextureToParentTexture(m_internal->offscreenColorTexture, parentTexture);
+ glFlush();
+}
+#endif
+
+void DrawingBuffer::reset(const IntSize& newSize)
+{
+ if (m_size == newSize)
+ return;
+ m_size = newSize;
+
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_internal->offscreenColorTexture);
+ m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_size.width(), m_size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_internal->platformLayer)
+ m_internal->platformLayer->setTextureChanged();
+#endif
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+PlatformLayer* DrawingBuffer::platformLayer()
+{
+ if (!m_internal->platformLayer)
+ m_internal->platformLayer = Canvas2DLayerChromium::create(this, 0);
+ return m_internal->platformLayer.get();
+}
+#endif
+
+unsigned DrawingBuffer::getRenderingResultsAsTexture()
+{
+ return m_internal->offscreenColorTexture;
+}
+
+}
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 78b7517..8a77501 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -372,6 +372,8 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
int numGlyphs,
const FloatPoint& point) const
{
+ graphicsContext->platformContext()->prepareForSoftwareDraw();
+
SkColor color = graphicsContext->platformContext()->effectiveFillColor();
unsigned char alpha = SkColorGetA(color);
// Skip 100% transparent text; no need to draw anything.
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index ec79b82..696cd9c 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -65,13 +65,13 @@ static bool isCanvasMultiLayered(SkCanvas* canvas)
return !layerIterator.done();
}
-static void adjustTextRenderMode(SkPaint* paint, bool isCanvasMultiLayered)
+static void adjustTextRenderMode(SkPaint* paint, PlatformContextSkia* skiaContext)
{
// Our layers only have a single alpha channel. This means that subpixel
// rendered text cannot be compositied correctly when the layer is
// collapsed. Therefore, subpixel text is disabled when we are drawing
- // onto a layer.
- if (isCanvasMultiLayered)
+ // onto a layer or when the compositor is being used.
+ if (isCanvasMultiLayered(skiaContext->canvas()) || skiaContext->isDrawingToImageBuffer())
paint->setLCDRenderText(false);
}
@@ -100,16 +100,17 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
y += SkFloatToScalar(adv[i].height());
}
+ gc->platformContext()->prepareForSoftwareDraw();
+
SkCanvas* canvas = gc->platformContext()->canvas();
int textMode = gc->platformContext()->getTextDrawingMode();
- bool haveMultipleLayers = isCanvasMultiLayered(canvas);
// We draw text up to two times (once for fill, once for stroke).
if (textMode & cTextFill) {
SkPaint paint;
gc->platformContext()->setupPaintForFilling(&paint);
font->platformData().setupPaint(&paint);
- adjustTextRenderMode(&paint, haveMultipleLayers);
+ adjustTextRenderMode(&paint, gc->platformContext());
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setColor(gc->fillColor().rgb());
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
@@ -122,7 +123,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
SkPaint paint;
gc->platformContext()->setupPaintForStroking(&paint, 0, 0);
font->platformData().setupPaint(&paint);
- adjustTextRenderMode(&paint, haveMultipleLayers);
+ adjustTextRenderMode(&paint, gc->platformContext());
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setColor(gc->strokeColor().rgb());
@@ -499,7 +500,11 @@ private:
// We overflowed our arrays. Resize and retry.
// HB_ShapeItem fills in m_item.num_glyphs with the needed size.
deleteGlyphArrays();
- createGlyphArrays(m_item.num_glyphs);
+ // The |+ 1| here is a workaround for a bug in Harfbuzz: the Khmer
+ // shaper (at least) can fail because of insufficient glyph buffers
+ // and request 0 additional glyphs: throwing us into an infinite
+ // loop.
+ createGlyphArrays(m_item.num_glyphs + 1);
}
}
@@ -522,8 +527,11 @@ private:
m_xPositions[i] = m_offsetX + position + offsetX;
double advance = truncateFixedPointToInteger(m_item.advances[i]);
- unsigned glyphIndex = m_item.item.pos + logClustersIndex;
- if (isWordBreak(glyphIndex, isRTL)) {
+ // The first half of the conjuction works around the case where
+ // output glyphs aren't associated with any codepoints by the
+ // clusters log.
+ if (logClustersIndex < m_item.item.length
+ && isWordBreak(m_item.item.pos + logClustersIndex, isRTL)) {
advance += m_wordSpacingAdjustment;
if (m_padding > 0) {
@@ -547,7 +555,7 @@ private:
while (logClustersIndex > 0 && logClusters()[logClustersIndex] == i)
logClustersIndex--;
} else {
- while (logClustersIndex < m_item.num_glyphs && logClusters()[logClustersIndex] == i)
+ while (logClustersIndex < m_item.item.length && logClusters()[logClustersIndex] == i)
logClustersIndex++;
}
@@ -637,7 +645,6 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
}
TextRunWalker walker(run, point.x(), this);
- bool haveMultipleLayers = isCanvasMultiLayered(canvas);
walker.setWordSpacingAdjustment(wordSpacing());
walker.setLetterSpacingAdjustment(letterSpacing());
walker.setPadding(run.padding());
@@ -645,13 +652,13 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
while (walker.nextScriptRun()) {
if (fill) {
walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint);
- adjustTextRenderMode(&fillPaint, haveMultipleLayers);
+ adjustTextRenderMode(&fillPaint, gc->platformContext());
canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, walker.xPositions(), point.y(), fillPaint);
}
if (stroke) {
walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint);
- adjustTextRenderMode(&strokePaint, haveMultipleLayers);
+ adjustTextRenderMode(&strokePaint, gc->platformContext());
canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, walker.xPositions(), point.y(), strokePaint);
}
}
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 82d4c0b..46aecf4 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -32,10 +32,12 @@
#include "GLES2Canvas.h"
+#include "DrawingBuffer.h"
#include "FloatRect.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
#include "PlatformString.h"
+#include "SharedGraphicsContext3D.h"
#include "SolidFillShader.h"
#include "TexShader.h"
#include "Texture.h"
@@ -61,37 +63,35 @@ struct GLES2Canvas::State {
AffineTransform m_ctm;
};
-GLES2Canvas::GLES2Canvas(GraphicsContext3D* context, const IntSize& size)
- : m_context(context)
+GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawingBuffer, const IntSize& size)
+ : m_size(size)
+ , m_context(context)
+ , m_drawingBuffer(drawingBuffer)
, m_state(0)
- , m_quadVertices(0)
- , m_solidFillShader(SolidFillShader::create(context))
- , m_texShader(TexShader::create(context))
{
m_flipMatrix.translate(-1.0f, 1.0f);
m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height());
- m_context->reshape(size.width(), size.height());
- m_context->viewport(0, 0, size.width(), size.height());
-
m_stateStack.append(State());
m_state = &m_stateStack.last();
-
- // Force the source over composite mode to be applied.
- m_lastCompositeOp = CompositeClear;
- applyCompositeOperator(CompositeSourceOver);
}
GLES2Canvas::~GLES2Canvas()
{
- m_context->deleteBuffer(m_quadVertices);
+}
+
+void GLES2Canvas::bindFramebuffer()
+{
+ m_drawingBuffer->bind();
}
void GLES2Canvas::clearRect(const FloatRect& rect)
{
+ bindFramebuffer();
if (m_state->m_ctm.isIdentity()) {
- m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
+ m_context->scissor(rect);
m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->clearColor(Color(RGBA32(0)));
m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
m_context->disable(GraphicsContext3D::SCISSOR_TEST);
} else {
@@ -104,16 +104,17 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
- applyCompositeOperator(m_state->m_compositeOp);
-
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ m_context->useQuadVertices();
AffineTransform matrix(m_flipMatrix);
matrix.multLeft(m_state->m_ctm);
matrix.translate(rect.x(), rect.y());
matrix.scale(rect.width(), rect.height());
- m_solidFillShader->use(matrix, color);
+ m_context->useFillSolidProgram(matrix, color);
+
+ bindFramebuffer();
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
}
@@ -165,21 +166,33 @@ void GLES2Canvas::restore()
m_state = &m_stateStack.last();
}
+void GLES2Canvas::drawTexturedRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
+{
+ m_context->applyCompositeOperator(compositeOp);
+
+ m_context->useQuadVertices();
+ m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
+
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
+
+ drawQuad(textureSize, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha);
+}
+
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp);
}
+
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp)
{
- applyCompositeOperator(compositeOp);
-
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
- checkGLError("glBindBuffer");
-
+ m_context->applyCompositeOperator(compositeOp);
const TilingData& tiles = texture->tiles();
IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
+ m_context->useQuadVertices();
+ m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
+
for (int y = tileIdxRect.y(); y <= tileIdxRect.bottom(); y++) {
for (int x = tileIdxRect.x(); x <= tileIdxRect.right(); x++)
drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect, dstRect, transform, alpha);
@@ -193,7 +206,6 @@ void GLES2Canvas::drawTexturedRectTile(Texture* texture, int tile, const FloatRe
const TilingData& tiles = texture->tiles();
- m_context->activeTexture(GraphicsContext3D::TEXTURE0);
texture->bindTile(tile);
FloatRect srcRectClippedInTileSpace;
@@ -202,18 +214,24 @@ void GLES2Canvas::drawTexturedRectTile(Texture* texture, int tile, const FloatRe
IntRect tileBoundsWithBorder = tiles.tileBoundsWithBorder(tile);
+ drawQuad(tileBoundsWithBorder.size(), srcRectClippedInTileSpace, dstRectIntersected, transform, alpha);
+}
+
+void GLES2Canvas::drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+{
AffineTransform matrix(m_flipMatrix);
matrix.multLeft(transform);
- matrix.translate(dstRectIntersected.x(), dstRectIntersected.y());
- matrix.scale(dstRectIntersected.width(), dstRectIntersected.height());
+ matrix.translate(dstRect.x(), dstRect.y());
+ matrix.scale(dstRect.width(), dstRect.height());
AffineTransform texMatrix;
- texMatrix.scale(1.0f / tileBoundsWithBorder.width(), 1.0f / tileBoundsWithBorder.height());
- texMatrix.translate(srcRectClippedInTileSpace.x(), srcRectClippedInTileSpace.y());
- texMatrix.scale(srcRectClippedInTileSpace.width(), srcRectClippedInTileSpace.height());
+ texMatrix.scale(1.0f / textureSize.width(), 1.0f / textureSize.height());
+ texMatrix.translate(srcRect.x(), srcRect.y());
+ texMatrix.scale(srcRect.width(), srcRect.height());
- m_texShader->use(matrix, texMatrix, 0, alpha);
+ bindFramebuffer();
+ m_context->useTextureProgram(matrix, texMatrix, alpha);
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
checkGLError("glDrawArrays");
}
@@ -223,98 +241,14 @@ void GLES2Canvas::setCompositeOperation(CompositeOperator op)
m_state->m_compositeOp = op;
}
-void GLES2Canvas::applyCompositeOperator(CompositeOperator op)
-{
- if (op == m_lastCompositeOp)
- return;
-
- switch (op) {
- case CompositeClear:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ZERO);
- break;
- case CompositeCopy:
- m_context->disable(GraphicsContext3D::BLEND);
- break;
- case CompositeSourceOver:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
- break;
- case CompositeSourceIn:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ZERO);
- break;
- case CompositeSourceOut:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ZERO);
- break;
- case CompositeSourceAtop:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
- break;
- case CompositeDestinationOver:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE);
- break;
- case CompositeDestinationIn:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::SRC_ALPHA);
- break;
- case CompositeDestinationOut:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
- break;
- case CompositeDestinationAtop:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::SRC_ALPHA);
- break;
- case CompositeXOR:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
- break;
- case CompositePlusDarker:
- case CompositeHighlight:
- // unsupported
- m_context->disable(GraphicsContext3D::BLEND);
- break;
- case CompositePlusLighter:
- m_context->enable(GraphicsContext3D::BLEND);
- m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE);
- break;
- }
- m_lastCompositeOp = op;
-}
-
-unsigned GLES2Canvas::getQuadVertices()
-{
- if (!m_quadVertices) {
- float vertices[] = { 0.0f, 0.0f, 1.0f,
- 1.0f, 0.0f, 1.0f,
- 0.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f };
- m_quadVertices = m_context->createBuffer();
- m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
- m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
- }
- return m_quadVertices;
-}
-
Texture* GLES2Canvas::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height)
{
- PassRefPtr<Texture> texture = m_textures.get(ptr);
- if (texture)
- return texture.get();
-
- texture = Texture::create(m_context, format, width, height);
- Texture* t = texture.get();
- m_textures.set(ptr, texture);
- return t;
+ return m_context->createTexture(ptr, format, width, height);
}
Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
{
- PassRefPtr<Texture> texture = m_textures.get(ptr);
- return texture ? texture.get() : 0;
+ return m_context->getTexture(ptr);
}
void GLES2Canvas::checkGLError(const char* header)
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h
index f49ac8b..6fc1a0e 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -45,16 +45,14 @@
namespace WebCore {
class Color;
+class DrawingBuffer;
class FloatRect;
class GraphicsContext3D;
-class SolidFillShader;
-class TexShader;
-
-typedef HashMap<NativeImagePtr, RefPtr<Texture> > TextureHashMap;
+class SharedGraphicsContext3D;
class GLES2Canvas : public Noncopyable {
public:
- GLES2Canvas(GraphicsContext3D*, const IntSize&);
+ GLES2Canvas(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
~GLES2Canvas();
void fillRect(const FloatRect&, const Color&, ColorSpace);
@@ -74,28 +72,33 @@ public:
// non-standard functions
// These are not standard GraphicsContext functions, and should be pushed
// down into a PlatformContextGLES2 at some point.
+ void drawTexturedRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator);
void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace, CompositeOperator);
void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator);
- GraphicsContext3D* context() { return m_context; }
Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height);
Texture* getTexture(NativeImagePtr);
+ SharedGraphicsContext3D* context() const { return m_context; }
+
+ void bindFramebuffer();
+
+ DrawingBuffer* drawingBuffer() const { return m_drawingBuffer; }
+
private:
void drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void applyCompositeOperator(CompositeOperator);
void checkGLError(const char* header);
- unsigned getQuadVertices();
- GraphicsContext3D* m_context;
+ IntSize m_size;
+
+ SharedGraphicsContext3D* m_context;
+ DrawingBuffer* m_drawingBuffer;
+
struct State;
WTF::Vector<State> m_stateStack;
State* m_state;
- unsigned m_quadVertices;
- OwnPtr<SolidFillShader> m_solidFillShader;
- OwnPtr<TexShader> m_texShader;
AffineTransform m_flipMatrix;
- TextureHashMap m_textures;
- CompositeOperator m_lastCompositeOp; // This is the one last set, not necessarily the one in the state stack.
};
}
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 648e35f..bbae72a 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -45,7 +45,9 @@
#include "GraphicsLayerChromium.h"
+#include "Canvas2DLayerChromium.h"
#include "ContentLayerChromium.h"
+#include "DrawingBuffer.h"
#include "FloatConversion.h"
#include "FloatRect.h"
#include "Image.h"
@@ -104,6 +106,12 @@ GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client)
GraphicsLayerChromium::~GraphicsLayerChromium()
{
+ if (m_layer)
+ m_layer->setOwner(0);
+ if (m_contentsLayer)
+ m_contentsLayer->setOwner(0);
+ if (m_transformLayer)
+ m_transformLayer->setOwner(0);
}
void GraphicsLayerChromium::setName(const String& inName)
@@ -290,6 +298,7 @@ void GraphicsLayerChromium::setContentsNeedsDisplay()
if (m_contentsLayer)
m_contentsLayer->setNeedsDisplay();
}
+
void GraphicsLayerChromium::setNeedsDisplay()
{
if (drawsContent())
@@ -344,13 +353,13 @@ void GraphicsLayerChromium::setContentsToCanvas(PlatformLayer* platformLayer)
bool childrenChanged = false;
if (platformLayer) {
platformLayer->setOwner(this);
- if (!m_contentsLayer.get() || m_contentsLayerPurpose != ContentsLayerForCanvas) {
+ if (m_contentsLayer.get() != platformLayer) {
setupContentsLayer(platformLayer);
m_contentsLayer = platformLayer;
m_contentsLayerPurpose = ContentsLayerForCanvas;
childrenChanged = true;
}
- platformLayer->setNeedsDisplay();
+ m_contentsLayer->setNeedsDisplay();
updateContentsRect();
} else {
if (m_contentsLayer) {
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
index 9dff66a..dde443d 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
@@ -138,7 +138,7 @@ private:
NoContentsLayer = 0,
ContentsLayerForImage,
ContentsLayerForVideo,
- ContentsLayerForCanvas
+ ContentsLayerForCanvas,
};
ContentsLayerPurpose m_contentsLayerPurpose;
diff --git a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
index 4fd3ba0..59e8122 100644
--- a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
+++ b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
@@ -38,6 +38,7 @@
#include "SkPath.h"
#include "SkPoint.h"
#include "SkRect.h"
+#include "SkUtils.h"
extern "C" {
#include "harfbuzz-shaper.h"
@@ -61,6 +62,15 @@ static HB_Bool stringToGlyphs(HB_Font hbFont, const HB_UChar16* characters, hb_u
font->setupPaint(&paint);
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+
+ unsigned codepoints = 0;
+ for (hb_uint32 i = 0; i < length; i++) {
+ if (!SkUTF16_IsHighSurrogate(characters[i]))
+ codepoints++;
+ if (codepoints > *glyphsSize)
+ return 0;
+ }
+
int numGlyphs = paint.textToGlyphs(characters, length * sizeof(uint16_t), reinterpret_cast<uint16_t*>(glyphs));
// HB_Glyph is 32-bit, but Skia outputs only 16-bit numbers. So our
diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 09b388d..060bb46 100644
--- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -108,8 +108,9 @@ void ImageLayerChromium::updateContents()
// completely overwrite its contents with the image below.
// Try to reuse the color space from the image to preserve its colors.
// Some images use a color space (such as indexed) unsupported by the bitmap context.
- RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGImageGetColorSpace(cgImage));
- CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace.get());
+ RetainPtr<CGColorSpaceRef> colorSpaceReleaser;
+ CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
+ CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
switch (colorSpaceModel) {
case kCGColorSpaceModelMonochrome:
case kCGColorSpaceModelRGB:
@@ -118,12 +119,13 @@ void ImageLayerChromium::updateContents()
case kCGColorSpaceModelDeviceN:
break;
default:
- colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
+ colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB());
+ colorSpace = colorSpaceReleaser.get();
break;
}
RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(tempVector.data(),
width, height, 8, tempRowBytes,
- colorSpace.get(),
+ colorSpace,
kCGImageAlphaPremultipliedLast));
CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy);
CGContextDrawImage(tempContext.get(),
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 50338d2..4708310 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -34,11 +34,11 @@
#if USE(ACCELERATED_COMPOSITING)
#include "LayerRendererChromium.h"
-#include "CanvasLayerChromium.h"
-#include "ContentLayerChromium.h"
+#include "Canvas2DLayerChromium.h"
#include "GLES2Context.h"
#include "LayerChromium.h"
#include "NotImplemented.h"
+#include "WebGLLayerChromium.h"
#if PLATFORM(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
@@ -77,7 +77,14 @@ static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GLES2Context> gles2Context)
{
- return new LayerRendererChromium(gles2Context);
+ if (!gles2Context)
+ return 0;
+
+ OwnPtr<LayerRendererChromium> layerRenderer(new LayerRendererChromium(gles2Context));
+ if (!layerRenderer->hardwareCompositing())
+ return 0;
+
+ return layerRenderer.release();
}
LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context)
@@ -91,7 +98,7 @@ LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Conte
, m_currentShader(0)
, m_gles2Context(gles2Context)
{
- m_hardwareCompositing = (m_gles2Context && initializeSharedObjects());
+ m_hardwareCompositing = initializeSharedObjects();
}
LayerRendererChromium::~LayerRendererChromium()
@@ -118,10 +125,7 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size)
// the old ones.
m_rootLayerCanvas = new skia::PlatformCanvas(size.width(), size.height(), false);
m_rootLayerSkiaContext = new PlatformContextSkia(m_rootLayerCanvas.get());
-#if OS(WINDOWS)
- // FIXME: why is this is a windows-only call ?
m_rootLayerSkiaContext->setDrawingToImageBuffer(true);
-#endif
m_rootLayerGraphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_rootLayerSkiaContext.get()));
#elif PLATFORM(CG)
// Release the previous CGBitmapContext before reallocating the backing store as a precaution.
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 7ff98b9..c0da285 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -96,14 +96,9 @@ void VideoLayerChromium::updateContents()
m_canvas = new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), true);
m_skiaContext = new PlatformContextSkia(m_canvas.get());
-#if OS(WINDOWS)
- // This is needed to get text to show up correctly. Without it,
- // GDI renders with zero alpha and the text becomes invisible.
- // Unfortunately, setting this to true disables cleartype.
+ // This is needed to get text to show up correctly.
// FIXME: Does this take us down a very slow text rendering path?
- // FIXME: Why is this is a windows-only call?
m_skiaContext->setDrawingToImageBuffer(true);
-#endif
m_graphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get()));
}
diff --git a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
new file mode 100644
index 0000000..411f416
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "WebGLLayerChromium.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include <GLES2/gl2.h>
+
+namespace WebCore {
+
+PassRefPtr<WebGLLayerChromium> WebGLLayerChromium::create(GraphicsLayerChromium* owner)
+{
+ return adoptRef(new WebGLLayerChromium(owner));
+}
+
+WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner)
+ : CanvasLayerChromium(owner)
+ , m_context(0)
+{
+}
+
+void WebGLLayerChromium::updateContents()
+{
+ ASSERT(m_context);
+ if (m_textureChanged) {
+ glBindTexture(GL_TEXTURE_2D, m_textureId);
+ // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE
+ // to get around NPOT texture limitations of GLES.
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ m_textureChanged = false;
+ }
+ // Update the contents of the texture used by the compositor.
+ if (m_contentsDirty) {
+ m_context->prepareTexture();
+ m_contentsDirty = false;
+ }
+}
+
+void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
+{
+ m_context = const_cast<GraphicsContext3D*>(context);
+
+ unsigned int textureId = m_context->platformTexture();
+ if (textureId != m_textureId)
+ m_textureChanged = true;
+ m_textureId = textureId;
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
new file mode 100644
index 0000000..11b8db7
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef WebGLLayerChromium_h
+#define WebGLLayerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "CanvasLayerChromium.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+// A Layer containing a WebGL canvas
+class WebGLLayerChromium : public CanvasLayerChromium {
+public:
+ static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0);
+ virtual bool drawsContent() { return m_context; }
+ virtual void updateContents();
+
+ void setContext(const GraphicsContext3D* context);
+
+private:
+ explicit WebGLLayerChromium(GraphicsLayerChromium* owner);
+ GraphicsContext3D* m_context;
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
new file mode 100644
index 0000000..dc80954
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "DrawingBuffer.h"
+
+#include "GraphicsContext3D.h"
+#include "SharedGraphicsContext3D.h"
+
+namespace WebCore {
+
+PassOwnPtr<DrawingBuffer> DrawingBuffer::create(SharedGraphicsContext3D* context, const IntSize& size)
+{
+ unsigned framebuffer = context->createFramebuffer();
+ ASSERT(framebuffer);
+ if (!framebuffer)
+ return 0;
+ return adoptPtr(new DrawingBuffer(context, size, framebuffer));
+}
+
+void DrawingBuffer::bind()
+{
+ m_context->bindFramebuffer(m_framebuffer);
+ m_context->setViewport(m_size);
+}
+
+void DrawingBuffer::setWillPublishCallback(PassOwnPtr<WillPublishCallback> callback)
+{
+ m_callback = callback;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/gpu/DrawingBuffer.h b/WebCore/platform/graphics/gpu/DrawingBuffer.h
new file mode 100644
index 0000000..23e6f4a
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DrawingBuffer_h
+#define DrawingBuffer_h
+
+#include "GraphicsLayer.h"
+#include "IntSize.h"
+
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class SharedGraphicsContext3D;
+
+struct DrawingBufferInternal;
+
+// Manages a rendering target (framebuffer + attachment) for a canvas. Can publish its rendering
+// results to a PlatformLayer for compositing.
+class DrawingBuffer : public Noncopyable {
+public:
+ static PassOwnPtr<DrawingBuffer> create(SharedGraphicsContext3D*, const IntSize&);
+ ~DrawingBuffer();
+
+ void reset(const IntSize&);
+ void bind();
+ IntSize size() const { return m_size; }
+
+#if USE(ACCELERATED_COMPOSITING)
+ PlatformLayer* platformLayer();
+ void publishToPlatformLayer();
+#endif
+
+ unsigned getRenderingResultsAsTexture();
+
+ class WillPublishCallback : public Noncopyable {
+ public:
+ virtual void willPublish() = 0;
+ };
+
+ void setWillPublishCallback(PassOwnPtr<WillPublishCallback>);
+private:
+ DrawingBuffer(SharedGraphicsContext3D*, const IntSize&, unsigned framebuffer);
+
+ SharedGraphicsContext3D* m_context;
+ IntSize m_size;
+ unsigned m_framebuffer;
+
+ OwnPtr<WillPublishCallback> m_callback;
+ OwnPtr<DrawingBufferInternal> m_internal;
+};
+
+} // namespace WebCore
+
+#endif // DrawingBuffer_h
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnClassifier.cpp b/WebCore/platform/graphics/gpu/LoopBlinnClassifier.cpp
new file mode 100644
index 0000000..e43dc37
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnClassifier.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnClassifier.h"
+
+#include "LoopBlinnMathUtils.h"
+
+namespace WebCore {
+
+using LoopBlinnMathUtils::approxEqual;
+using LoopBlinnMathUtils::roundToZero;
+
+LoopBlinnClassifier::Result LoopBlinnClassifier::classify(const FloatPoint& c0,
+ const FloatPoint& c1,
+ const FloatPoint& c2,
+ const FloatPoint& c3)
+{
+ // Consult the chapter for the definitions of the following
+ // (terse) variable names. Note that the b0..b3 coordinates are
+ // homogeneous, so the "z" value (actually the w coordinate) must
+ // be 1.0.
+ FloatPoint3D b0(c0.x(), c0.y(), 1.0f);
+ FloatPoint3D b1(c1.x(), c1.y(), 1.0f);
+ FloatPoint3D b2(c2.x(), c2.y(), 1.0f);
+ FloatPoint3D b3(c3.x(), c3.y(), 1.0f);
+
+ // Compute a1..a3.
+ float a1 = b0 * b3.cross(b2);
+ float a2 = b1 * b0.cross(b3);
+ float a3 = b2 * b1.cross(b0);
+
+ // Compute d1..d3.
+ float d1 = a1 - 2 * a2 + 3 * a3;
+ float d2 = -a2 + 3 * a3;
+ float d3 = 3 * a3;
+
+ // Experimentation has shown that the texture coordinates computed
+ // from these values quickly become huge, leading to roundoff errors
+ // and artifacts in the shader. It turns out that if we normalize
+ // the vector defined by (d1, d2, d3), this fixes the problem of the
+ // texture coordinates getting too large without affecting the
+ // classification results.
+ FloatPoint3D nd(d1, d2, d3);
+ nd.normalize();
+ d1 = nd.x();
+ d2 = nd.y();
+ d3 = nd.z();
+
+ // Compute the discriminant.
+ // term0 is a common term in the computation which helps decide
+ // which way to classify the cusp case: as serpentine or loop.
+ float term0 = (3 * d2 * d2 - 4 * d1 * d3);
+ float discriminant = d1 * d1 * term0;
+
+ // Experimentation has also shown that when the classification is
+ // near the boundary between one curve type and another, the shader
+ // becomes numerically unstable, particularly with the cusp case.
+ // Correct for this by rounding d1..d3 and the discriminant to zero
+ // when they get near it.
+ d1 = roundToZero(d1);
+ d2 = roundToZero(d2);
+ d3 = roundToZero(d3);
+ discriminant = roundToZero(discriminant);
+
+ // Do the classification.
+ if (approxEqual(b0, b1) && approxEqual(b0, b2) && approxEqual(b0, b3))
+ return Result(kPoint, d1, d2, d3);
+
+ if (!discriminant) {
+ if (!d1 && !d2) {
+ if (!d3)
+ return Result(kLine, d1, d2, d3);
+ return Result(kQuadratic, d1, d2, d3);
+ }
+
+ if (!d1)
+ return Result(kCusp, d1, d2, d3);
+
+ // This is the boundary case described in Loop and Blinn's
+ // SIGGRAPH '05 paper of a cusp with inflection at infinity.
+ // Because term0 might not be exactly 0, we decide between using
+ // the serpentine and loop cases depending on its sign to avoid
+ // taking the square root of a negative number when computing the
+ // cubic texture coordinates.
+ if (term0 < 0)
+ return Result(kLoop, d1, d2, d3);
+
+ return Result(kSerpentine, d1, d2, d3);
+ }
+
+ if (discriminant > 0)
+ return Result(kSerpentine, d1, d2, d3);
+
+ // discriminant < 0
+ return Result(kLoop, d1, d2, d3);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h b/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h
new file mode 100644
index 0000000..c665844
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Cubic curve classification algorithm from "Rendering Vector Art on
+// the GPU" by Loop and Blinn, GPU Gems 3, Chapter 25:
+// http://http.developer.nvidia.com/GPUGems3/gpugems3_ch25.html .
+
+#ifndef LoopBlinnClassifier_h
+#define LoopBlinnClassifier_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class FloatPoint;
+
+// Classifies cubic curves into specific types.
+class LoopBlinnClassifier : public Noncopyable {
+public:
+ // The types of cubic curves.
+ enum CurveType {
+ kSerpentine,
+ kCusp,
+ kLoop,
+ kQuadratic,
+ kLine,
+ kPoint
+ };
+
+ // The result of the classifier.
+ struct Result {
+ public:
+ Result(CurveType inputCurveType, float inputD1, float inputD2, float inputD3)
+ : curveType(inputCurveType)
+ , d1(inputD1)
+ , d2(inputD2)
+ , d3(inputD3) { }
+
+ CurveType curveType;
+
+ // These are coefficients used later in the computation of
+ // texture coordinates per vertex.
+ float d1;
+ float d2;
+ float d3;
+ };
+
+ // Classifies the given cubic bezier curve starting at c0, ending
+ // at c3, and affected by control points c1 and c2.
+ static Result classify(const FloatPoint& c0,
+ const FloatPoint& c1,
+ const FloatPoint& c2,
+ const FloatPoint& c3);
+
+private:
+ // This class does not need to be instantiated.
+ LoopBlinnClassifier() { }
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnClassifier_h
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnConstants.h b/WebCore/platform/graphics/gpu/LoopBlinnConstants.h
new file mode 100644
index 0000000..1997d9f
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnConstants.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnConstants_h
+#define LoopBlinnConstants_h
+
+namespace WebCore {
+namespace LoopBlinnConstants {
+
+enum FillSide {
+ LeftSide,
+ RightSide
+};
+
+} // namespace LoopBlinnConstants
+} // namespace WebCore
+
+#endif // LoopBlinnConstants_h
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp b/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp
new file mode 100644
index 0000000..61ebc9b
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnMathUtils.h"
+
+#include "FloatPoint.h"
+#include "MathExtras.h"
+#include <algorithm>
+#include <string.h> // for memcpy
+
+namespace WebCore {
+namespace LoopBlinnMathUtils {
+
+namespace {
+
+// Utility functions local to this file.
+int orientation(const FloatPoint& p1,
+ const FloatPoint& p2,
+ const FloatPoint& p3)
+{
+ float crossProduct = (p2.y() - p1.y()) * (p3.x() - p2.x()) - (p3.y() - p2.y()) * (p2.x() - p1.x());
+ return (crossProduct < 0.0f) ? -1 : ((crossProduct > 0.0f) ? 1 : 0);
+}
+
+bool edgeEdgeTest(const FloatSize& v0Delta,
+ const FloatPoint& v0,
+ const FloatPoint& u0,
+ const FloatPoint& u1)
+{
+ // This edge to edge test is based on Franlin Antonio's gem: "Faster
+ // Line Segment Intersection", in Graphics Gems III, pp. 199-202.
+ float ax = v0Delta.width();
+ float ay = v0Delta.height();
+ float bx = u0.x() - u1.x();
+ float by = u0.y() - u1.y();
+ float cx = v0.x() - u0.x();
+ float cy = v0.y() - u0.y();
+ float f = ay * bx - ax * by;
+ float d = by * cx - bx * cy;
+ if ((f > 0 && d >= 0 && d <= f) || (f < 0 && d <= 0 && d >= f)) {
+ float e = ax * cy - ay * cx;
+
+ // This additional test avoids reporting coincident edges, which
+ // is the behavior we want.
+ if (approxEqual(e, 0) || approxEqual(f, 0) || approxEqual(e, f))
+ return false;
+
+ if (f > 0)
+ return e >= 0 && e <= f;
+
+ return e <= 0 && e >= f;
+ }
+ return false;
+}
+
+bool edgeAgainstTriangleEdges(const FloatPoint& v0,
+ const FloatPoint& v1,
+ const FloatPoint& u0,
+ const FloatPoint& u1,
+ const FloatPoint& u2)
+{
+ FloatSize delta = v1 - v0;
+ // Test edge u0, u1 against v0, v1.
+ if (edgeEdgeTest(delta, v0, u0, u1))
+ return true;
+ // Test edge u1, u2 against v0, v1.
+ if (edgeEdgeTest(delta, v0, u1, u2))
+ return true;
+ // Test edge u2, u1 against v0, v1.
+ if (edgeEdgeTest(delta, v0, u2, u0))
+ return true;
+ return false;
+}
+
+// A roundoff factor in the cubic classification and texture coordinate
+// generation algorithms. It primarily determines the handling of corner
+// cases during the classification process. Be careful when adjusting it;
+// it has been determined empirically to work well. When changing it, you
+// should look in particular at shapes that contain quadratic curves and
+// ensure they still look smooth. Once pixel tests are running against this
+// algorithm, they should provide sufficient coverage to ensure that
+// adjusting the constant won't break anything.
+const float Epsilon = 5.0e-4f;
+
+} // anonymous namespace
+
+// Exported routines
+
+float roundToZero(float val)
+{
+ if (val < Epsilon && val > -Epsilon)
+ return 0;
+ return val;
+}
+
+bool approxEqual(const FloatPoint& v0, const FloatPoint& v1)
+{
+ return (v0 - v1).diagonalLengthSquared() < Epsilon * Epsilon;
+}
+
+bool approxEqual(const FloatPoint3D& v0, const FloatPoint3D& v1)
+{
+ return (v0 - v1).lengthSquared() < Epsilon * Epsilon;
+}
+
+bool approxEqual(float f0, float f1)
+{
+ return fabsf(f0 - f1) < Epsilon;
+}
+
+bool linesIntersect(const FloatPoint& p1,
+ const FloatPoint& q1,
+ const FloatPoint& p2,
+ const FloatPoint& q2)
+{
+ return (orientation(p1, q1, p2) != orientation(p1, q1, q2)
+ && orientation(p2, q2, p1) != orientation(p2, q2, q1));
+}
+
+bool pointInTriangle(const FloatPoint& point,
+ const FloatPoint& a,
+ const FloatPoint& b,
+ const FloatPoint& c)
+{
+ // Algorithm from http://www.blackpawn.com/texts/pointinpoly/default.html
+ float x0 = c.x() - a.x();
+ float y0 = c.y() - a.y();
+ float x1 = b.x() - a.x();
+ float y1 = b.y() - a.y();
+ float x2 = point.x() - a.x();
+ float y2 = point.y() - a.y();
+
+ float dot00 = x0 * x0 + y0 * y0;
+ float dot01 = x0 * x1 + y0 * y1;
+ float dot02 = x0 * x2 + y0 * y2;
+ float dot11 = x1 * x1 + y1 * y1;
+ float dot12 = x1 * x2 + y1 * y2;
+ float denominator = dot00 * dot11 - dot01 * dot01;
+ if (!denominator)
+ // Triangle is zero-area. Treat query point as not being inside.
+ return false;
+ // Compute
+ float inverseDenominator = 1.0f / denominator;
+ float u = (dot11 * dot02 - dot01 * dot12) * inverseDenominator;
+ float v = (dot00 * dot12 - dot01 * dot02) * inverseDenominator;
+
+ return (u > 0.0f) && (v > 0.0f) && (u + v < 1.0f);
+}
+
+bool trianglesOverlap(const FloatPoint& a1,
+ const FloatPoint& b1,
+ const FloatPoint& c1,
+ const FloatPoint& a2,
+ const FloatPoint& b2,
+ const FloatPoint& c2)
+{
+ // Derived from coplanar_tri_tri() at
+ // http://jgt.akpeters.com/papers/ShenHengTang03/tri_tri.html ,
+ // simplified for the 2D case and modified so that overlapping edges
+ // do not report overlapping triangles.
+
+ // Test all edges of triangle 1 against the edges of triangle 2.
+ if (edgeAgainstTriangleEdges(a1, b1, a2, b2, c2)
+ || edgeAgainstTriangleEdges(b1, c1, a2, b2, c2)
+ || edgeAgainstTriangleEdges(c1, a1, a2, b2, c2))
+ return true;
+ // Finally, test if tri1 is totally contained in tri2 or vice versa.
+ // The paper above only performs the first two point-in-triangle tests.
+ // Because we define that triangles sharing a vertex or edge don't
+ // overlap, we must perform additional tests to see whether one
+ // triangle is contained in the other.
+ if (pointInTriangle(a1, a2, b2, c2)
+ || pointInTriangle(a2, a1, b1, c1)
+ || pointInTriangle(b1, a2, b2, c2)
+ || pointInTriangle(b2, a1, b1, c1)
+ || pointInTriangle(c1, a2, b2, c2)
+ || pointInTriangle(c2, a1, b1, c1))
+ return true;
+ return false;
+}
+
+namespace {
+
+// Helper routines for public XRay queries below. All of this code
+// originated in Skia; see include/core/ and src/core/, SkScalar.h and
+// SkGeometry.{cpp,h}.
+
+const float NearlyZeroConstant = (1.0f / (1 << 12));
+
+bool nearlyZero(float x, float tolerance = NearlyZeroConstant)
+{
+ ASSERT(tolerance > 0.0f);
+ return ::fabsf(x) < tolerance;
+}
+
+// Linearly interpolate between a and b, based on t.
+// If t is 0, return a; if t is 1, return b; else interpolate.
+// t must be [0..1].
+float interpolate(float a, float b, float t)
+{
+ ASSERT(t >= 0 && t <= 1);
+ return a + (b - a) * t;
+}
+
+float evaluateCubic(float controlPoint0, float controlPoint1, float controlPoint2, float controlPoint3, float t)
+{
+ ASSERT(t >= 0 && t <= 1);
+
+ if (!t)
+ return controlPoint0;
+
+ float ab = interpolate(controlPoint0, controlPoint1, t);
+ float bc = interpolate(controlPoint1, controlPoint2, t);
+ float cd = interpolate(controlPoint2, controlPoint3, t);
+ float abc = interpolate(ab, bc, t);
+ float bcd = interpolate(bc, cd, t);
+ return interpolate(abc, bcd, t);
+}
+
+// Evaluates the point on the source cubic specified by t, 0 <= t <= 1.0.
+FloatPoint evaluateCubicAt(const FloatPoint cubic[4], float t)
+{
+ return FloatPoint(evaluateCubic(cubic[0].x(), cubic[1].x(), cubic[2].x(), cubic[3].x(), t),
+ evaluateCubic(cubic[0].y(), cubic[1].y(), cubic[2].y(), cubic[3].y(), t));
+}
+
+bool xRayCrossesMonotonicCubic(const XRay& xRay, const FloatPoint cubic[4], bool& ambiguous)
+{
+ ambiguous = false;
+
+ // Find the minimum and maximum y of the extrema, which are the
+ // first and last points since this cubic is monotonic
+ float minY = std::min(cubic[0].y(), cubic[3].y());
+ float maxY = std::max(cubic[0].y(), cubic[3].y());
+
+ if (xRay.y() == cubic[0].y()
+ || xRay.y() < minY
+ || xRay.y() > maxY) {
+ // The query line definitely does not cross the curve
+ ambiguous = (xRay.y() == cubic[0].y());
+ return false;
+ }
+
+ const bool pointAtExtremum = (xRay.y() == cubic[3].y());
+
+ float minX = std::min(std::min(std::min(cubic[0].x(), cubic[1].x()),
+ cubic[2].x()),
+ cubic[3].x());
+ if (xRay.x() < minX) {
+ // The query line definitely crosses the curve
+ ambiguous = pointAtExtremum;
+ return true;
+ }
+
+ float maxX = std::max(std::max(std::max(cubic[0].x(), cubic[1].x()),
+ cubic[2].x()),
+ cubic[3].x());
+ if (xRay.x() > maxX)
+ // The query line definitely does not cross the curve
+ return false;
+
+ // Do a binary search to find the parameter value which makes y as
+ // close as possible to the query point. See whether the query
+ // line's origin is to the left of the associated x coordinate.
+
+ // MaxIterations is chosen as the number of mantissa bits for a float,
+ // since there's no way we are going to get more precision by
+ // iterating more times than that.
+ const int MaxIterations = 23;
+ FloatPoint evaluatedPoint;
+ int iter = 0;
+ float upperT;
+ float lowerT;
+ // Need to invert direction of t parameter if cubic goes up
+ // instead of down
+ if (cubic[3].y() > cubic[0].y()) {
+ upperT = 1;
+ lowerT = 0;
+ } else {
+ upperT = 0;
+ lowerT = 1;
+ }
+ do {
+ float t = 0.5f * (upperT + lowerT);
+ evaluatedPoint = evaluateCubicAt(cubic, t);
+ if (xRay.y() > evaluatedPoint.y())
+ lowerT = t;
+ else
+ upperT = t;
+ } while (++iter < MaxIterations && !nearlyZero(evaluatedPoint.y() - xRay.y()));
+
+ // FIXME: once we have more regression tests for this code,
+ // determine whether this should be using a fuzzy test.
+ if (xRay.x() <= evaluatedPoint.x()) {
+ ambiguous = pointAtExtremum;
+ return true;
+ }
+ return false;
+}
+
+// Divides the numerator by the denominator safely for the case where
+// the result must lie in the range (0..1). Result indicates whether
+// the result is valid.
+bool safeUnitDivide(float numerator, float denominator, float& ratio)
+{
+ if (numerator < 0) {
+ // Make the "numerator >= denominator" check below work.
+ numerator = -numerator;
+ denominator = -denominator;
+ }
+ if (!numerator || !denominator || numerator >= denominator)
+ return false;
+ float r = numerator / denominator;
+ if (isnan(r))
+ return false;
+ ASSERT(r >= 0 && r < 1);
+ if (!r) // catch underflow if numerator <<<< denominator
+ return false;
+ ratio = r;
+ return true;
+}
+
+// From Numerical Recipes in C.
+//
+// q = -1/2 (b + sign(b) sqrt[b*b - 4*a*c])
+// x1 = q / a
+// x2 = c / q
+//
+// Returns the number of real roots of the equation [0..2]. Roots are
+// returned in sorted order, smaller root first.
+int findUnitQuadRoots(float a, float b, float c, float roots[2])
+{
+ if (!a)
+ return safeUnitDivide(-c, b, roots[0]) ? 1 : 0;
+
+ float discriminant = b*b - 4*a*c;
+ if (discriminant < 0 || isnan(discriminant)) // complex roots
+ return 0;
+ discriminant = sqrtf(discriminant);
+
+ float q = (b < 0) ? -(b - discriminant) / 2 : -(b + discriminant) / 2;
+ int numberOfRoots = 0;
+ if (safeUnitDivide(q, a, roots[numberOfRoots]))
+ ++numberOfRoots;
+ if (safeUnitDivide(c, q, roots[numberOfRoots]))
+ ++numberOfRoots;
+ if (numberOfRoots == 2) {
+ // Seemingly have two roots. Check for equality and sort.
+ if (roots[0] == roots[1])
+ return 1;
+ if (roots[0] > roots[1])
+ std::swap(roots[0], roots[1]);
+ }
+ return numberOfRoots;
+}
+
+// Cubic'(t) = pt^2 + qt + r, where
+// p = 3(-a + 3(b - c) + d)
+// q = 6(a - 2b + c)
+// r = 3(b - a)
+// Solve for t, keeping only those that fit between 0 < t < 1.
+int findCubicExtrema(float a, float b, float c, float d, float tValues[2])
+{
+ // Divide p, q, and r by 3 to simplify the equations.
+ float p = d - a + 3*(b - c);
+ float q = 2*(a - b - b + c);
+ float r = b - a;
+
+ return findUnitQuadRoots(p, q, r, tValues);
+}
+
+void interpolateCubicCoords(float controlPoint0, float controlPoint1, float controlPoint2, float controlPoint3, float* dst, float t)
+{
+ float ab = interpolate(controlPoint0, controlPoint1, t);
+ float bc = interpolate(controlPoint1, controlPoint2, t);
+ float cd = interpolate(controlPoint2, controlPoint3, t);
+ float abc = interpolate(ab, bc, t);
+ float bcd = interpolate(bc, cd, t);
+ float abcd = interpolate(abc, bcd, t);
+
+ dst[0] = controlPoint0;
+ dst[2] = ab;
+ dst[4] = abc;
+ dst[6] = abcd;
+ dst[8] = bcd;
+ dst[10] = cd;
+ dst[12] = controlPoint3;
+}
+
+#ifndef NDEBUG
+bool isUnitInterval(float x)
+{
+ return x > 0 && x < 1;
+}
+#endif
+
+void chopCubicAtTValues(const FloatPoint src[4], FloatPoint dst[], const float tValues[], int roots)
+{
+#ifndef NDEBUG
+ for (int i = 0; i < roots - 1; ++i) {
+ ASSERT(isUnitInterval(tValues[i]));
+ ASSERT(isUnitInterval(tValues[i+1]));
+ ASSERT(tValues[i] < tValues[i+1]);
+ }
+#endif
+
+ if (!roots) {
+ // nothing to chop
+ for (int j = 0; j < 4; ++j)
+ dst[j] = src[j];
+ return;
+ }
+
+ float t = tValues[0];
+ FloatPoint tmp[4];
+ for (int j = 0; j < 4; ++j)
+ tmp[j] = src[j];
+
+ for (int i = 0; i < roots; ++i) {
+ chopCubicAt(tmp, dst, t);
+ if (i == roots - 1)
+ break;
+
+ dst += 3;
+ // Make tmp contain the remaining cubic (after the first chop).
+ for (int j = 0; j < 4; ++j)
+ tmp[j] = dst[j];
+
+ // Watch out for the case that the renormalized t isn't in range.
+ if (!safeUnitDivide(tValues[i+1] - tValues[i], 1.0f - tValues[i], t)) {
+ // If it isn't, just create a degenerate cubic.
+ dst[4] = dst[5] = dst[6] = tmp[3];
+ break;
+ }
+ }
+}
+
+void flattenDoubleCubicYExtrema(FloatPoint coords[7])
+{
+ coords[2].setY(coords[3].y());
+ coords[4].setY(coords[3].y());
+}
+
+int chopCubicAtYExtrema(const FloatPoint src[4], FloatPoint dst[10])
+{
+ float tValues[2];
+ int roots = findCubicExtrema(src[0].y(), src[1].y(), src[2].y(), src[3].y(), tValues);
+
+ chopCubicAtTValues(src, dst, tValues, roots);
+ if (roots) {
+ // we do some cleanup to ensure our Y extrema are flat
+ flattenDoubleCubicYExtrema(&dst[0]);
+ if (roots == 2)
+ flattenDoubleCubicYExtrema(&dst[3]);
+ }
+ return roots;
+}
+
+} // anonymous namespace
+
+// Public cubic operations.
+
+void chopCubicAt(const FloatPoint src[4], FloatPoint dst[7], float t)
+{
+ ASSERT(t >= 0 && t <= 1);
+
+ float output[14];
+ interpolateCubicCoords(src[0].x(), src[1].x(), src[2].x(), src[3].x(), &output[0], t);
+ interpolateCubicCoords(src[0].y(), src[1].y(), src[2].y(), src[3].y(), &output[1], t);
+ for (int i = 0; i < 7; i++)
+ dst[i].set(output[2 * i], output[2 * i + 1]);
+}
+
+// Public XRay queries.
+
+bool xRayCrossesLine(const XRay& xRay, const FloatPoint pts[2], bool& ambiguous)
+{
+ ambiguous = false;
+
+ // Determine quick discards.
+ // Consider query line going exactly through point 0 to not
+ // intersect, for symmetry with xRayCrossesMonotonicCubic.
+ if (xRay.y() == pts[0].y()) {
+ ambiguous = true;
+ return false;
+ }
+ if (xRay.y() < pts[0].y() && xRay.y() < pts[1].y())
+ return false;
+ if (xRay.y() > pts[0].y() && xRay.y() > pts[1].y())
+ return false;
+ if (xRay.x() > pts[0].x() && xRay.x() > pts[1].x())
+ return false;
+ // Determine degenerate cases
+ if (nearlyZero(pts[0].y() - pts[1].y()))
+ return false;
+ if (nearlyZero(pts[0].x() - pts[1].x())) {
+ // We've already determined the query point lies within the
+ // vertical range of the line segment.
+ if (xRay.x() <= pts[0].x()) {
+ ambiguous = (xRay.y() == pts[1].y());
+ return true;
+ }
+ return false;
+ }
+ // Ambiguity check
+ if (xRay.y() == pts[1].y()) {
+ if (xRay.x() <= pts[1].x()) {
+ ambiguous = true;
+ return true;
+ }
+ return false;
+ }
+ // Full line segment evaluation
+ float deltaY = pts[1].y() - pts[0].y();
+ float deltaX = pts[1].x() - pts[0].x();
+ float slope = deltaY / deltaX;
+ float b = pts[0].y() - slope * pts[0].x();
+ // Solve for x coordinate at y = xRay.y()
+ float x = (xRay.y() - b) / slope;
+ return xRay.x() <= x;
+}
+
+int numXRayCrossingsForCubic(const XRay& xRay, const FloatPoint cubic[4], bool& ambiguous)
+{
+ int numCrossings = 0;
+ FloatPoint monotonicCubics[10];
+ int numMonotonicCubics = 1 + chopCubicAtYExtrema(cubic, monotonicCubics);
+ ambiguous = false;
+ FloatPoint* monotonicCubicsPointer = &monotonicCubics[0];
+ for (int i = 0; i < numMonotonicCubics; ++i) {
+ if (xRayCrossesMonotonicCubic(xRay, monotonicCubicsPointer, ambiguous))
+ ++numCrossings;
+ if (ambiguous)
+ return 0;
+ monotonicCubicsPointer += 3;
+ }
+ return numCrossings;
+}
+
+} // namespace LoopBlinnMathUtils
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h b/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h
new file mode 100644
index 0000000..b9d19c5
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnMathUtils_h
+#define LoopBlinnMathUtils_h
+
+#include "FloatPoint.h"
+#include "FloatPoint3D.h"
+#include <math.h>
+
+namespace WebCore {
+
+// Use a namespace for these so we can easily import them.
+namespace LoopBlinnMathUtils {
+
+float roundToZero(float val);
+bool approxEqual(const FloatPoint& v0, const FloatPoint& v1);
+bool approxEqual(const FloatPoint3D& v0, const FloatPoint3D& v1);
+bool approxEqual(float f0, float f1);
+
+// Determines whether the line segment between (p1, q1) intersects
+// that between (p2, q2).
+bool linesIntersect(const FloatPoint& p1,
+ const FloatPoint& q1,
+ const FloatPoint& p2,
+ const FloatPoint& q2);
+
+// Determines whether "point" is inside the 2D triangle defined by
+// vertices a, b, and c. This test defines that points exactly on an
+// edge are not considered to be inside the triangle.
+bool pointInTriangle(const FloatPoint& point,
+ const FloatPoint& a,
+ const FloatPoint& b,
+ const FloatPoint& c);
+
+// Determines whether the triangles defined by the points (a1, b1, c1)
+// and (a2, b2, c2) overlap. The definition of this function is that
+// if the two triangles only share an adjacent edge or vertex, they
+// are not considered to overlap.
+bool trianglesOverlap(const FloatPoint& a1,
+ const FloatPoint& b1,
+ const FloatPoint& c1,
+ const FloatPoint& a2,
+ const FloatPoint& b2,
+ const FloatPoint& c2);
+
+// Given a src cubic bezier, chops it at the specified t value,
+// where 0 < t < 1, and returns the two new cubics in dst[0..3]
+// and dst[3..6].
+void chopCubicAt(const FloatPoint src[4], FloatPoint dst[7], float t);
+
+// "X-Ray" queries. An XRay is a half-line originating at the given
+// point and extending to x=+infinity.
+typedef FloatPoint XRay;
+
+// Given an arbitrary cubic bezier, return the number of times an XRay
+// crosses the cubic. Valid return values are [0..3].
+//
+// By definition the cubic is open at the starting point; in other
+// words, if pt.fY is equivalent to cubic[0].fY, and pt.fX is to the
+// left of the curve, the line is not considered to cross the curve,
+// but if it is equal to cubic[3].fY then it is considered to
+// cross.
+//
+// Outgoing "ambiguous" argument indicates whether the answer is ambiguous
+// because the query occurred exactly at one of the endpoints' y
+// coordinates or at a tangent point, indicating that another query y
+// coordinate is preferred for robustness.
+int numXRayCrossingsForCubic(const XRay& xRay,
+ const FloatPoint cubic[4],
+ bool& ambiguous);
+
+// Given a line segment from lineEndpoints[0] to lineEndpoints[1], and an
+// XRay, returns true if they intersect. Outgoing "ambiguous" argument
+// indicates whether the answer is ambiguous because the query occurred
+// exactly at one of the endpoints' y coordinates, indicating that another
+// query y coordinate is preferred for robustness.
+bool xRayCrossesLine(const XRay& xRay,
+ const FloatPoint lineEndpoints[2],
+ bool& ambiguous);
+
+} // namespace LoopBlinnMathUtils
+
+} // namespace WebCore
+
+#endif // LoopBlinnMathUtils_h
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.cpp b/WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.cpp
new file mode 100644
index 0000000..ac82637
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnTextureCoords.h"
+
+#include <math.h>
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+LoopBlinnTextureCoords::Result LoopBlinnTextureCoords::compute(const LoopBlinnClassifier::Result& classification, LoopBlinnConstants::FillSide sideToFill)
+{
+ // Loop and Blinn's formulation states that the right side of the
+ // curve is defined to be the inside (filled region), but for some
+ // reason it looks like with the default orientation parameters we
+ // are filling the left side of the curve. Regardless, because we
+ // can receive arbitrarily oriented curves as input, we might have
+ // to reverse the orientation of the cubic texture coordinates even
+ // in cases where the paper doesn't say it is necessary.
+ bool reverseOrientation = false;
+ static const float OneThird = 1.0f / 3.0f;
+ static const float TwoThirds = 2.0f / 3.0f;
+ LoopBlinnClassifier::CurveType curveType = classification.curveType;
+
+ LoopBlinnTextureCoords::Result result;
+
+ switch (curveType) {
+ case LoopBlinnClassifier::kSerpentine: {
+ float t1 = sqrtf(9.0f * classification.d2 * classification.d2 - 12 * classification.d1 * classification.d3);
+ float ls = 3.0f * classification.d2 - t1;
+ float lt = 6.0f * classification.d1;
+ float ms = 3.0f * classification.d2 + t1;
+ float mt = lt;
+ float ltMinusLs = lt - ls;
+ float mtMinusMs = mt - ms;
+ result.klmCoordinates[0] = FloatPoint3D(ls * ms,
+ ls * ls * ls,
+ ms * ms * ms);
+ result.klmCoordinates[1] = FloatPoint3D(OneThird * (3.0f * ls * ms - ls * mt - lt * ms),
+ ls * ls * (ls - lt),
+ ms * ms * (ms - mt));
+ result.klmCoordinates[2] = FloatPoint3D(OneThird * (lt * (mt - 2.0f * ms) + ls * (3.0f * ms - 2.0f * mt)),
+ ltMinusLs * ltMinusLs * ls,
+ mtMinusMs * mtMinusMs * ms);
+ result.klmCoordinates[3] = FloatPoint3D(ltMinusLs * mtMinusMs,
+ -(ltMinusLs * ltMinusLs * ltMinusLs),
+ -(mtMinusMs * mtMinusMs * mtMinusMs));
+ if (classification.d1 < 0.0f)
+ reverseOrientation = true;
+ break;
+ }
+
+ case LoopBlinnClassifier::kLoop: {
+ float t1 = sqrtf(4.0f * classification.d1 * classification.d3 - 3.0f * classification.d2 * classification.d2);
+ float ls = classification.d2 - t1;
+ float lt = 2.0f * classification.d1;
+ float ms = classification.d2 + t1;
+ float mt = lt;
+
+ // Figure out whether there is a rendering artifact requiring
+ // the curve to be subdivided by the caller.
+ float ql = ls / lt;
+ float qm = ms / mt;
+ if (0.0f < ql && ql < 1.0f) {
+ result.hasRenderingArtifact = true;
+ result.subdivisionParameterValue = ql;
+ return result;
+ }
+
+ if (0.0f < qm && qm < 1.0f) {
+ result.hasRenderingArtifact = true;
+ result.subdivisionParameterValue = qm;
+ return result;
+ }
+
+ float ltMinusLs = lt - ls;
+ float mtMinusMs = mt - ms;
+ result.klmCoordinates[0] = FloatPoint3D(ls * ms,
+ ls * ls * ms,
+ ls * ms * ms);
+ result.klmCoordinates[1] = FloatPoint3D(OneThird * (-ls * mt - lt * ms + 3.0f * ls * ms),
+ -OneThird * ls * (ls * (mt - 3.0f * ms) + 2.0f * lt * ms),
+ -OneThird * ms * (ls * (2.0f * mt - 3.0f * ms) + lt * ms));
+ result.klmCoordinates[2] = FloatPoint3D(OneThird * (lt * (mt - 2.0f * ms) + ls * (3.0f * ms - 2.0f * mt)),
+ OneThird * (lt - ls) * (ls * (2.0f * mt - 3.0f * ms) + lt * ms),
+ OneThird * (mt - ms) * (ls * (mt - 3.0f * ms) + 2.0f * lt * ms));
+ result.klmCoordinates[3] = FloatPoint3D(ltMinusLs * mtMinusMs,
+ -(ltMinusLs * ltMinusLs) * mtMinusMs,
+ -ltMinusLs * mtMinusMs * mtMinusMs);
+ reverseOrientation = ((classification.d1 > 0.0f && result.klmCoordinates[0].x() < 0.0f)
+ || (classification.d1 < 0.0f && result.klmCoordinates[0].x() > 0.0f));
+ break;
+ }
+
+ case LoopBlinnClassifier::kCusp: {
+ float ls = classification.d3;
+ float lt = 3.0f * classification.d2;
+ float lsMinusLt = ls - lt;
+ result.klmCoordinates[0] = FloatPoint3D(ls,
+ ls * ls * ls,
+ 1.0f);
+ result.klmCoordinates[1] = FloatPoint3D(ls - OneThird * lt,
+ ls * ls * lsMinusLt,
+ 1.0f);
+ result.klmCoordinates[2] = FloatPoint3D(ls - TwoThirds * lt,
+ lsMinusLt * lsMinusLt * ls,
+ 1.0f);
+ result.klmCoordinates[3] = FloatPoint3D(lsMinusLt,
+ lsMinusLt * lsMinusLt * lsMinusLt,
+ 1.0f);
+ break;
+ }
+
+ case LoopBlinnClassifier::kQuadratic: {
+ result.klmCoordinates[0] = FloatPoint3D(0, 0, 0);
+ result.klmCoordinates[1] = FloatPoint3D(OneThird, 0, OneThird);
+ result.klmCoordinates[2] = FloatPoint3D(TwoThirds, OneThird, TwoThirds);
+ result.klmCoordinates[3] = FloatPoint3D(1, 1, 1);
+ if (classification.d3 < 0)
+ reverseOrientation = true;
+ break;
+ }
+
+ case LoopBlinnClassifier::kLine:
+ case LoopBlinnClassifier::kPoint:
+ result.isLineOrPoint = true;
+ break;
+
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ if (sideToFill == LoopBlinnConstants::RightSide)
+ reverseOrientation = !reverseOrientation;
+
+ if (reverseOrientation) {
+ for (int i = 0; i < 4; ++i) {
+ result.klmCoordinates[i].setX(-result.klmCoordinates[i].x());
+ result.klmCoordinates[i].setY(-result.klmCoordinates[i].y());
+ }
+ }
+
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.h b/WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.h
new file mode 100644
index 0000000..5fdeb3b
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnTextureCoords.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnTextureCoords_h
+#define LoopBlinnTextureCoords_h
+
+#include "FloatPoint3D.h"
+#include "LoopBlinnClassifier.h"
+#include "LoopBlinnConstants.h"
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+// Computes three-dimensional texture coordinates for the control
+// points of a cubic curve for rendering via the shader in "Rendering
+// Vector Art on the GPU" by Loop and Blinn, GPU Gems 3, Chapter 25.
+class LoopBlinnTextureCoords {
+public:
+ // Container for the cubic texture coordinates and other associated
+ // information.
+ struct Result {
+ Result()
+ : isLineOrPoint(false)
+ , hasRenderingArtifact(false)
+ , subdivisionParameterValue(0.0f) { }
+
+ // The (k, l, m) texture coordinates that are to be associated
+ // with the four control points of the cubic curve.
+ FloatPoint3D klmCoordinates[4];
+
+ // Indicates whether the curve is a line or a point, in which case
+ // we do not need to add its triangles to the mesh.
+ bool isLineOrPoint;
+
+ // For the loop case, indicates whether a rendering artifact was
+ // detected, in which case the curve needs to be further
+ // subdivided.
+ bool hasRenderingArtifact;
+
+ // If a rendering artifact will occur for the given loop curve,
+ // this is the parameter value (0 <= value <= 1) at which the
+ // curve needs to be subdivided to fix the artifact.
+ float subdivisionParameterValue;
+ };
+
+ // Computes the texture coordinates for a cubic curve segment's
+ // control points, given the classification of the curve as well as
+ // an indication of which side is to be filled.
+ static Result compute(const LoopBlinnClassifier::Result& classification,
+ LoopBlinnConstants::FillSide sideToFill);
+
+private:
+ // This class does not need to be instantiated.
+ LoopBlinnTextureCoords() { }
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnTextureCoords_h
diff --git a/WebCore/platform/graphics/gpu/PODArena.h b/WebCore/platform/graphics/gpu/PODArena.h
new file mode 100644
index 0000000..f68baef
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/PODArena.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PODArena_h
+#define PODArena_h
+
+#include <stdint.h>
+#include <wtf/Assertions.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// An arena which allocates only Plain Old Data (POD), or classes and
+// structs bottoming out in Plain Old Data. NOTE: the constructors of
+// the objects allocated in this arena are called, but _not_ their
+// destructors.
+
+class PODArena : public RefCounted<PODArena> {
+public:
+ // The arena is configured with an allocator, which is responsible
+ // for allocating and freeing chunks of memory at a time.
+ class Allocator : public RefCounted<Allocator> {
+ public:
+ virtual void* allocate(size_t size) = 0;
+ virtual void free(void* ptr) = 0;
+ protected:
+ virtual ~Allocator() { }
+ friend class WTF::RefCounted<Allocator>;
+ };
+
+ // The Arena's default allocator, which uses fastMalloc and
+ // fastFree to allocate chunks of storage.
+ class FastMallocAllocator : public Allocator {
+ public:
+ static PassRefPtr<FastMallocAllocator> create()
+ {
+ return adoptRef(new FastMallocAllocator);
+ }
+
+ virtual void* allocate(size_t size) { return fastMalloc(size); }
+ virtual void free(void* ptr) { fastFree(ptr); }
+
+ protected:
+ FastMallocAllocator() { }
+ };
+
+ // Creates a new PODArena configured with a FastMallocAllocator.
+ static PassRefPtr<PODArena> create()
+ {
+ return adoptRef(new PODArena);
+ }
+
+ // Creates a new PODArena configured with the given Allocator.
+ static PassRefPtr<PODArena> create(PassRefPtr<Allocator> allocator)
+ {
+ return adoptRef(new PODArena(allocator));
+ }
+
+ // Allocates an object from the arena.
+ template<class T> T* allocateObject()
+ {
+ void* ptr = allocateBase<T>();
+ if (ptr) {
+ // Use placement operator new to allocate a T at this location.
+ new(ptr) T();
+ }
+ return static_cast<T*>(ptr);
+ }
+
+ // Allocates an object from the arena, calling a single-argument constructor.
+ template<class T, class Argument1Type> T* allocateObject(const Argument1Type& argument1)
+ {
+ void* ptr = allocateBase<T>();
+ if (ptr) {
+ // Use placement operator new to allocate a T at this location.
+ new(ptr) T(argument1);
+ }
+ return static_cast<T*>(ptr);
+ }
+
+ // The initial size of allocated chunks; increases as necessary to
+ // satisfy large allocations. Mainly public for unit tests.
+ enum {
+ DefaultChunkSize = 16384
+ };
+
+protected:
+ ~PODArena() { }
+ friend class WTF::RefCounted<PODArena>;
+
+private:
+ PODArena()
+ : m_allocator(FastMallocAllocator::create())
+ , m_current(0)
+ , m_currentChunkSize(DefaultChunkSize) { }
+
+ explicit PODArena(PassRefPtr<Allocator> allocator)
+ : m_allocator(allocator)
+ , m_current(0)
+ , m_currentChunkSize(DefaultChunkSize) { }
+
+ // Returns the alignment requirement for classes and structs on the
+ // current platform.
+ template <class T> static size_t minAlignment()
+ {
+ return WTF_ALIGN_OF(T);
+ }
+
+ template<class T> void* allocateBase()
+ {
+ void* ptr = 0;
+ size_t roundedSize = roundUp(sizeof(T), minAlignment<T>());
+ if (m_current)
+ ptr = m_current->allocate(roundedSize);
+
+ if (!ptr) {
+ if (roundedSize > m_currentChunkSize)
+ m_currentChunkSize = roundedSize;
+ m_chunks.append(adoptPtr(new Chunk(m_allocator.get(), m_currentChunkSize)));
+ m_current = m_chunks.last().get();
+ ptr = m_current->allocate(roundedSize);
+ }
+ return ptr;
+ }
+
+ // Rounds up the given allocation size to the specified alignment.
+ size_t roundUp(size_t size, size_t alignment)
+ {
+ ASSERT(!(alignment % 2));
+ return (size + alignment - 1) & ~(alignment - 1);
+ }
+
+ // Manages a chunk of memory and individual allocations out of it.
+ class Chunk : public Noncopyable {
+ public:
+ // Allocates a block of memory of the given size from the passed
+ // Allocator.
+ Chunk(Allocator* allocator, size_t size)
+ : m_allocator(allocator)
+ , m_size(size)
+ , m_currentOffset(0)
+ {
+ m_base = static_cast<uint8_t*>(m_allocator->allocate(size));
+ }
+
+ // Frees the memory allocated from the Allocator in the
+ // constructor.
+ ~Chunk()
+ {
+ m_allocator->free(m_base);
+ }
+
+ // Returns a pointer to "size" bytes of storage, or 0 if this
+ // Chunk could not satisfy the allocation.
+ void* allocate(size_t size)
+ {
+ // Check for overflow
+ if (m_currentOffset + size < m_currentOffset)
+ return 0;
+
+ if (m_currentOffset + size > m_size)
+ return 0;
+
+ void* result = m_base + m_currentOffset;
+ m_currentOffset += size;
+ return result;
+ }
+
+ private:
+ Allocator* m_allocator;
+ uint8_t* m_base;
+ size_t m_size;
+ size_t m_currentOffset;
+ };
+
+ RefPtr<Allocator> m_allocator;
+ Chunk* m_current;
+ size_t m_currentChunkSize;
+ Vector<OwnPtr<Chunk> > m_chunks;
+};
+
+} // namespace WebCore
+
+#endif // PODArena_h
diff --git a/WebCore/platform/graphics/gpu/PODInterval.h b/WebCore/platform/graphics/gpu/PODInterval.h
new file mode 100644
index 0000000..9df69ba
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/PODInterval.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PODInterval_h
+#define PODInterval_h
+
+#ifndef NDEBUG
+#include "StringBuilder.h"
+#endif
+
+namespace WebCore {
+
+// Class representing a closed interval which can hold an arbitrary
+// Plain Old Datatype (POD) as its endpoints and a piece of user
+// data. An important characteristic for the algorithms we use is that
+// if two intervals have identical endpoints but different user data,
+// they are not considered to be equal. This situation can arise when
+// representing the vertical extents of bounding boxes of overlapping
+// triangles, where the pointer to the triangle is the user data of
+// the interval.
+//
+// *Note* that the destructors of type T and UserData will *not* be
+// called by this class. They must not allocate any memory that is
+// required to be cleaned up in their destructors.
+//
+// The following constructors and operators must be implemented on
+// type T:
+//
+// - Copy constructor (if user data is desired)
+// - operator<
+// - operator==
+// - operator=
+//
+// If the UserData type is specified, it must support a copy
+// constructor and assignment operator.
+//
+// In debug mode, printing of intervals and the data they contain is
+// enabled. This requires the following functions to be available:
+//
+// String valueToString(const T&);
+// String valueToString(const UserData&);
+//
+// Note that this class requires a copy constructor and assignment
+// operator in order to be stored in the red-black tree.
+
+template<class T, class UserData = void*>
+class PODInterval {
+public:
+ // Constructor from endpoints. This constructor only works when the
+ // UserData type is a pointer or other type which can be initialized
+ // with 0.
+ PODInterval(const T& low, const T& high)
+ : m_low(low)
+ , m_high(high)
+ , m_data(0)
+ , m_maxHigh(high)
+ {
+ }
+
+ // Constructor from two endpoints plus explicit user data.
+ PODInterval(const T& low, const T& high, const UserData data)
+ : m_low(low)
+ , m_high(high)
+ , m_data(data)
+ , m_maxHigh(high)
+ {
+ }
+
+ const T& low() const { return m_low; }
+ const T& high() const { return m_high; }
+ const UserData& data() const { return m_data; }
+
+ bool overlaps(const T& low, const T& high) const
+ {
+ if (this->high() < low)
+ return false;
+ if (high < this->low())
+ return false;
+ return true;
+ }
+
+ bool overlaps(const PODInterval& other) const
+ {
+ return overlaps(other.low(), other.high());
+ }
+
+ // Returns true if this interval is "less" than the other. The
+ // comparison is performed on the low endpoints of the intervals.
+ bool operator<(const PODInterval& other) const
+ {
+ return low() < other.low();
+ }
+
+ // Returns true if this interval is strictly equal to the other,
+ // including comparison of the user data.
+ bool operator==(const PODInterval& other) const
+ {
+ return (low() == other.low()
+ && high() == other.high()
+ && data() == other.data());
+ }
+
+ const T& maxHigh() const { return m_maxHigh; }
+ void setMaxHigh(const T& maxHigh) { m_maxHigh = maxHigh; }
+
+#ifndef NDEBUG
+ // Support for printing PODIntervals.
+ String toString() const
+ {
+ StringBuilder builder;
+ builder.append("[PODInterval (");
+ builder.append(valueToString(low()));
+ builder.append(", ");
+ builder.append(valueToString(high()));
+ builder.append("), data=");
+ builder.append(valueToString(data()));
+ builder.append(", maxHigh=");
+ builder.append(valueToString(maxHigh()));
+ builder.append("]");
+ return builder.toString();
+ }
+#endif
+
+private:
+ T m_low;
+ T m_high;
+ UserData m_data;
+ T m_maxHigh;
+};
+
+} // namespace WebCore
+
+#endif // PODInterval_h
diff --git a/WebCore/platform/graphics/gpu/PODIntervalTree.h b/WebCore/platform/graphics/gpu/PODIntervalTree.h
new file mode 100644
index 0000000..c0a86aa
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/PODIntervalTree.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PODIntervalTree_h
+#define PODIntervalTree_h
+
+#include "PODArena.h"
+#include "PODInterval.h"
+#include "PODRedBlackTree.h"
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// An interval tree, which is a form of augmented red-black tree. It
+// supports efficient (O(lg n)) insertion, removal and querying of
+// intervals in the tree.
+template<class T, class UserData = void*>
+class PODIntervalTree : public Noncopyable,
+ public PODRedBlackTree<PODInterval<T, UserData> > {
+public:
+ // Typedef to reduce typing when declaring intervals to be stored in
+ // this tree.
+ typedef PODInterval<T, UserData> IntervalType;
+
+ PODIntervalTree()
+ : PODRedBlackTree<IntervalType>()
+ {
+ init();
+ }
+
+ explicit PODIntervalTree(PassRefPtr<PODArena> arena)
+ : PODRedBlackTree<IntervalType>(arena)
+ {
+ init();
+ }
+
+ // Returns all intervals in the tree which overlap the given query
+ // interval. The returned intervals are sorted by increasing low
+ // endpoint.
+ Vector<IntervalType> allOverlaps(const IntervalType& interval) const
+ {
+ Vector<IntervalType> result;
+ allOverlaps(interval, result);
+ return result;
+ }
+
+ // Returns all intervals in the tree which overlap the given query
+ // interval. The returned intervals are sorted by increasing low
+ // endpoint.
+ void allOverlaps(const IntervalType& interval, Vector<IntervalType>& result) const
+ {
+ // Explicit dereference of "this" required because of
+ // inheritance rules in template classes.
+ searchForOverlapsFrom(this->root(), interval, result);
+ }
+
+ // Helper to create interval objects.
+ static IntervalType createInterval(const T& low, const T& high, const UserData data = 0)
+ {
+ return IntervalType(low, high, data);
+ }
+
+ virtual bool checkInvariants() const
+ {
+ if (!PODRedBlackTree<IntervalType>::checkInvariants())
+ return false;
+ if (!this->root())
+ return true;
+ return checkInvariantsFromNode(this->root(), 0);
+ }
+
+private:
+ typedef typename PODRedBlackTree<IntervalType>::Node IntervalNode;
+
+ // Initializes the tree.
+ void init()
+ {
+ // Explicit dereference of "this" required because of
+ // inheritance rules in template classes.
+ this->setNeedsFullOrderingComparisons(true);
+ }
+
+ // Starting from the given node, adds all overlaps with the given
+ // interval to the result vector. The intervals are sorted by
+ // increasing low endpoint.
+ void searchForOverlapsFrom(IntervalNode* node, const IntervalType& interval, Vector<IntervalType>& res) const
+ {
+ if (!node)
+ return;
+
+ // Because the intervals are sorted by left endpoint, inorder
+ // traversal produces results sorted as desired.
+
+ // See whether we need to traverse the left subtree.
+ IntervalNode* left = node->left();
+ if (left
+ // This is phrased this way to avoid the need for operator
+ // <= on type T.
+ && !(left->data().maxHigh() < interval.low()))
+ searchForOverlapsFrom(left, interval, res);
+
+ // Check for overlap with current node.
+ if (node->data().overlaps(interval))
+ res.append(node->data());
+
+ // See whether we need to traverse the right subtree.
+ // This is phrased this way to avoid the need for operator <=
+ // on type T.
+ if (!(interval.high() < node->data().low()))
+ searchForOverlapsFrom(node->right(), interval, res);
+ }
+
+ virtual bool updateNode(IntervalNode* node)
+ {
+ // Would use const T&, but need to reassign this reference in this
+ // function.
+ const T* curMax = &node->data().high();
+ IntervalNode* left = node->left();
+ if (left) {
+ if (*curMax < left->data().maxHigh())
+ curMax = &left->data().maxHigh();
+ }
+ IntervalNode* right = node->right();
+ if (right) {
+ if (*curMax < right->data().maxHigh())
+ curMax = &right->data().maxHigh();
+ }
+ // This is phrased like this to avoid needing operator!= on type T.
+ if (!(*curMax == node->data().maxHigh())) {
+ node->data().setMaxHigh(*curMax);
+ return true;
+ }
+ return false;
+ }
+
+ bool checkInvariantsFromNode(IntervalNode* node, T* currentMaxValue) const
+ {
+ // These assignments are only done in order to avoid requiring
+ // a default constructor on type T.
+ T leftMaxValue(node->data().maxHigh());
+ T rightMaxValue(node->data().maxHigh());
+ IntervalNode* left = node->left();
+ IntervalNode* right = node->right();
+ if (left) {
+ if (!checkInvariantsFromNode(left, &leftMaxValue))
+ return false;
+ }
+ if (right) {
+ if (!checkInvariantsFromNode(right, &rightMaxValue))
+ return false;
+ }
+ if (!left && !right) {
+ // Base case.
+ if (currentMaxValue)
+ *currentMaxValue = node->data().high();
+ return (node->data().high() == node->data().maxHigh());
+ }
+ T localMaxValue(node->data().maxHigh());
+ if (!left || !right) {
+ if (left)
+ localMaxValue = leftMaxValue;
+ else
+ localMaxValue = rightMaxValue;
+ } else
+ localMaxValue = (leftMaxValue < rightMaxValue) ? rightMaxValue : leftMaxValue;
+ if (localMaxValue < node->data().high())
+ localMaxValue = node->data().high();
+ if (!(localMaxValue == node->data().maxHigh())) {
+#ifndef NDEBUG
+ String localMaxValueString = valueToString(localMaxValue);
+ LOG_ERROR("PODIntervalTree verification failed at node 0x%p: localMaxValue=%s and data=%s",
+ node, localMaxValueString.utf8().data(), node->data().toString().utf8().data());
+#endif
+ return false;
+ }
+ if (currentMaxValue)
+ *currentMaxValue = localMaxValue;
+ return true;
+ }
+};
+
+#ifndef NDEBUG
+// Support for printing PODIntervals at the PODRedBlackTree level.
+template<class T, class UserData>
+String valueToString(const PODInterval<T, UserData>& interval)
+{
+ return interval.toString();
+}
+#endif
+
+} // namespace WebCore
+
+#endif // PODIntervalTree_h
diff --git a/WebCore/platform/graphics/gpu/PODRedBlackTree.h b/WebCore/platform/graphics/gpu/PODRedBlackTree.h
new file mode 100644
index 0000000..9b02037
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/PODRedBlackTree.h
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// A red-black tree, which is a form of a balanced binary tree. It
+// supports efficient insertion, deletion and queries of comparable
+// elements. The same element may be inserted multiple times. The
+// algorithmic complexity of common operations is:
+//
+// Insertion: O(lg(n))
+// Deletion: O(lg(n))
+// Querying: O(lg(n))
+//
+// The data type T that is stored in this red-black tree must be only
+// Plain Old Data (POD), or bottom out into POD. It must _not_ rely on
+// having its destructor called. This implementation internally
+// allocates storage in large chunks and does not call the destructor
+// on each object.
+//
+// Type T must supply a default constructor, a copy constructor, and
+// the "<" and "==" operators.
+//
+// In debug mode, printing of the data contained in the tree is
+// enabled. This requires the following function to be available:
+//
+// String valueToString(const T&);
+//
+// Note that when complex types are stored in this red/black tree, it
+// is possible that single invocations of the "<" and "==" operators
+// will be insufficient to describe the ordering of elements in the
+// tree during queries. As a concrete example, consider the case where
+// intervals are stored in the tree sorted by low endpoint. The "<"
+// operator on the Interval class only compares the low endpoint, but
+// the "==" operator takes into account the high endpoint as well.
+// This makes the necessary logic for querying and deletion somewhat
+// more complex. In order to properly handle such situations, the
+// property "needsFullOrderingComparisons" must be set to true on
+// the tree.
+//
+// This red-black tree is designed to be _augmented_; subclasses can
+// add additional and summary information to each node to efficiently
+// store and index more complex data structures. A concrete example is
+// the IntervalTree, which extends each node with a summary statistic
+// to efficiently store one-dimensional intervals.
+//
+// The design of this red-black tree comes from Cormen, Leiserson,
+// and Rivest, _Introduction to Algorithms_, MIT Press, 1990.
+
+#ifndef PODRedBlackTree_h
+#define PODRedBlackTree_h
+
+#include "PODArena.h"
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+#ifndef NDEBUG
+#include "Logging.h"
+#include "PlatformString.h"
+#include "StringBuilder.h"
+#include <wtf/text/CString.h>
+#endif
+
+namespace WebCore {
+
+template<class T>
+class PODRedBlackTree {
+public:
+ // Visitor interface for walking all of the tree's elements.
+ class Visitor {
+ public:
+ virtual void visit(const T& data) = 0;
+ protected:
+ virtual ~Visitor() { }
+ };
+
+ // Constructs a new red-black tree, allocating temporary objects
+ // from a newly constructed PODArena.
+ PODRedBlackTree()
+ : m_arena(PODArena::create())
+ , m_root(0)
+ , m_needsFullOrderingComparisons(false)
+#ifndef NDEBUG
+ , m_verboseDebugging(false)
+#endif
+ {
+ }
+
+ // Constructs a new red-black tree, allocating temporary objects
+ // from the given PODArena.
+ explicit PODRedBlackTree(PassRefPtr<PODArena> arena)
+ : m_arena(arena)
+ , m_root(0)
+ , m_needsFullOrderingComparisons(false)
+#ifndef NDEBUG
+ , m_verboseDebugging(false)
+#endif
+ {
+ }
+
+ virtual ~PODRedBlackTree() { }
+
+ void add(const T& data)
+ {
+ Node* node = m_arena->allocateObject<Node, T>(data);
+ insertNode(node);
+ }
+
+ // Returns true if the datum was found in the tree.
+ bool remove(const T& data)
+ {
+ Node* node = treeSearch(data);
+ if (node) {
+ deleteNode(node);
+ return true;
+ }
+ return false;
+ }
+
+ bool contains(const T& data) const { return treeSearch(data); }
+
+ void visitInorder(Visitor* visitor) const
+ {
+ if (!m_root)
+ return;
+ visitInorderImpl(m_root, visitor);
+ }
+
+ int size() const
+ {
+ Counter counter;
+ visitInorder(&counter);
+ return counter.count();
+ }
+
+ // See the class documentation for an explanation of this property.
+ void setNeedsFullOrderingComparisons(bool needsFullOrderingComparisons)
+ {
+ m_needsFullOrderingComparisons = needsFullOrderingComparisons;
+ }
+
+ virtual bool checkInvariants() const
+ {
+ int blackCount;
+ return checkInvariantsFromNode(m_root, &blackCount);
+ }
+
+#ifndef NDEBUG
+ // Dumps the tree's contents to the logging info stream for
+ // debugging purposes.
+ void dump() const
+ {
+ dumpFromNode(m_root, 0);
+ }
+
+ // Turns on or off verbose debugging of the tree, causing many
+ // messages to be logged during insertion and other operations in
+ // debug mode.
+ void setVerboseDebugging(bool verboseDebugging)
+ {
+ m_verboseDebugging = verboseDebugging;
+ }
+#endif
+
+protected:
+ enum Color {
+ Red = 1,
+ Black
+ };
+
+ // The base Node class which is stored in the tree. Nodes are only
+ // an internal concept; users of the tree deal only with the data
+ // they store in it.
+ class Node : public Noncopyable {
+ public:
+ // Constructor. Newly-created nodes are colored red.
+ explicit Node(const T& data)
+ : m_left(0)
+ , m_right(0)
+ , m_parent(0)
+ , m_color(Red)
+ , m_data(data)
+ {
+ }
+
+ virtual ~Node() { }
+
+ Color color() const { return m_color; }
+ void setColor(Color color) { m_color = color; }
+
+ // Fetches the user data.
+ T& data() { return m_data; }
+
+ // Copies all user-level fields from the source node, but not
+ // internal fields. For example, the base implementation of this
+ // method copies the "m_data" field, but not the child or parent
+ // fields. Any augmentation information also does not need to be
+ // copied, as it will be recomputed. Subclasses must call the
+ // superclass implementation.
+ virtual void copyFrom(Node* src) { m_data = src->data(); }
+
+ Node* left() const { return m_left; }
+ void setLeft(Node* node) { m_left = node; }
+
+ Node* right() const { return m_right; }
+ void setRight(Node* node) { m_right = node; }
+
+ Node* parent() const { return m_parent; }
+ void setParent(Node* node) { m_parent = node; }
+
+ private:
+ Node* m_left;
+ Node* m_right;
+ Node* m_parent;
+ Color m_color;
+ T m_data;
+ };
+
+ // Returns the root of the tree, which is needed by some subclasses.
+ Node* root() const { return m_root; }
+
+private:
+ // This virtual method is the hook that subclasses should use when
+ // augmenting the red-black tree with additional per-node summary
+ // information. For example, in the case of an interval tree, this
+ // is used to compute the maximum endpoint of the subtree below the
+ // given node based on the values in the left and right children. It
+ // is guaranteed that this will be called in the correct order to
+ // properly update such summary information based only on the values
+ // in the left and right children. This method should return true if
+ // the node's summary information changed.
+ virtual bool updateNode(Node* node) { return false; }
+
+ //----------------------------------------------------------------------
+ // Generic binary search tree operations
+ //
+
+ // Searches the tree for the given datum.
+ Node* treeSearch(const T& data) const
+ {
+ if (m_needsFullOrderingComparisons)
+ return treeSearchFullComparisons(m_root, data);
+
+ return treeSearchNormal(m_root, data);
+ }
+
+ // Searches the tree using the normal comparison operations,
+ // suitable for simple data types such as numbers.
+ Node* treeSearchNormal(Node* current, const T& data) const
+ {
+ while (current) {
+ if (current->data() == data)
+ return current;
+ if (data < current->data())
+ current = current->left();
+ else
+ current = current->right();
+ }
+ return 0;
+ }
+
+ // Searches the tree using multiple comparison operations, required
+ // for data types with more complex behavior such as intervals.
+ Node* treeSearchFullComparisons(Node* current, const T& data) const
+ {
+ if (!current)
+ return 0;
+ if (data < current->data())
+ return treeSearchFullComparisons(current->left(), data);
+ if (current->data() < data)
+ return treeSearchFullComparisons(current->right(), data);
+ if (data == current->data())
+ return current;
+
+ // We may need to traverse both the left and right subtrees.
+ Node* result = treeSearchFullComparisons(current->left(), data);
+ if (!result)
+ result = treeSearchFullComparisons(current->right(), data);
+ return result;
+ }
+
+ void treeInsert(Node* z)
+ {
+ Node* y = 0;
+ Node* x = m_root;
+ while (x) {
+ y = x;
+ if (z->data() < x->data())
+ x = x->left();
+ else
+ x = x->right();
+ }
+ z->setParent(y);
+ if (!y)
+ m_root = z;
+ else {
+ if (z->data() < y->data())
+ y->setLeft(z);
+ else
+ y->setRight(z);
+ }
+ }
+
+ // Finds the node following the given one in sequential ordering of
+ // their data, or null if none exists.
+ Node* treeSuccessor(Node* x)
+ {
+ if (x->right())
+ return treeMinimum(x->right());
+ Node* y = x->parent();
+ while (y && x == y->right()) {
+ x = y;
+ y = y->parent();
+ }
+ return y;
+ }
+
+ // Finds the minimum element in the sub-tree rooted at the given
+ // node.
+ Node* treeMinimum(Node* x)
+ {
+ while (x->left())
+ x = x->left();
+ return x;
+ }
+
+ // Helper for maintaining the augmented red-black tree.
+ void propagateUpdates(Node* start)
+ {
+ bool shouldContinue = true;
+ while (start && shouldContinue) {
+ shouldContinue = updateNode(start);
+ start = start->parent();
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Red-Black tree operations
+ //
+
+ // Left-rotates the subtree rooted at x.
+ // Returns the new root of the subtree (x's right child).
+ Node* leftRotate(Node* x)
+ {
+ // Set y.
+ Node* y = x->right();
+
+ // Turn y's left subtree into x's right subtree.
+ x->setRight(y->left());
+ if (y->left())
+ y->left()->setParent(x);
+
+ // Link x's parent to y.
+ y->setParent(x->parent());
+ if (!x->parent())
+ m_root = y;
+ else {
+ if (x == x->parent()->left())
+ x->parent()->setLeft(y);
+ else
+ x->parent()->setRight(y);
+ }
+
+ // Put x on y's left.
+ y->setLeft(x);
+ x->setParent(y);
+
+ // Update nodes lowest to highest.
+ updateNode(x);
+ updateNode(y);
+ return y;
+ }
+
+ // Right-rotates the subtree rooted at y.
+ // Returns the new root of the subtree (y's left child).
+ Node* rightRotate(Node* y)
+ {
+ // Set x.
+ Node* x = y->left();
+
+ // Turn x's right subtree into y's left subtree.
+ y->setLeft(x->right());
+ if (x->right())
+ x->right()->setParent(y);
+
+ // Link y's parent to x.
+ x->setParent(y->parent());
+ if (!y->parent())
+ m_root = x;
+ else {
+ if (y == y->parent()->left())
+ y->parent()->setLeft(x);
+ else
+ y->parent()->setRight(x);
+ }
+
+ // Put y on x's right.
+ x->setRight(y);
+ y->setParent(x);
+
+ // Update nodes lowest to highest.
+ updateNode(y);
+ updateNode(x);
+ return x;
+ }
+
+ // Inserts the given node into the tree.
+ void insertNode(Node* x)
+ {
+ treeInsert(x);
+ x->setColor(Red);
+ updateNode(x);
+
+ logIfVerbose(" PODRedBlackTree::InsertNode");
+
+ // The node from which to start propagating updates upwards.
+ Node* updateStart = x->parent();
+
+ while (x != m_root && x->parent()->color() == Red) {
+ if (x->parent() == x->parent()->parent()->left()) {
+ Node* y = x->parent()->parent()->right();
+ if (y && y->color() == Red) {
+ // Case 1
+ logIfVerbose(" Case 1/1");
+ x->parent()->setColor(Black);
+ y->setColor(Black);
+ x->parent()->parent()->setColor(Red);
+ updateNode(x->parent());
+ x = x->parent()->parent();
+ updateNode(x);
+ updateStart = x->parent();
+ } else {
+ if (x == x->parent()->right()) {
+ logIfVerbose(" Case 1/2");
+ // Case 2
+ x = x->parent();
+ leftRotate(x);
+ }
+ // Case 3
+ logIfVerbose(" Case 1/3");
+ x->parent()->setColor(Black);
+ x->parent()->parent()->setColor(Red);
+ Node* newSubTreeRoot = rightRotate(x->parent()->parent());
+ updateStart = newSubTreeRoot->parent();
+ }
+ } else {
+ // Same as "then" clause with "right" and "left" exchanged.
+ Node* y = x->parent()->parent()->left();
+ if (y && y->color() == Red) {
+ // Case 1
+ logIfVerbose(" Case 2/1");
+ x->parent()->setColor(Black);
+ y->setColor(Black);
+ x->parent()->parent()->setColor(Red);
+ updateNode(x->parent());
+ x = x->parent()->parent();
+ updateNode(x);
+ updateStart = x->parent();
+ } else {
+ if (x == x->parent()->left()) {
+ // Case 2
+ logIfVerbose(" Case 2/2");
+ x = x->parent();
+ rightRotate(x);
+ }
+ // Case 3
+ logIfVerbose(" Case 2/3");
+ x->parent()->setColor(Black);
+ x->parent()->parent()->setColor(Red);
+ Node* newSubTreeRoot = leftRotate(x->parent()->parent());
+ updateStart = newSubTreeRoot->parent();
+ }
+ }
+ }
+
+ propagateUpdates(updateStart);
+
+ m_root->setColor(Black);
+ }
+
+ // Restores the red-black property to the tree after splicing out
+ // a node. Note that x may be null, which is why xParent must be
+ // supplied.
+ void deleteFixup(Node* x, Node* xParent)
+ {
+ while (x != m_root && (!x || x->color() == Black)) {
+ if (x == xParent->left()) {
+ // Note: the text points out that w can not be null.
+ // The reason is not obvious from simply looking at
+ // the code; it comes about from the properties of the
+ // red-black tree.
+ Node* w = xParent->right();
+ ASSERT(w); // x's sibling should not be null.
+ if (w->color() == Red) {
+ // Case 1
+ w->setColor(Black);
+ xParent->setColor(Red);
+ leftRotate(xParent);
+ w = xParent->right();
+ }
+ if ((!w->left() || w->left()->color() == Black)
+ && (!w->right() || w->right()->color() == Black)) {
+ // Case 2
+ w->setColor(Red);
+ x = xParent;
+ xParent = x->parent();
+ } else {
+ if (!w->right() || w->right()->color() == Black) {
+ // Case 3
+ w->left()->setColor(Black);
+ w->setColor(Red);
+ rightRotate(w);
+ w = xParent->right();
+ }
+ // Case 4
+ w->setColor(xParent->color());
+ xParent->setColor(Black);
+ if (w->right())
+ w->right()->setColor(Black);
+ leftRotate(xParent);
+ x = m_root;
+ xParent = x->parent();
+ }
+ } else {
+ // Same as "then" clause with "right" and "left"
+ // exchanged.
+
+ // Note: the text points out that w can not be null.
+ // The reason is not obvious from simply looking at
+ // the code; it comes about from the properties of the
+ // red-black tree.
+ Node* w = xParent->left();
+ ASSERT(w); // x's sibling should not be null.
+ if (w->color() == Red) {
+ // Case 1
+ w->setColor(Black);
+ xParent->setColor(Red);
+ rightRotate(xParent);
+ w = xParent->left();
+ }
+ if ((!w->right() || w->right()->color() == Black)
+ && (!w->left() || w->left()->color() == Black)) {
+ // Case 2
+ w->setColor(Red);
+ x = xParent;
+ xParent = x->parent();
+ } else {
+ if (!w->left() || w->left()->color() == Black) {
+ // Case 3
+ w->right()->setColor(Black);
+ w->setColor(Red);
+ leftRotate(w);
+ w = xParent->left();
+ }
+ // Case 4
+ w->setColor(xParent->color());
+ xParent->setColor(Black);
+ if (w->left())
+ w->left()->setColor(Black);
+ rightRotate(xParent);
+ x = m_root;
+ xParent = x->parent();
+ }
+ }
+ }
+ if (x)
+ x->setColor(Black);
+ }
+
+ // Deletes the given node from the tree. Note that this
+ // particular node may not actually be removed from the tree;
+ // instead, another node might be removed and its contents
+ // copied into z.
+ void deleteNode(Node* z)
+ {
+ // Y is the node to be unlinked from the tree.
+ Node* y;
+ if (!z->left() || !z->right())
+ y = z;
+ else
+ y = treeSuccessor(z);
+
+ // Y is guaranteed to be non-null at this point.
+ Node* x;
+ if (y->left())
+ x = y->left();
+ else
+ x = y->right();
+
+ // X is the child of y which might potentially replace y in
+ // the tree. X might be null at this point.
+ Node* xParent;
+ if (x) {
+ x->setParent(y->parent());
+ xParent = x->parent();
+ } else
+ xParent = y->parent();
+ if (!y->parent())
+ m_root = x;
+ else {
+ if (y == y->parent()->left())
+ y->parent()->setLeft(x);
+ else
+ y->parent()->setRight(x);
+ }
+ if (y != z) {
+ z->copyFrom(y);
+ // This node has changed location in the tree and must be updated.
+ updateNode(z);
+ // The parent and its parents may now be out of date.
+ propagateUpdates(z->parent());
+ }
+
+ // If we haven't already updated starting from xParent, do so now.
+ if (xParent && xParent != y && xParent != z)
+ propagateUpdates(xParent);
+ if (y->color() == Black)
+ deleteFixup(x, xParent);
+ }
+
+ // Visits the subtree rooted at the given node in order.
+ void visitInorderImpl(Node* node, Visitor* visitor) const
+ {
+ if (node->left())
+ visitInorderImpl(node->left(), visitor);
+ visitor->visit(node->data());
+ if (node->right())
+ visitInorderImpl(node->right(), visitor);
+ }
+
+ //----------------------------------------------------------------------
+ // Helper class for size()
+
+ // A Visitor which simply counts the number of visited elements.
+ class Counter : public Visitor, public Noncopyable {
+ public:
+ Counter()
+ : m_count(0) { }
+
+ virtual void visit(const T& data) { ++m_count; }
+ int count() const { return m_count; }
+
+ private:
+ int m_count;
+ };
+
+ //----------------------------------------------------------------------
+ // Verification and debugging routines
+ //
+
+ // Returns in the "blackCount" parameter the number of black
+ // children along all paths to all leaves of the given node.
+ bool checkInvariantsFromNode(Node* node, int* blackCount) const
+ {
+ // Base case is a leaf node.
+ if (!node) {
+ *blackCount = 1;
+ return true;
+ }
+
+ // Each node is either red or black.
+ if (!(node->color() == Red || node->color() == Black))
+ return false;
+
+ // Every leaf (or null) is black.
+
+ if (node->color() == Red) {
+ // Both of its children are black.
+ if (!((!node->left() || node->left()->color() == Black)))
+ return false;
+ if (!((!node->right() || node->right()->color() == Black)))
+ return false;
+ }
+
+ // Every simple path to a leaf node contains the same number of
+ // black nodes.
+ int leftCount = 0, rightCount = 0;
+ bool leftValid = checkInvariantsFromNode(node->left(), &leftCount);
+ bool rightValid = checkInvariantsFromNode(node->right(), &rightCount);
+ if (!leftValid || !rightValid)
+ return false;
+ *blackCount = leftCount + (node->color() == Black ? 1 : 0);
+ return leftCount == rightCount;
+ }
+
+#ifdef NDEBUG
+ void logIfVerbose(const char* output) const { }
+#else
+ void logIfVerbose(const char* output) const
+ {
+ if (m_verboseDebugging)
+ LOG_ERROR("%s", output);
+ }
+#endif
+
+#ifndef NDEBUG
+ // Dumps the subtree rooted at the given node.
+ void dumpFromNode(Node* node, int indentation) const
+ {
+ StringBuilder builder;
+ for (int i = 0; i < indentation; i++)
+ builder.append(" ");
+ builder.append("-");
+ if (node) {
+ builder.append(" ");
+ builder.append(valueToString(node->data()));
+ builder.append((node->color() == Black) ? " (black)" : " (red)");
+ }
+ LOG_ERROR("%s", builder.toString().ascii().data());
+ if (node) {
+ dumpFromNode(node->left(), indentation + 2);
+ dumpFromNode(node->right(), indentation + 2);
+ }
+ }
+#endif
+
+ //----------------------------------------------------------------------
+ // Data members
+
+ RefPtr<PODArena> m_arena;
+ Node* m_root;
+ bool m_needsFullOrderingComparisons;
+#ifndef NDEBUG
+ bool m_verboseDebugging;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // PODRedBlackTree_h
diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
new file mode 100644
index 0000000..6424293
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "SharedGraphicsContext3D.h"
+
+#include "AffineTransform.h"
+#include "Color.h"
+#include "FloatRect.h"
+#include "GraphicsContext3D.h"
+#include "GraphicsTypes.h"
+#include "IntSize.h"
+#include "SolidFillShader.h"
+#include "TexShader.h"
+
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// static
+PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(PassOwnPtr<GraphicsContext3D> context)
+{
+ return adoptRef(new SharedGraphicsContext3D(context));
+}
+
+SharedGraphicsContext3D::SharedGraphicsContext3D(PassOwnPtr<GraphicsContext3D> context)
+ : m_context(context)
+ , m_quadVertices(0)
+ , m_solidFillShader(SolidFillShader::create(m_context.get()))
+ , m_texShader(TexShader::create(m_context.get()))
+{
+}
+
+SharedGraphicsContext3D::~SharedGraphicsContext3D()
+{
+ m_context->deleteBuffer(m_quadVertices);
+}
+
+void SharedGraphicsContext3D::makeContextCurrent()
+{
+ m_context->makeContextCurrent();
+}
+
+void SharedGraphicsContext3D::scissor(const FloatRect& rect)
+{
+ m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void SharedGraphicsContext3D::enable(unsigned capacity)
+{
+ m_context->enable(capacity);
+}
+
+void SharedGraphicsContext3D::disable(unsigned capacity)
+{
+ m_context->disable(capacity);
+}
+
+void SharedGraphicsContext3D::clearColor(const Color& color)
+{
+ float rgba[4];
+ color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+ m_context->clearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
+}
+
+void SharedGraphicsContext3D::clear(unsigned mask)
+{
+ m_context->clear(mask);
+}
+
+void SharedGraphicsContext3D::drawArrays(unsigned long mode, long first, long count)
+{
+ m_context->drawArrays(mode, first, count);
+}
+
+unsigned long SharedGraphicsContext3D::getError()
+{
+ return m_context->getError();
+}
+
+void SharedGraphicsContext3D::getIntegerv(unsigned long pname, int* value)
+{
+ m_context->getIntegerv(pname, value);
+}
+
+unsigned SharedGraphicsContext3D::createFramebuffer()
+{
+ return m_context->createFramebuffer();
+}
+
+unsigned SharedGraphicsContext3D::createTexture()
+{
+ return m_context->createTexture();
+}
+
+void SharedGraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
+{
+ m_context->deleteFramebuffer(framebuffer);
+}
+
+void SharedGraphicsContext3D::deleteTexture(unsigned texture)
+{
+ m_context->deleteTexture(texture);
+}
+
+void SharedGraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, unsigned texture, long level)
+{
+ m_context->framebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void SharedGraphicsContext3D::texParameteri(unsigned target, unsigned pname, int param)
+{
+ m_context->texParameteri(target, pname, param);
+}
+
+int SharedGraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
+{
+ return m_context->texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+int SharedGraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels)
+{
+ return m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void SharedGraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data)
+{
+ m_context->readPixels(x, y, width, height, format, type, data);
+}
+
+bool SharedGraphicsContext3D::supportsBGRA()
+{
+ return m_context->supportsBGRA();
+}
+
+Texture* SharedGraphicsContext3D::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height)
+{
+ RefPtr<Texture> texture = m_textures.get(ptr);
+ if (texture)
+ return texture.get();
+
+ texture = Texture::create(m_context.get(), format, width, height);
+ Texture* t = texture.get();
+ m_textures.set(ptr, texture);
+ return t;
+}
+
+Texture* SharedGraphicsContext3D::getTexture(NativeImagePtr ptr)
+{
+ RefPtr<Texture> texture = m_textures.get(ptr);
+ return texture ? texture.get() : 0;
+}
+
+PassRefPtr<Texture> SharedGraphicsContext3D::createTexture(Texture::Format format, int width, int height)
+{
+ return Texture::create(m_context.get(), format, width, height);
+}
+
+void SharedGraphicsContext3D::applyCompositeOperator(CompositeOperator op)
+{
+ switch (op) {
+ case CompositeClear:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ZERO);
+ break;
+ case CompositeCopy:
+ m_context->disable(GraphicsContext3D::BLEND);
+ break;
+ case CompositeSourceOver:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositeSourceIn:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ZERO);
+ break;
+ case CompositeSourceOut:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ZERO);
+ break;
+ case CompositeSourceAtop:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositeDestinationOver:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE);
+ break;
+ case CompositeDestinationIn:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::SRC_ALPHA);
+ break;
+ case CompositeDestinationOut:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositeDestinationAtop:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::SRC_ALPHA);
+ break;
+ case CompositeXOR:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE_MINUS_DST_ALPHA, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+ break;
+ case CompositePlusDarker:
+ case CompositeHighlight:
+ // unsupported
+ m_context->disable(GraphicsContext3D::BLEND);
+ break;
+ case CompositePlusLighter:
+ m_context->enable(GraphicsContext3D::BLEND);
+ m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE);
+ break;
+ }
+}
+
+void SharedGraphicsContext3D::useQuadVertices()
+{
+ if (!m_quadVertices) {
+ float vertices[] = { 0.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f };
+ m_quadVertices = m_context->createBuffer();
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
+ } else {
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
+ }
+}
+
+void SharedGraphicsContext3D::setActiveTexture(unsigned textureUnit)
+{
+ m_context->activeTexture(textureUnit);
+}
+
+void SharedGraphicsContext3D::bindTexture(unsigned target, unsigned texture)
+{
+ m_context->bindTexture(target, texture);
+}
+
+void SharedGraphicsContext3D::useFillSolidProgram(const AffineTransform& transform, const Color& color)
+{
+ m_solidFillShader->use(transform, color);
+}
+
+void SharedGraphicsContext3D::useTextureProgram(const AffineTransform& transform, const AffineTransform& texTransform, float alpha)
+{
+ m_texShader->use(transform, texTransform, 0, alpha);
+}
+
+void SharedGraphicsContext3D::bindFramebuffer(unsigned framebuffer)
+{
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
+}
+
+void SharedGraphicsContext3D::setViewport(const IntSize& size)
+{
+ m_context->viewport(0, 0, size.width(), size.height());
+}
+
+bool SharedGraphicsContext3D::paintsIntoCanvasBuffer() const
+{
+ return m_context->paintsIntoCanvasBuffer();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
new file mode 100644
index 0000000..1baa0f6
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SharedGraphicsContext3D_h
+#define SharedGraphicsContext3D_h
+
+#include "GraphicsTypes.h"
+#include "ImageSource.h"
+#include "Texture.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class AffineTransform;
+class Color;
+class GraphicsContext3D;
+class FloatRect;
+class IntSize;
+class SolidFillShader;
+class TexShader;
+
+typedef HashMap<NativeImagePtr, RefPtr<Texture> > TextureHashMap;
+
+class SharedGraphicsContext3D : public RefCounted<SharedGraphicsContext3D> {
+public:
+ static PassRefPtr<SharedGraphicsContext3D> create(PassOwnPtr<GraphicsContext3D>);
+ ~SharedGraphicsContext3D();
+
+ // Functions that delegate directly to GraphicsContext3D, with caching
+ void makeContextCurrent();
+ void bindFramebuffer(unsigned framebuffer);
+ void setViewport(const IntSize&);
+ void scissor(const FloatRect&);
+ void enable(unsigned capacity);
+ void disable(unsigned capacity);
+ void clearColor(const Color&);
+ void clear(unsigned mask);
+ void drawArrays(unsigned long mode, long first, long count);
+ unsigned long getError();
+ void getIntegerv(unsigned long pname, int* value);
+
+ unsigned createFramebuffer();
+ unsigned createTexture();
+
+ void deleteFramebuffer(unsigned framebuffer);
+ void deleteTexture(unsigned texture);
+
+ void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, unsigned, long level);
+ void texParameteri(unsigned target, unsigned pname, int param);
+ int texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels);
+
+ void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data);
+
+ bool paintsIntoCanvasBuffer() const;
+
+ // Shared logic for canvas 2d
+ void applyCompositeOperator(CompositeOperator);
+ void useQuadVertices();
+
+ void useFillSolidProgram(const AffineTransform&, const Color&);
+ void useTextureProgram(const AffineTransform&, const AffineTransform&, float alpha);
+
+ void setActiveTexture(unsigned textureUnit);
+ void bindTexture(unsigned target, unsigned texture);
+
+ bool supportsBGRA();
+
+ // Creates a texture associated with the given image. Is owned by this context's
+ // TextureHashMap.
+ Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height);
+ Texture* getTexture(NativeImagePtr);
+
+ // Creates a texture that is not associated with any image. The caller takes ownership of
+ // the texture.
+ PassRefPtr<Texture> createTexture(Texture::Format, int width, int height);
+
+private:
+ SharedGraphicsContext3D(PassOwnPtr<GraphicsContext3D> context);
+
+ OwnPtr<GraphicsContext3D> m_context;
+
+ unsigned m_quadVertices;
+
+ OwnPtr<SolidFillShader> m_solidFillShader;
+ OwnPtr<TexShader> m_texShader;
+
+ TextureHashMap m_textures;
+};
+
+} // namespace WebCore
+
+#endif // SharedGraphicsContext3D_h
diff --git a/WebCore/platform/graphics/gpu/Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp
index 557603c..95436ba 100644
--- a/WebCore/platform/graphics/gpu/Texture.cpp
+++ b/WebCore/platform/graphics/gpu/Texture.cpp
@@ -32,10 +32,15 @@
#include "Texture.h"
+#include "FloatRect.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
+
+#include <algorithm>
#include <wtf/OwnArrayPtr.h>
+using namespace std;
+
namespace WebCore {
@@ -81,7 +86,6 @@ PassRefPtr<Texture> Texture::create(GraphicsContext3D* context, Format format, i
{
int maxTextureSize = 0;
context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
-
TilingData tiling(maxTextureSize, width, height, true);
int numTiles = tiling.numTiles();
@@ -120,15 +124,18 @@ static uint32_t* copySubRect(uint32_t* src, int srcX, int srcY, uint32_t* dst, i
if (!swizzle && width == srcStride)
return srcOffset;
- uint32_t* dstPixel = dst;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width ; x++) {
- uint32_t pixel = srcOffset[x + y * srcStride];
- if (swizzle)
+ if (swizzle) {
+ uint32_t* dstPixel = dst;
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width ; ++x) {
+ uint32_t pixel = srcOffset[x + y * srcStride];
*dstPixel = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
- else
- *dstPixel = pixel;
- dstPixel++;
+ dstPixel++;
+ }
+ }
+ } else {
+ for (int y = 0; y < height; ++y) {
+ memcpy(dst + y * width, srcOffset + y * srcStride, 4 * width);
}
}
return dst;
@@ -136,6 +143,11 @@ static uint32_t* copySubRect(uint32_t* src, int srcX, int srcY, uint32_t* dst, i
void Texture::load(void* pixels)
{
+ updateSubRect(pixels, IntRect(0, 0, m_tiles.totalSizeX(), m_tiles.totalSizeY()));
+}
+
+void Texture::updateSubRect(void* pixels, const IntRect updateRect)
+{
uint32_t* pixels32 = static_cast<uint32_t*>(pixels);
unsigned int glFormat = 0;
unsigned int glType = 0;
@@ -145,26 +157,42 @@ void Texture::load(void* pixels)
ASSERT(glFormat == GraphicsContext3D::RGBA && glType == GraphicsContext3D::UNSIGNED_BYTE);
// FIXME: This could use PBO's to save doing an extra copy here.
}
- OwnArrayPtr<uint32_t> tempBuff(new uint32_t[m_tiles.maxTextureSize() * m_tiles.maxTextureSize()]);
+ int tempBuffSize = // Temporary buffer size is the smaller of the max texture size or the updateRect
+ min(m_tiles.maxTextureSize(), m_tiles.borderTexels() + updateRect.width()) *
+ min(m_tiles.maxTextureSize(), m_tiles.borderTexels() + updateRect.height());
+ OwnArrayPtr<uint32_t> tempBuff(new uint32_t[tempBuffSize]);
+
+ for (int tile = 0; tile < m_tiles.numTiles(); tile++) {
+ // Intersect with tile
+ IntRect tileBoundsWithBorder = m_tiles.tileBoundsWithBorder(tile);
- for (int i = 0; i < m_tiles.numTiles(); i++) {
- IntRect tileBoundsWithBorder = m_tiles.tileBoundsWithBorder(i);
+ IntRect updateRectIntersected = updateRect;
+ updateRectIntersected.intersect(tileBoundsWithBorder);
+ IntRect dstRect = updateRectIntersected;
+ dstRect.move(-tileBoundsWithBorder.x(), -tileBoundsWithBorder.y());
+
+ if (updateRectIntersected.isEmpty())
+ continue;
+
+ // Copy sub rectangle out of larger pixel data
uint32_t* uploadBuff = 0;
if (swizzle) {
uploadBuff = copySubRect<true>(
- pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(),
- tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX());
+ pixels32, updateRectIntersected.x(), updateRectIntersected.y(),
+ tempBuff.get(), updateRectIntersected.width(), updateRectIntersected.height(), m_tiles.totalSizeX());
} else {
uploadBuff = copySubRect<false>(
- pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(),
- tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX());
+ pixels32, updateRectIntersected.x(), updateRectIntersected.y(),
+ tempBuff.get(), updateRectIntersected.width(), updateRectIntersected.height(), m_tiles.totalSizeX());
}
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(i));
- m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0,
- tileBoundsWithBorder.width(),
- tileBoundsWithBorder.height(), glFormat, glType, uploadBuff);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(tile));
+ m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0 /* level */,
+ dstRect.x(),
+ dstRect.y(),
+ updateRectIntersected.width(),
+ updateRectIntersected.height(), glFormat, glType, uploadBuff);
}
}
diff --git a/WebCore/platform/graphics/gpu/Texture.h b/WebCore/platform/graphics/gpu/Texture.h
index 7e4a72b..eda475e 100644
--- a/WebCore/platform/graphics/gpu/Texture.h
+++ b/WebCore/platform/graphics/gpu/Texture.h
@@ -41,6 +41,8 @@
namespace WebCore {
class GraphicsContext3D;
+class IntRect;
+
class Texture : public RefCounted<Texture> {
public:
~Texture();
@@ -48,6 +50,7 @@ public:
static PassRefPtr<Texture> create(GraphicsContext3D*, Format, int width, int height);
void bindTile(int tile);
void load(void* pixels);
+ void updateSubRect(void* pixels, const IntRect);
Format format() const { return m_format; }
const TilingData& tiles() const { return m_tiles; }
private:
diff --git a/WebCore/platform/graphics/gpu/TilingData.h b/WebCore/platform/graphics/gpu/TilingData.h
index f12e66e..1bdc51a 100644
--- a/WebCore/platform/graphics/gpu/TilingData.h
+++ b/WebCore/platform/graphics/gpu/TilingData.h
@@ -44,6 +44,7 @@ public:
int maxTextureSize() const { return m_maxTextureSize; }
int totalSizeX() const { return m_totalSizeX; }
int totalSizeY() const { return m_totalSizeY; }
+ int borderTexels() const { return m_borderTexels; }
int numTiles() const { return numTilesX() * numTilesY(); }
int numTilesX() const { return m_numTilesX; }
diff --git a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp
index 567da74..63555bf 100644
--- a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp
@@ -18,6 +18,7 @@
#include "config.h"
#include "DataSourceGStreamer.h"
+#if ENABLE(VIDEO)
#include <gio/gio.h>
#include <glib.h>
@@ -241,3 +242,5 @@ static void webkit_data_src_uri_handler_init(gpointer g_iface, gpointer iface_da
iface->get_uri = webkit_data_src_uri_get_uri;
iface->set_uri = webkit_data_src_uri_set_uri;
}
+
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h
index 38f69b1..453685a 100644
--- a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h
@@ -19,6 +19,8 @@
#ifndef DataSourceGStreamer_h
#define DataSourceGStreamer_h
+#if ENABLE(VIDEO)
+
#include <glib-object.h>
#include <gst/base/gstbasesrc.h>
@@ -51,4 +53,5 @@ GType webkit_data_src_get_type(void);
G_END_DECLS
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
index 75bf5e7..6333437 100644
--- a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
@@ -32,4 +32,4 @@ template <> void freeOwnedGPtr<GstElement>(GstElement* ptr)
}
}
-#endif
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h
index 6655f38..84a3e30 100644
--- a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h
@@ -19,6 +19,7 @@
#ifndef GOwnPtrGStreamer_h
#define GOwnPtrGStreamer_h
+#if ENABLE(VIDEO)
#include "GOwnPtr.h"
@@ -30,4 +31,5 @@ template<> void freeOwnedGPtr<GstElement>(GstElement* ptr);
}
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
index e1efdd4..2ff4f38 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
@@ -18,11 +18,10 @@
*/
#include "config.h"
-
#include "GStreamerGWorld.h"
+#if ENABLE(VIDEO)
#include "GOwnPtrGStreamer.h"
-
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
@@ -200,3 +199,4 @@ void GStreamerGWorld::setWindowOverlay(GstMessage* message)
}
}
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
index 659052a..282f13c 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
@@ -20,7 +20,6 @@
#ifndef GStreamerGWorld_h
#define GStreamerGWorld_h
-
#if ENABLE(VIDEO)
#include "PlatformVideoWindow.h"
@@ -63,5 +62,5 @@ private:
};
}
-#endif
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
index 9288df9..4a4ff2b 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
@@ -23,7 +23,6 @@
#if ENABLE(VIDEO)
#include "BitmapImage.h"
-
#include <gst/gst.h>
#include <gst/video/video.h>
#include <wtf/PassRefPtr.h>
@@ -60,6 +59,5 @@ class ImageGStreamer : public RefCounted<ImageGStreamer> {
};
}
-#endif
-
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm b/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm
index 421b90f..076df4a 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm
@@ -19,6 +19,7 @@
#include "config.h"
#include "ImageGStreamer.h"
+#if ENABLE(VIDEO)
using namespace WebCore;
@@ -55,3 +56,5 @@ ImageGStreamer::~ImageGStreamer()
m_image = 0;
}
+
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp b/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
index aeaee19..2fed892 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
@@ -18,12 +18,13 @@
*/
#include "config.h"
+#include "ImageGStreamer.h"
+
+#if ENABLE(VIDEO)
#include "GOwnPtr.h"
-#include "ImageGStreamer.h"
using namespace std;
-
using namespace WebCore;
PassRefPtr<ImageGStreamer> ImageGStreamer::createImage(GstBuffer* buffer)
@@ -64,3 +65,4 @@ ImageGStreamer::~ImageGStreamer()
m_image = 0;
}
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 5628eb3..4791b4c 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -22,11 +22,8 @@
*/
#include "config.h"
-
-#if ENABLE(VIDEO)
-
#include "MediaPlayerPrivateGStreamer.h"
-
+#if ENABLE(VIDEO)
#include "ColorSpace.h"
#include "DataSourceGStreamer.h"
@@ -49,14 +46,13 @@
#include "VideoSinkGStreamer.h"
#include "WebKitWebSourceGStreamer.h"
#include "Widget.h"
-#include <wtf/text/CString.h>
-
#include <GOwnPtr.h>
#include <gst/gst.h>
#include <gst/interfaces/mixer.h>
#include <gst/video/video.h>
#include <limits>
#include <math.h>
+#include <wtf/text/CString.h>
// GstPlayFlags flags from playbin2. It is the policy of GStreamer to
// not publicly expose element-specific enums. That's why this
@@ -843,8 +839,12 @@ void MediaPlayerPrivateGStreamer::updateStates()
// Try to figure out ready and network states.
if (state == GST_STATE_READY) {
- m_readyState = MediaPlayer::HaveNothing;
+ m_readyState = MediaPlayer::HaveMetadata;
m_networkState = MediaPlayer::Empty;
+ // Cache the duration without emiting the durationchange
+ // event because it's taken care of by the media element
+ // in this precise case.
+ cacheDuration();
} else if (maxTimeLoaded() == duration()) {
m_networkState = MediaPlayer::Loaded;
m_readyState = MediaPlayer::HaveEnoughData;
@@ -880,13 +880,6 @@ void MediaPlayerPrivateGStreamer::updateStates()
m_readyState = MediaPlayer::HaveEnoughData;
m_paused = false;
- if (!m_mediaDuration) {
- float newDuration = duration();
- m_mediaDurationKnown = !isinf(newDuration);
- if (m_mediaDurationKnown)
- m_mediaDuration = newDuration;
- }
-
if (m_buffering) {
m_readyState = MediaPlayer::HaveCurrentData;
m_networkState = MediaPlayer::Loading;
@@ -1119,7 +1112,7 @@ void MediaPlayerPrivateGStreamer::didEnd()
timeChanged();
}
-void MediaPlayerPrivateGStreamer::durationChanged()
+void MediaPlayerPrivateGStreamer::cacheDuration()
{
// Reset cached media duration
m_mediaDuration = 0;
@@ -1143,8 +1136,16 @@ void MediaPlayerPrivateGStreamer::durationChanged()
if (!isinf(newDuration))
m_mediaDuration = newDuration;
+}
- m_player->durationChanged();
+void MediaPlayerPrivateGStreamer::durationChanged()
+{
+ float previousDuration = m_mediaDuration;
+
+ cacheDuration();
+
+ if (m_mediaDuration != previousDuration)
+ m_player->durationChanged();
}
bool MediaPlayerPrivateGStreamer::supportsMuting() const
@@ -1266,6 +1267,7 @@ static HashSet<String> mimeTypeCache()
if (g_str_equal(name, "audio/x-vorbis")) {
cache.add(String("audio/ogg"));
+ cache.add(String("audio/x-vorbis+ogg"));
cached = true;
}
@@ -1460,4 +1462,4 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
}
-#endif
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
index f2f684b..6d1392d 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
@@ -22,7 +22,6 @@
#ifndef MediaPlayerPrivateGStreamer_h
#define MediaPlayerPrivateGStreamer_h
-
#if ENABLE(VIDEO)
#include <wtf/Forward.h>
@@ -132,6 +131,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
static bool isAvailable();
+ void cacheDuration();
void updateStates();
void cancelSeek();
void endPointTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
@@ -179,5 +179,5 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
};
}
-#endif
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
index 8d99f05..3c4904b 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
@@ -19,7 +19,6 @@
#ifndef PlatformVideoWindow_h
#define PlatformVideoWindow_h
-
#if ENABLE(VIDEO)
#include "Widget.h"
@@ -45,6 +44,5 @@ class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> {
};
}
-#endif
-
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
index 5c0e6ea..68ab7ac 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
@@ -19,6 +19,7 @@
#include "config.h"
#include "PlatformVideoWindow.h"
+#if ENABLE(VIDEO)
#include "NotImplemented.h"
@@ -33,3 +34,5 @@ PlatformVideoWindow::~PlatformVideoWindow()
{
notImplemented();
}
+
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
index c5f835c..88b6552 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
@@ -19,8 +19,10 @@
#include "config.h"
#include "PlatformVideoWindow.h"
+#if ENABLE(VIDEO)
#include <gtk/gtk.h>
+
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h> // for GDK_WINDOW_XID
#endif
@@ -59,3 +61,4 @@ PlatformVideoWindow::~PlatformVideoWindow()
m_videoWindowId = 0;
}
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
index dd8c3ee..00fef4b 100644
--- a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
@@ -28,6 +28,7 @@
#include "config.h"
#include "VideoSinkGStreamer.h"
+#if ENABLE(VIDEO)
#include <glib.h>
#include <gst/gst.h>
@@ -370,3 +371,4 @@ webkit_video_sink_new(void)
return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0);
}
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
index 4fb0b73..767e83f 100644
--- a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
@@ -20,6 +20,8 @@
#ifndef VideoSinkGStreamer_h
#define VideoSinkGStreamer_h
+#if ENABLE(VIDEO)
+
#include <glib-object.h>
#include <gst/video/gstvideosink.h>
@@ -75,4 +77,5 @@ GstElement *webkit_video_sink_new(void);
G_END_DECLS
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
index 1059b59..bcd59c6 100644
--- a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
@@ -18,6 +18,7 @@
#include "config.h"
#include "WebKitWebSourceGStreamer.h"
+#if ENABLE(VIDEO)
#include "Document.h"
#include "GOwnPtr.h"
@@ -790,3 +791,5 @@ void StreamingClient::cannotShowURL(ResourceHandle*)
GST_ELEMENT_ERROR(m_src, RESOURCE, OPEN_READ, ("Can't show \"%s\"", m_src->priv->uri), (0));
}
+#endif // ENABLE(VIDEO)
+
diff --git a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
index ae19640..1594062 100644
--- a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
@@ -18,6 +18,7 @@
#ifndef WebKitWebSourceGStreamer_h
#define WebKitWebSourceGStreamer_h
+#if ENABLE(VIDEO)
#include "Frame.h"
#include <gst/gst.h>
@@ -49,4 +50,5 @@ void webKitWebSrcSetFrame(WebKitWebSrc* src, WebCore::Frame* frame);
G_END_DECLS
+#endif // ENABLE(VIDEO)
#endif
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index ab4ef4b..54b261c 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -31,7 +31,6 @@
#import "BlockExceptions.h"
-#include "ANGLE/ResourceLimits.h"
#include "ArrayBuffer.h"
#include "ArrayBufferView.h"
#include "WebGLObject.h"
@@ -186,23 +185,23 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
TBuiltInResource ANGLEResources;
- ANGLEResources.maxVertexAttribs = 0;
- getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.maxVertexAttribs);
- ANGLEResources.maxVertexUniformVectors = 0;
- getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.maxVertexUniformVectors);
- ANGLEResources.maxVaryingVectors = 0;
- getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.maxVaryingVectors);
- ANGLEResources.maxVertexTextureImageUnits = 0;
- getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxVertexTextureImageUnits);
- ANGLEResources.maxCombinedTextureImageUnits = 0;
- getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxCombinedTextureImageUnits);
- ANGLEResources.maxTextureImageUnits = 0;
- getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxTextureImageUnits);
- ANGLEResources.maxFragmentUniformVectors = 0;
- getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.maxFragmentUniformVectors);
+ ANGLEResources.MaxVertexAttribs = 0;
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs);
+ ANGLEResources.MaxVertexUniformVectors = 0;
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors);
+ ANGLEResources.MaxVaryingVectors = 0;
+ getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors);
+ ANGLEResources.MaxVertexTextureImageUnits = 0;
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits);
+ ANGLEResources.MaxCombinedTextureImageUnits = 0;
+ getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits);
+ ANGLEResources.MaxTextureImageUnits = 0;
+ getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits);
+ ANGLEResources.MaxFragmentUniformVectors = 0;
+ getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors);
// Always set to 1 for OpenGL ES.
- ANGLEResources.maxDrawBuffers = 1;
+ ANGLEResources.MaxDrawBuffers = 1;
m_compiler.setResources(ANGLEResources);
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index 315cc00..5fedaff 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -272,16 +272,16 @@ static TransformationMatrix flipTransform()
}
#endif
-static CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction& timingFunction)
-{
- switch (timingFunction.type()) {
- case LinearTimingFunction:
- return [CAMediaTimingFunction functionWithName:@"linear"];
- case CubicBezierTimingFunction:
- return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(timingFunction.x1()) :static_cast<float>(timingFunction.y1())
- :static_cast<float>(timingFunction.x2()) :static_cast<float>(timingFunction.y2())];
- }
- return 0;
+static CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction* timingFunction)
+{
+ // By this point, timing functions can only be linear or cubic, not steps.
+ ASSERT(!timingFunction->isStepsTimingFunction());
+ if (timingFunction->isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
+ return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(ctf->x1()) :static_cast<float>(ctf->y1())
+ :static_cast<float>(ctf->x2()) :static_cast<float>(ctf->y2())];
+ } else
+ return [CAMediaTimingFunction functionWithName:@"linear"];
}
static void setLayerBorderColor(PlatformLayer* layer, const Color& color)
@@ -356,6 +356,20 @@ static NSDictionary* nullActionsDictionary()
return actions;
}
+static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
+{
+ if (anim->timingFunction()->isStepsTimingFunction())
+ return true;
+
+ for (unsigned i = 0; i < valueList.size(); ++i) {
+ const TimingFunction* timingFunction = valueList.at(i)->timingFunction();
+ if (timingFunction && timingFunction->isStepsTimingFunction())
+ return true;
+ }
+
+ return false;
+}
+
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return new GraphicsLayerCA(client);
@@ -716,6 +730,11 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
return false;
#endif
+ // CoreAnimation does not handle the steps() timing function. Fall back
+ // to software animation in that case.
+ if (animationHasStepsTimingFunction(valueList, anim))
+ return false;
+
bool createdAnimations = false;
if (valueList.property() == AnimatedPropertyWebkitTransform)
createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, timeOffset, boxSize);
@@ -1913,9 +1932,9 @@ CAMediaTimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const An
if (animValue->timingFunction())
tf = animValue->timingFunction();
else if (anim->isTimingFunctionSet())
- tf = &anim->timingFunction();
+ tf = anim->timingFunction().get();
- return getCAMediaTimingFunction(tf ? *tf : TimingFunction());
+ return getCAMediaTimingFunction(tf ? tf : CubicBezierTimingFunction::create().get());
}
bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, CABasicAnimation* basicAnim)
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index 89badcc..e164f8c 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -1213,7 +1213,7 @@ PlatformLayer* GraphicsLayerQt::platformLayer() const
template <typename T>
struct KeyframeValueQt {
- TimingFunction timingFunction;
+ const TimingFunction* timingFunction;
T value;
};
@@ -1230,23 +1230,32 @@ static inline double solveCubicBezierFunction(qreal p1x, qreal p1y, qreal p2x, q
return bezier.solve(t, solveEpsilon(duration));
}
-static inline qreal applyTimingFunction(const TimingFunction& timingFunction, qreal progress, double duration)
+static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t)
+{
+ if (stepAtStart)
+ return qMin(1.0, (floor(numSteps * t) + 1) / numSteps);
+ return floor(numSteps * t) / numSteps;
+}
+
+static inline qreal applyTimingFunction(const TimingFunction* timingFunction, qreal progress, double duration)
{
// We want the timing function to be as close as possible to what the web-developer intended, so
// we're using the same function used by WebCore when compositing is disabled. Using easing-curves
// would probably work for some of the cases, but wouldn't really buy us anything as we'd have to
// convert the bezier function back to an easing curve.
- if (timingFunction.type() == LinearTimingFunction)
- return progress;
- if (timingFunction.type() == CubicBezierTimingFunction) {
- return solveCubicBezierFunction(timingFunction.x1(),
- timingFunction.y1(),
- timingFunction.x2(),
- timingFunction.y2(),
+ if (timingFunction->isCubicBezierTimingFunction()) {
+ const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
+ return solveCubicBezierFunction(ctf->x1(),
+ ctf->y1(),
+ ctf->x2(),
+ ctf->y2(),
double(progress), double(duration) / 1000);
- }
- return progress;
+ } else if (timingFunction->isStepsTimingFunction()) {
+ const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(timingFunction);
+ return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), double(progress));
+ } else
+ return progress;
}
// Helper functions to safely get a value out of WebCore's AnimationValue*.
@@ -1322,9 +1331,9 @@ public:
const AnimationValue* animationValue = values.at(i);
KeyframeValueQt<T> keyframeValue;
if (animationValue->timingFunction())
- keyframeValue.timingFunction = *animationValue->timingFunction();
+ keyframeValue.timingFunction = animationValue->timingFunction();
else
- keyframeValue.timingFunction = anim->timingFunction();
+ keyframeValue.timingFunction = anim->timingFunction().get();
webkitAnimationToQtAnimationValue(animationValue, keyframeValue.value);
m_keyframeValues[animationValue->keyTime()] = keyframeValue;
}
@@ -1381,7 +1390,7 @@ protected:
const KeyframeValueQt<T>& fromKeyframe = it.value();
const KeyframeValueQt<T>& toKeyframe = it2.value();
- const TimingFunction& timingFunc = fromKeyframe.timingFunction;
+ const TimingFunction* timingFunc = fromKeyframe.timingFunction;
const T& fromValue = fromKeyframe.value;
const T& toValue = toKeyframe.value;
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 4ad5571..605dcb7 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -604,6 +604,14 @@ PlatformLayer* MediaPlayerPrivate::platformLayer() const
}
#endif
+PlatformMedia MediaPlayerPrivate::platformMedia() const
+{
+ PlatformMedia pm;
+ pm.type = PlatformMedia::QtMediaPlayerType;
+ pm.media.qtMediaPlayer = const_cast<MediaPlayerPrivate*>(this);
+ return pm;
+}
+
} // namespace WebCore
#include "moc_MediaPlayerPrivateQt.cpp"
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
index 165efde..117187d 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
@@ -99,6 +99,7 @@ public:
virtual PlatformLayer* platformLayer() const;
#endif
+ virtual PlatformMedia platformMedia() const;
private slots:
void mediaStatusChanged(QMediaPlayer::MediaStatus);
void handleError(QMediaPlayer::Error);
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index ce5da2e..df54684 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -264,6 +264,11 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
void Path::closeSubpath()
{
+ m_path.closeSubpath();
+}
+
+void Path::closeCanvasSubpath()
+{
const int elementCount = m_path.elementCount();
if (!elementCount)
@@ -469,6 +474,31 @@ void Path::transform(const AffineTransform& transform)
m_path = qTransform.map(m_path);
}
+float Path::length()
+{
+ return m_path.length();
+}
+
+FloatPoint Path::pointAtLength(float length, bool& ok)
+{
+ ok = (length >= 0 && length <= m_path.length());
+
+ qreal percent = m_path.percentAtLength(length);
+ QPointF point = m_path.pointAtPercent(percent);
+
+ return point;
+}
+
+float Path::normalAngleAtLength(float length, bool& ok)
+{
+ ok = (length >= 0 && length <= m_path.length());
+
+ qreal percent = m_path.percentAtLength(length);
+ qreal angle = m_path.angleAtPercent(percent);
+
+ return angle;
+}
+
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
index b6d6e65..b6d6e65 100644
--- a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
diff --git a/WebCore/platform/graphics/chromium/FontCustomPlatformData.h b/WebCore/platform/graphics/skia/FontCustomPlatformData.h
index d451c9c..d451c9c 100644
--- a/WebCore/platform/graphics/chromium/FontCustomPlatformData.h
+++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.h
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 1c80d49..d618c19 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2006, 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
@@ -14,7 +14,7 @@
* * 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
@@ -65,7 +65,7 @@ namespace {
inline int fastMod(int value, int max)
{
int sign = SkExtractSign(value);
-
+
value = SkApplySign(value, sign);
if (value >= max)
value %= max;
@@ -391,7 +391,7 @@ void GraphicsContext::canvasClip(const Path& path)
if (!isPathSkiaSafe(getCTM(), p))
return;
- platformContext()->canvas()->clipPath(p);
+ platformContext()->canvasClipPath(p);
}
void GraphicsContext::clipOut(const IntRect& rect)
@@ -499,7 +499,7 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin
if (numPoints <= 1)
return;
-
+
// FIXME: IMPLEMENT!!
}
@@ -767,7 +767,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
}
- if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient && !platformContext()->getDrawLooper()) {
+ if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect);
return;
@@ -789,7 +789,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (paintingDisabled())
return;
- if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient) {
+ if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect, color, colorSpace);
return;
@@ -1240,14 +1240,19 @@ void GraphicsContext::translate(float w, float h)
WebCoreFloatToSkScalar(h));
}
-void GraphicsContext::setGraphicsContext3D(GraphicsContext3D* context3D, const IntSize& size)
+void GraphicsContext::syncSoftwareCanvas()
{
- platformContext()->setGraphicsContext3D(context3D, size);
+ platformContext()->syncSoftwareCanvas();
}
-void GraphicsContext::syncSoftwareCanvas()
+void GraphicsContext::setSharedGraphicsContext3D(SharedGraphicsContext3D* context, DrawingBuffer* framebuffer, const IntSize& size)
{
- platformContext()->syncSoftwareCanvas();
+ platformContext()->setSharedGraphicsContext3D(context, framebuffer, size);
+}
+
+void GraphicsContext::markDirtyRect(const IntRect& rect)
+{
+ platformContext()->markDirtyRect(rect);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 9403406..2be7dc5 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -36,10 +36,12 @@
#include "Base64.h"
#include "BitmapImage.h"
#include "BitmapImageSingleFrameSkia.h"
+#include "DrawingBuffer.h"
+#include "GLES2Canvas.h"
#include "GraphicsContext.h"
#include "ImageData.h"
-#include "PlatformContextSkia.h"
#include "PNGImageEncoder.h"
+#include "PlatformContextSkia.h"
#include "SkColorPriv.h"
#include "SkiaUtils.h"
@@ -67,9 +69,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
m_data.m_platformContext.setCanvas(&m_data.m_canvas);
m_context.set(new GraphicsContext(&m_data.m_platformContext));
-#if OS(WINDOWS)
m_context->platformContext()->setDrawingToImageBuffer(true);
-#endif
// Make the background transparent. It would be nice if this wasn't
// required, but the canvas is currently filled with the magic transparency
@@ -100,14 +100,26 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
{
-#if OS(LINUX) || OS(WINDOWS)
context->platformContext()->beginLayerClippedToImage(rect, this);
-#endif
}
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
CompositeOperator op, bool useLowQualityScale)
{
+ if (m_data.m_platformContext.useGPU() && context->platformContext()->useGPU()) {
+ if (context->platformContext()->canAccelerate()) {
+ DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer();
+ unsigned sourceTexture = sourceDrawingBuffer->getRenderingResultsAsTexture();
+ FloatRect destRectFlipped(destRect);
+ destRectFlipped.setY(destRect.y() + destRect.height());
+ destRectFlipped.setHeight(-destRect.height());
+ context->platformContext()->prepareForHardwareDraw();
+ context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRect, destRectFlipped, styleColorSpace, op);
+ return;
+ }
+ m_data.m_platformContext.syncSoftwareCanvas();
+ }
+
RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), context == m_context);
context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
}
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index aed289f..9625b34 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -47,6 +47,7 @@
#include "SkRect.h"
#include "SkShader.h"
#include "SkiaUtils.h"
+#include "Texture.h"
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
@@ -468,7 +469,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
- if (ctxt->platformContext()->useGPU()) {
+ if (ctxt->platformContext()->useGPU() && ctxt->platformContext()->canAccelerate()) {
drawBitmapGLES2(ctxt, bm, normSrcRect, normDstRect, colorSpace, compositeOp);
return;
}
@@ -496,7 +497,7 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
- if (ctxt->platformContext()->useGPU()) {
+ if (ctxt->platformContext()->useGPU() && ctxt->platformContext()->canAccelerate()) {
drawBitmapGLES2(ctxt, &m_nativeImage, srcRect, dstRect, styleColorSpace, compositeOp);
return;
}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 3b1d015..88fbcdd 100644..100755
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, 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
@@ -14,7 +14,7 @@
* * 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
@@ -33,12 +33,13 @@
#include "PlatformContextSkia.h"
#include "AffineTransform.h"
-#include "CanvasLayerChromium.h"
+#include "DrawingBuffer.h"
#include "GLES2Canvas.h"
#include "GraphicsContext.h"
#include "GraphicsContext3D.h"
#include "ImageBuffer.h"
#include "NativeImageSkia.h"
+#include "SharedGraphicsContext3D.h"
#include "SkiaUtils.h"
#include "Texture.h"
#include "TilingData.h"
@@ -96,18 +97,19 @@ struct PlatformContextSkia::State {
// color to produce a new output color.
SkColor applyAlpha(SkColor) const;
-#if OS(LINUX) || OS(WINDOWS)
// If non-empty, the current State is clipped to this image.
SkBitmap m_imageBufferClip;
// If m_imageBufferClip is non-empty, this is the region the image is clipped to.
FloatRect m_clip;
-#endif
// This is a list of clipping paths which are currently active, in the
// order in which they were pushed.
WTF::Vector<SkPath> m_antiAliasClipPaths;
InterpolationQuality m_interpolationQuality;
+ // If we currently have a canvas (non-antialiased path) clip applied.
+ bool m_canvasClipApplied;
+
PlatformContextSkia::State cloneInheritedProperties();
private:
// Not supported.
@@ -133,6 +135,7 @@ PlatformContextSkia::State::State()
, m_dash(0)
, m_textDrawingMode(cTextFill)
, m_interpolationQuality(InterpolationHigh)
+ , m_canvasClipApplied(false)
{
}
@@ -153,12 +156,11 @@ PlatformContextSkia::State::State(const State& other)
, m_lineJoin(other.m_lineJoin)
, m_dash(other.m_dash)
, m_textDrawingMode(other.m_textDrawingMode)
-#if OS(LINUX) || OS(WINDOWS)
, m_imageBufferClip(other.m_imageBufferClip)
, m_clip(other.m_clip)
-#endif
, m_antiAliasClipPaths(other.m_antiAliasClipPaths)
, m_interpolationQuality(other.m_interpolationQuality)
+ , m_canvasClipApplied(other.m_canvasClipApplied)
{
// Up the ref count of these. saveRef does nothing if 'this' is NULL.
m_looper->safeRef();
@@ -181,7 +183,7 @@ PlatformContextSkia::State PlatformContextSkia::State::cloneInheritedProperties(
PlatformContextSkia::State state(*this);
// Everything is inherited except for the clip paths.
- state.m_antiAliasClipPaths.clear();
+ state.m_antiAliasClipPaths.clear();
return state;
}
@@ -203,9 +205,7 @@ SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
// Danger: canvas can be NULL.
PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
: m_canvas(canvas)
-#if OS(WINDOWS)
, m_drawingToImageBuffer(false)
-#endif
, m_useGPU(false)
, m_gpuCanvas(0)
, m_backingStoreState(None)
@@ -216,12 +216,8 @@ PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
PlatformContextSkia::~PlatformContextSkia()
{
-#if USE(ACCELERATED_COMPOSITING)
- if (m_gpuCanvas) {
- CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(m_gpuCanvas->context()->platformLayer());
- layer->setPrepareTextureCallback(0);
- }
-#endif
+ if (m_gpuCanvas)
+ m_gpuCanvas->drawingBuffer()->setWillPublishCallback(0);
}
void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
@@ -229,7 +225,6 @@ void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
m_canvas = canvas;
}
-#if OS(WINDOWS)
void PlatformContextSkia::setDrawingToImageBuffer(bool value)
{
m_drawingToImageBuffer = value;
@@ -239,7 +234,6 @@ bool PlatformContextSkia::isDrawingToImageBuffer() const
{
return m_drawingToImageBuffer;
}
-#endif
void PlatformContextSkia::save()
{
@@ -248,17 +242,14 @@ void PlatformContextSkia::save()
m_stateStack.append(m_state->cloneInheritedProperties());
m_state = &m_stateStack.last();
-#if OS(LINUX) || OS(WINDOWS)
// The clip image only needs to be applied once. Reset the image so that we
// don't attempt to clip multiple times.
m_state->m_imageBufferClip.reset();
-#endif
// Save our native canvas.
canvas()->save();
}
-#if OS(LINUX) || OS(WINDOWS)
void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect,
const ImageBuffer* imageBuffer)
{
@@ -287,7 +278,6 @@ void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect,
m_state->m_imageBufferClip = *bitmap;
}
}
-#endif
void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
{
@@ -306,12 +296,10 @@ void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
void PlatformContextSkia::restore()
{
-#if OS(LINUX) || OS(WINDOWS)
if (!m_state->m_imageBufferClip.empty()) {
applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip);
canvas()->restore();
}
-#endif
if (!m_state->m_antiAliasClipPaths.isEmpty())
applyAntiAliasedClipPaths(m_state->m_antiAliasClipPaths);
@@ -337,7 +325,7 @@ void PlatformContextSkia::drawRect(SkRect rect)
// We do a fill of four rects to simulate the stroke of a border.
SkColor oldFillColor = m_state->m_fillColor;
- // setFillColor() will set the shader to NULL, so save a ref to it now.
+ // setFillColor() will set the shader to NULL, so save a ref to it now.
SkShader* oldFillShader = m_state->m_fillShader;
oldFillShader->safeRef();
setFillColor(m_state->m_strokeColor);
@@ -462,7 +450,7 @@ void PlatformContextSkia::setXfermodeMode(SkXfermode::Mode pdm)
void PlatformContextSkia::setFillColor(SkColor color)
{
m_state->m_fillColor = color;
- setFillShader(NULL);
+ setFillShader(0);
}
SkDrawLooper* PlatformContextSkia::getDrawLooper() const
@@ -483,7 +471,7 @@ void PlatformContextSkia::setStrokeStyle(StrokeStyle strokeStyle)
void PlatformContextSkia::setStrokeColor(SkColor strokeColor)
{
m_state->m_strokeColor = strokeColor;
- setStrokeShader(NULL);
+ setStrokeShader(0);
}
float PlatformContextSkia::getStrokeThickness() const
@@ -559,6 +547,12 @@ SkPath PlatformContextSkia::currentPathInLocalCoordinates() const
return localPath;
}
+void PlatformContextSkia::canvasClipPath(const SkPath& path)
+{
+ m_state->m_canvasClipApplied = true;
+ m_canvas->clipPath(path);
+}
+
void PlatformContextSkia::setFillRule(SkPath::FillType fr)
{
m_path.setFillType(fr);
@@ -630,7 +624,6 @@ bool PlatformContextSkia::hasImageResamplingHint() const
return !m_imageResamplingHintSrcSize.isEmpty() && !m_imageResamplingHintDstSize.isEmpty();
}
-#if OS(LINUX) || OS(WINDOWS)
void PlatformContextSkia::applyClipFromImage(const FloatRect& rect, const SkBitmap& imageBuffer)
{
// NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we
@@ -639,7 +632,6 @@ void PlatformContextSkia::applyClipFromImage(const FloatRect& rect, const SkBitm
paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint);
}
-#endif
void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
{
@@ -678,33 +670,47 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
m_canvas->restore();
}
-#if USE(ACCELERATED_COMPOSITING)
-class PrepareTextureCallbackImpl : public CanvasLayerChromium::PrepareTextureCallback {
+bool PlatformContextSkia::canAccelerate() const
+{
+ return !m_state->m_fillShader // Can't accelerate with a fill gradient or pattern.
+ && !m_state->m_looper // Can't accelerate with a shadow.
+ && !m_state->m_canvasClipApplied; // Can't accelerate with a clip to path applied.
+}
+
+class WillPublishCallbackImpl : public DrawingBuffer::WillPublishCallback {
public:
- static PassOwnPtr<PrepareTextureCallbackImpl> create(PlatformContextSkia* pcs)
+ static PassOwnPtr<WillPublishCallback> create(PlatformContextSkia* pcs)
{
- return new PrepareTextureCallbackImpl(pcs);
+ return adoptPtr(new WillPublishCallbackImpl(pcs));
}
- virtual void willPrepareTexture()
+ virtual void willPublish()
{
m_pcs->prepareForHardwareDraw();
}
+
private:
- explicit PrepareTextureCallbackImpl(PlatformContextSkia* pcs) : m_pcs(pcs) {}
+ explicit WillPublishCallbackImpl(PlatformContextSkia* pcs)
+ : m_pcs(pcs)
+ {
+ }
+
PlatformContextSkia* m_pcs;
};
-#endif
-void PlatformContextSkia::setGraphicsContext3D(GraphicsContext3D* context, const WebCore::IntSize& size)
+void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* context, DrawingBuffer* drawingBuffer, const WebCore::IntSize& size)
{
- m_useGPU = true;
- m_gpuCanvas = new GLES2Canvas(context, size);
- m_uploadTexture.clear();
-#if USE(ACCELERATED_COMPOSITING)
- CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(context->platformLayer());
- layer->setPrepareTextureCallback(PrepareTextureCallbackImpl::create(this));
-#endif
+ if (context && drawingBuffer) {
+ m_useGPU = true;
+ m_gpuCanvas = new GLES2Canvas(context, drawingBuffer, size);
+ m_uploadTexture.clear();
+ drawingBuffer->setWillPublishCallback(WillPublishCallbackImpl::create(this));
+ } else {
+ syncSoftwareCanvas();
+ m_uploadTexture.clear();
+ m_gpuCanvas.clear();
+ m_useGPU = false;
+ }
}
void PlatformContextSkia::prepareForSoftwareDraw() const
@@ -725,9 +731,7 @@ void PlatformContextSkia::prepareForSoftwareDraw() const
// of a compositing operation).
if (m_state->m_xferMode == SkXfermode::kSrcOver_Mode) {
- // Last drawn on hardware; clear out the canvas.
- m_canvas->getDevice()->eraseColor(0);
- // Start compositing into the empty canvas.
+ // Note that we have rendering results in both the hardware and software backing stores.
m_backingStoreState = Mixed;
} else {
readbackHardwareToSoftware();
@@ -780,17 +784,42 @@ void PlatformContextSkia::syncSoftwareCanvas() const
m_backingStoreState = Software;
}
+void PlatformContextSkia::markDirtyRect(const IntRect& rect)
+{
+ if (!m_useGPU)
+ return;
+
+ switch (m_backingStoreState) {
+ case Software:
+ case Mixed:
+ m_softwareDirtyRect.unite(rect);
+ return;
+ case Hardware:
+ return;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const
{
const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
SkAutoLockPixels lock(bitmap);
- GraphicsContext3D* context = m_gpuCanvas->context();
+ SharedGraphicsContext3D* context = m_gpuCanvas->context();
if (!m_uploadTexture || m_uploadTexture->tiles().totalSizeX() < bitmap.width() || m_uploadTexture->tiles().totalSizeY() < bitmap.height())
- m_uploadTexture = Texture::create(context, Texture::BGRA8, bitmap.width(), bitmap.height());
- m_uploadTexture->load(bitmap.getPixels());
- IntRect rect(0, 0, bitmap.width(), bitmap.height());
+ m_uploadTexture = context->createTexture(Texture::BGRA8, bitmap.width(), bitmap.height());
+
+ m_uploadTexture->updateSubRect(bitmap.getPixels(), m_softwareDirtyRect);
AffineTransform identity;
- gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op);
+ gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), m_softwareDirtyRect, m_softwareDirtyRect, identity, 1.0, DeviceColorSpace, op);
+ // Clear out the region of the software canvas we just uploaded.
+ m_canvas->save();
+ m_canvas->resetMatrix();
+ SkRect bounds = m_softwareDirtyRect;
+ m_canvas->clipRect(bounds, SkRegion::kReplace_Op);
+ m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ m_canvas->restore();
+ m_softwareDirtyRect.setWidth(0); // Clear dirty rect.
}
void PlatformContextSkia::readbackHardwareToSoftware() const
@@ -799,7 +828,8 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
SkAutoLockPixels lock(bitmap);
int width = bitmap.width(), height = bitmap.height();
OwnArrayPtr<uint32_t> buf(new uint32_t[width]);
- GraphicsContext3D* context = m_gpuCanvas->context();
+ SharedGraphicsContext3D* context = m_gpuCanvas->context();
+ m_gpuCanvas->bindFramebuffer();
// Flips the image vertically.
for (int y = 0; y < height; ++y) {
uint32_t* pixels = bitmap.getAddr32(0, y);
@@ -814,6 +844,7 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
}
}
}
+ m_softwareDirtyRect.unite(IntRect(0, 0, width, height)); // Mark everything as dirty.
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 82edc16..4ba85d1 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, 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
@@ -14,7 +14,7 @@
* * 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
@@ -35,7 +35,6 @@
#include "Noncopyable.h"
#include "SkDashPathEffect.h"
-#include "SkDeque.h"
#include "SkDrawLooper.h"
#include "SkPaint.h"
#include "SkPath.h"
@@ -46,9 +45,10 @@
namespace WebCore {
enum CompositeOperator;
+class DrawingBuffer;
class GLES2Canvas;
-class Texture;
class GraphicsContext3D;
+class Texture;
// This class holds the platform-specific state for GraphicsContext. We put
// most of our Skia wrappers on this class. In theory, a lot of this stuff could
@@ -78,7 +78,6 @@ public:
// to the constructor.
void setCanvas(skia::PlatformCanvas*);
-#if OS(WINDOWS)
// If false we're rendering to a GraphicsContext for a web page, if false
// we're not (as is the case when rendering to a canvas object).
// If this is true the contents have not been marked up with the magic
@@ -86,7 +85,6 @@ public:
// correctly updated.
void setDrawingToImageBuffer(bool);
bool isDrawingToImageBuffer() const;
-#endif
void save();
void restore();
@@ -95,9 +93,7 @@ public:
// |rect|. This layer is implicitly restored when the next restore is
// invoked.
// NOTE: |imageBuffer| may be deleted before the |restore| is invoked.
-#if OS(LINUX) || OS(WINDOWS)
void beginLayerClippedToImage(const FloatRect&, const ImageBuffer*);
-#endif
void clipPathAntiAliased(const SkPath&);
// Sets up the common flags on a paint for antialiasing, effects, etc.
@@ -143,6 +139,8 @@ public:
void addPath(const SkPath&);
SkPath currentPathInLocalCoordinates() const;
+ void canvasClipPath(const SkPath&);
+
// Returns the fill color. The returned color has it's alpha adjusted
// by the current alpha.
SkColor effectiveFillColor() const;
@@ -180,8 +178,10 @@ public:
void setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize);
void clearImageResamplingHint();
bool hasImageResamplingHint() const;
+
+ bool canAccelerate() const;
bool useGPU() { return m_useGPU; }
- void setGraphicsContext3D(GraphicsContext3D*, const IntSize&);
+ void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); }
// Call these before making a call that manipulates the underlying
@@ -190,13 +190,12 @@ public:
void prepareForHardwareDraw() const;
// Call to force the skia::PlatformCanvas to contain all rendering results.
void syncSoftwareCanvas() const;
+ void markDirtyRect(const IntRect& rect);
private:
-#if OS(LINUX) || OS(WINDOWS)
// Used when restoring and the state has an image clip. Only shows the pixels in
// m_canvas that are also in imageBuffer.
void applyClipFromImage(const FloatRect&, const SkBitmap&);
-#endif
void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
void uploadSoftwareToHardware(CompositeOperator) const;
@@ -218,17 +217,16 @@ private:
// Current path in global coordinates.
SkPath m_path;
- // Stores image sizes for a hint to compute image resampling modes.
+ // Stores image sizes for a hint to compute image resampling modes.
// Values are used in ImageSkia.cpp
IntSize m_imageResamplingHintSrcSize;
FloatSize m_imageResamplingHintDstSize;
-#if OS(WINDOWS)
bool m_drawingToImageBuffer;
-#endif
bool m_useGPU;
OwnPtr<GLES2Canvas> m_gpuCanvas;
mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
mutable RefPtr<Texture> m_uploadTexture;
+ mutable IntRect m_softwareDirtyRect;
};
}
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index 7b65e96..0203d42 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -79,37 +79,37 @@ GraphicsContext::GraphicsContext(HDC hdc, bool hasAlpha)
// suitable for all clients?
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
- if (mayCreateBitmap && hdc && inTransparencyLayer()) {
- if (dstRect.isEmpty())
- return;
-
- HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
-
- // Need to make a CGImage out of the bitmap's pixel buffer and then draw
- // it into our context.
- BITMAP info;
- GetObject(bitmap, sizeof(info), &info);
- ASSERT(info.bmBitsPixel == 32);
-
- CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
- CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
- info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little |
- (supportAlphaBlend ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst));
- CGColorSpaceRelease(deviceRGB);
-
- CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
- CGContextDrawImage(m_data->m_cgContext.get(), dstRect, image);
-
- // Delete all our junk.
- CGImageRelease(image);
- CGContextRelease(bitmapContext);
- ::DeleteDC(hdc);
- ::DeleteObject(bitmap);
-
+ bool createdBitmap = mayCreateBitmap && (!m_data->m_hdc || inTransparencyLayer());
+ if (!createdBitmap) {
+ m_data->restore();
return;
}
- m_data->restore();
+ if (dstRect.isEmpty())
+ return;
+
+ HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+
+ // Need to make a CGImage out of the bitmap's pixel buffer and then draw
+ // it into our context.
+ BITMAP info;
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
+ CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
+ info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little |
+ (supportAlphaBlend ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst));
+ CGColorSpaceRelease(deviceRGB);
+
+ CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
+ CGContextDrawImage(m_data->m_cgContext.get(), dstRect, image);
+
+ // Delete all our junk.
+ CGImageRelease(image);
+ CGContextRelease(bitmapContext);
+ ::DeleteDC(hdc);
+ ::DeleteObject(bitmap);
}
void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point)
diff --git a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
index 94df6ae..a989c24 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
@@ -92,7 +92,8 @@ static void setRGBABitmapAlpha(unsigned char* bytes, size_t length, unsigned cha
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
- if (!mayCreateBitmap || !hdc || !inTransparencyLayer()) {
+ bool createdBitmap = mayCreateBitmap && (!m_data->m_hdc || inTransparencyLayer());
+ if (!hdc || !createdBitmap) {
m_data->restore();
return;
}
diff --git a/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index 161b9c6..f1953e4 100644
--- a/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -101,7 +101,7 @@ GraphicsContext::WindowsBitmap* GraphicsContext::createWindowsBitmap(IntSize siz
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
// FIXME: Should a bitmap be created also when a shadow is set?
- if (mayCreateBitmap && inTransparencyLayer()) {
+ if (mayCreateBitmap && (!m_data->m_hdc || inTransparencyLayer())) {
if (dstRect.isEmpty())
return 0;
diff --git a/WebCore/platform/graphics/win/IconWin.cpp b/WebCore/platform/graphics/win/IconWin.cpp
index cc9343a..05959e0 100644
--- a/WebCore/platform/graphics/win/IconWin.cpp
+++ b/WebCore/platform/graphics/win/IconWin.cpp
@@ -23,6 +23,7 @@
#include "Icon.h"
#include "GraphicsContext.h"
+#include "LocalWindowsContext.h"
#include "PlatformString.h"
#include <tchar.h>
#include <windows.h>
@@ -90,11 +91,8 @@ void Icon::paint(GraphicsContext* context, const IntRect& r)
#if OS(WINCE)
context->drawIcon(m_hIcon, r, DI_NORMAL);
#else
- HDC hdc = context->getWindowsContext(r);
-
- DrawIconEx(hdc, r.x(), r.y(), m_hIcon, r.width(), r.height(), 0, 0, DI_NORMAL);
-
- context->releaseWindowsContext(hdc, r);
+ LocalWindowsContext windowContext(context, r);
+ DrawIconEx(windowContext.hdc(), r.x(), r.y(), m_hIcon, r.width(), r.height(), 0, 0, DI_NORMAL);
#endif
}
diff --git a/WebCore/platform/graphics/win/LocalWindowsContext.h b/WebCore/platform/graphics/win/LocalWindowsContext.h
new file mode 100755
index 0000000..c216140
--- /dev/null
+++ b/WebCore/platform/graphics/win/LocalWindowsContext.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LocalWindowsContext_h
+#define LocalWindowsContext_h
+
+#include "config.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+class LocalWindowsContext : public Noncopyable {
+public:
+ LocalWindowsContext(GraphicsContext* graphicsContext, const IntRect& rect, bool supportAlphaBlend = true, bool mayCreateBitmap = true)
+ : m_graphicsContext(graphicsContext)
+ , m_rect(rect)
+ , m_supportAlphaBlend(supportAlphaBlend)
+ , m_mayCreateBitmap(mayCreateBitmap)
+ {
+ m_hdc = m_graphicsContext->getWindowsContext(m_rect, m_supportAlphaBlend, m_mayCreateBitmap);
+ }
+
+ ~LocalWindowsContext()
+ {
+ m_graphicsContext->releaseWindowsContext(m_hdc, m_rect, m_supportAlphaBlend, m_mayCreateBitmap);
+ }
+
+ HDC hdc() const { return m_hdc; }
+
+private:
+ GraphicsContext* m_graphicsContext;
+ HDC m_hdc;
+ IntRect m_rect;
+ bool m_supportAlphaBlend;
+ bool m_mayCreateBitmap;
+};
+
+} // namespace WebCore
+#endif // LocalWindowsContext_h
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index 34f1135..c37f5d5 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -600,6 +600,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
bool usingTempBitmap = false;
OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
+ // FIXME: use LocalWindowsContext.
HDC hdc = p->getWindowsContext(r);
if (!hdc) {
// The graphics context doesn't have an associated HDC so create a temporary
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
index 2a355c2..630a8af 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
@@ -408,10 +408,7 @@ bool WKCACFLayerRenderer::createRenderer()
m_d3dDevice = device;
- D3DXMATRIXA16 projection;
- D3DXMatrixOrthoOffCenterRH(&projection, rect.left, rect.right, rect.top, rect.bottom, -1.0f, 1.0f);
-
- m_d3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
+ initD3DGeometry();
m_renderer = CARenderOGLNew(&kCARenderDX9Callbacks, m_d3dDevice.get(), 0);
diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp
index b2c32a4..3fe5ba1 100644
--- a/WebCore/platform/gtk/ClipboardGtk.cpp
+++ b/WebCore/platform/gtk/ClipboardGtk.cpp
@@ -348,7 +348,7 @@ void ClipboardGtk::writeRange(Range* range, Frame* frame)
{
ASSERT(range);
- m_dataObject->setText(frame->selectedText());
+ m_dataObject->setText(frame->editor()->selectedText());
m_dataObject->setMarkup(createMarkup(range, 0, AnnotateForInterchange, false, AbsoluteURLs));
if (m_clipboard)
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.cpp b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
index 69a0843..5b34c68 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.cpp
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
@@ -19,6 +19,7 @@
#include "config.h"
#include "GeolocationServiceGtk.h"
+#if ENABLE(GEOLOCATION)
#include "GOwnPtr.h"
#include "NotImplemented.h"
@@ -211,3 +212,4 @@ void GeolocationServiceGtk::setError(PositionError::ErrorCode errorCode, const c
}
}
+#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.h b/WebCore/platform/gtk/GeolocationServiceGtk.h
index c123017..46249ed 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.h
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.h
@@ -19,6 +19,7 @@
#ifndef GeolocationServiceGtk_h
#define GeolocationServiceGtk_h
+#if ENABLE(GEOLOCATION)
#include "GeolocationService.h"
#include "Geoposition.h"
@@ -70,4 +71,5 @@ namespace WebCore {
};
}
+#endif // ENABLE(GEOLOCATION)
#endif
diff --git a/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp b/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp
new file mode 100644
index 0000000..c2e24e0
--- /dev/null
+++ b/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2007, 2009 Holger Hans Peter Freyther zecke@selfish.org
+ * Copyright (C) 2010 Gustavo Noronha Silva <gns@gnome.org>
+ * Copyright (C) 2010 Collabora Ltd.
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "MainFrameScrollbarGtk.h"
+
+#include "GraphicsContext.h"
+#include "GtkVersioning.h"
+#include "IntRect.h"
+#include <gtk/gtk.h>
+
+using namespace WebCore;
+
+PassRefPtr<MainFrameScrollbarGtk> MainFrameScrollbarGtk::create(ScrollbarClient* client, ScrollbarOrientation orientation, GtkAdjustment* adj)
+{
+ return adoptRef(new MainFrameScrollbarGtk(client, orientation, adj));
+}
+
+// Main frame scrollbars are slaves to a GtkAdjustment. If a main frame
+// scrollbar has an m_adjustment, it belongs to the container (a GtkWidget such
+// as GtkScrolledWindow). The adjustment may also be null, in which case there
+// is no containing view or the parent ScrollView is in some sort of transition
+// state. These scrollbars are never painted, as the container takes care of
+// that. They exist only to shuttle data from the GtkWidget container into
+// WebCore and vice-versa.
+MainFrameScrollbarGtk::MainFrameScrollbarGtk(ScrollbarClient* client, ScrollbarOrientation orientation, GtkAdjustment* adjustment)
+ : Scrollbar(client, orientation, RegularScrollbar)
+ , m_adjustment(0)
+{
+ attachAdjustment(adjustment);
+
+ // We have nothing to show as we are solely operating on the GtkAdjustment.
+ resize(0, 0);
+}
+
+MainFrameScrollbarGtk::~MainFrameScrollbarGtk()
+{
+ if (m_adjustment)
+ detachAdjustment();
+}
+
+void MainFrameScrollbarGtk::attachAdjustment(GtkAdjustment* adjustment)
+{
+ if (m_adjustment)
+ detachAdjustment();
+
+ m_adjustment = adjustment;
+ if (!m_adjustment)
+ return;
+
+ g_signal_connect(m_adjustment.get(), "value-changed", G_CALLBACK(MainFrameScrollbarGtk::gtkValueChanged), this);
+ updateThumbProportion();
+ updateThumbPosition();
+}
+
+void MainFrameScrollbarGtk::detachAdjustment()
+{
+ if (!m_adjustment)
+ return;
+
+ g_signal_handlers_disconnect_by_func(G_OBJECT(m_adjustment.get()), (gpointer)MainFrameScrollbarGtk::gtkValueChanged, this);
+
+ // For the case where we only operate on the GtkAdjustment it is best to
+ // reset the values so that the surrounding scrollbar gets updated, or
+ // e.g. for a GtkScrolledWindow the scrollbar gets hidden.
+ gtk_adjustment_configure(m_adjustment.get(), 0, 0, 0, 0, 0, 0);
+
+ m_adjustment = 0;
+}
+
+void MainFrameScrollbarGtk::updateThumbPosition()
+{
+ if (!m_adjustment || gtk_adjustment_get_value(m_adjustment.get()) == m_currentPos)
+ return;
+ gtk_adjustment_set_value(m_adjustment.get(), m_currentPos);
+}
+
+void MainFrameScrollbarGtk::updateThumbProportion()
+{
+ if (!m_adjustment)
+ return;
+ gtk_adjustment_configure(m_adjustment.get(),
+ gtk_adjustment_get_value(m_adjustment.get()),
+ gtk_adjustment_get_lower(m_adjustment.get()),
+ m_totalSize,
+ m_lineStep,
+ m_pageStep,
+ m_visibleSize);
+}
+
+void MainFrameScrollbarGtk::gtkValueChanged(GtkAdjustment*, MainFrameScrollbarGtk* that)
+{
+ that->setValue(static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get())), NotFromScrollAnimator);
+}
+
+void MainFrameScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect)
+{
+ // Main frame scrollbars are not painted by WebCore.
+ return;
+}
diff --git a/WebCore/platform/gtk/MainFrameScrollbarGtk.h b/WebCore/platform/gtk/MainFrameScrollbarGtk.h
new file mode 100644
index 0000000..8271ef5
--- /dev/null
+++ b/WebCore/platform/gtk/MainFrameScrollbarGtk.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef MainFrameScrollbarGtk_h
+#define MainFrameScrollbarGtk_h
+
+#include "GRefPtrGtk.h"
+#include "Scrollbar.h"
+#include <wtf/PassRefPtr.h>
+
+typedef struct _GtkAdjustment GtkAdjustment;
+
+namespace WebCore {
+
+class MainFrameScrollbarGtk : public Scrollbar {
+public:
+ ~MainFrameScrollbarGtk();
+ virtual void paint(GraphicsContext*, const IntRect&);
+ void detachAdjustment();
+ void attachAdjustment(GtkAdjustment*);
+ static PassRefPtr<MainFrameScrollbarGtk> create(ScrollbarClient*, ScrollbarOrientation, GtkAdjustment*);
+
+protected:
+ virtual void updateThumbPosition();
+ virtual void updateThumbProportion();
+
+private:
+ MainFrameScrollbarGtk(ScrollbarClient*, ScrollbarOrientation, GtkAdjustment*);
+ static void gtkValueChanged(GtkAdjustment*, MainFrameScrollbarGtk*);
+
+ PlatformRefPtr<GtkAdjustment> m_adjustment;
+};
+
+}
+
+#endif // ScrollbarGtk_h
diff --git a/WebCore/platform/gtk/PasteboardGtk.cpp b/WebCore/platform/gtk/PasteboardGtk.cpp
index ddb9768..76b7bb0 100644
--- a/WebCore/platform/gtk/PasteboardGtk.cpp
+++ b/WebCore/platform/gtk/PasteboardGtk.cpp
@@ -67,7 +67,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
{
GtkClipboard* clipboard = m_helper->getClipboard(frame);
DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
- dataObject->setText(frame->selectedText());
+ dataObject->setText(frame->editor()->selectedText());
dataObject->setMarkup(createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs));
m_helper->writeClipboardContents(clipboard);
}
diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp
index 565123c..ebcdaa1 100644
--- a/WebCore/platform/gtk/ScrollViewGtk.cpp
+++ b/WebCore/platform/gtk/ScrollViewGtk.cpp
@@ -39,10 +39,10 @@
#include "GtkVersioning.h"
#include "HostWindow.h"
#include "IntRect.h"
+#include "MainFrameScrollbarGtk.h"
#include "Page.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
-#include "ScrollbarGtk.h"
#include "ScrollbarTheme.h"
#include <gtk/gtk.h>
@@ -53,8 +53,6 @@ namespace WebCore {
void ScrollView::platformInit()
{
- m_horizontalAdjustment = 0;
- m_verticalAdjustment = 0;
}
void ScrollView::platformDestroy()
@@ -65,9 +63,8 @@ void ScrollView::platformDestroy()
PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientation)
{
- // If this is an interior frame scrollbar, we want to create a scrollbar without
- // passing a GtkAdjustment. This will cause the Scrollbar to create a native GTK+
- // scrollbar.
+ // If this is an interior frame scrollbar, we want to create a totally fake
+ // scrollbar with no GtkAdjustment backing it.
if (parent())
return Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
@@ -75,10 +72,10 @@ PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientati
// and defers to our GtkAdjustment for all of its state. Note that the GtkAdjustment
// may be null here.
if (orientation == HorizontalScrollbar)
- return ScrollbarGtk::createScrollbar(this, orientation, m_horizontalAdjustment);
+ return MainFrameScrollbarGtk::create(this, orientation, m_horizontalAdjustment.get());
// VerticalScrollbar
- return ScrollbarGtk::createScrollbar(this, orientation, m_verticalAdjustment);
+ return MainFrameScrollbarGtk::create(this, orientation, m_verticalAdjustment.get());
}
/*
@@ -89,15 +86,23 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo
{
ASSERT(!hadj == !vadj);
+ // If this is a non-main frame ScrollView, we do not want to set the
+ // m_horizontalAdjustments & m_verticalAdjustments members. At the same
+ // time we want to to allow FrameLoaderClientGtk.cpp to call
+ // ScrollView::setGtkAdjustments(0, 0) unconditionally.
+ ASSERT(!parent() || !hadj);
+ if (parent())
+ return;
+
m_horizontalAdjustment = hadj;
m_verticalAdjustment = vadj;
if (!m_horizontalAdjustment) {
- ScrollbarGtk* hScrollbar = reinterpret_cast<ScrollbarGtk*>(horizontalScrollbar());
+ MainFrameScrollbarGtk* hScrollbar = reinterpret_cast<MainFrameScrollbarGtk*>(horizontalScrollbar());
if (hScrollbar)
hScrollbar->detachAdjustment();
- ScrollbarGtk* vScrollbar = reinterpret_cast<ScrollbarGtk*>(verticalScrollbar());
+ MainFrameScrollbarGtk* vScrollbar = reinterpret_cast<MainFrameScrollbarGtk*>(verticalScrollbar());
if (vScrollbar)
vScrollbar->detachAdjustment();
@@ -109,11 +114,11 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo
setHasVerticalScrollbar(true);
setHasHorizontalScrollbar(true);
- ScrollbarGtk* hScrollbar = reinterpret_cast<ScrollbarGtk*>(horizontalScrollbar());
- hScrollbar->attachAdjustment(m_horizontalAdjustment);
+ MainFrameScrollbarGtk* hScrollbar = reinterpret_cast<MainFrameScrollbarGtk*>(horizontalScrollbar());
+ hScrollbar->attachAdjustment(m_horizontalAdjustment.get());
- ScrollbarGtk* vScrollbar = reinterpret_cast<ScrollbarGtk*>(verticalScrollbar());
- vScrollbar->attachAdjustment(m_verticalAdjustment);
+ MainFrameScrollbarGtk* vScrollbar = reinterpret_cast<MainFrameScrollbarGtk*>(verticalScrollbar());
+ vScrollbar->attachAdjustment(m_verticalAdjustment.get());
// We used to reset everything to 0 here, but when page cache
// is enabled we reuse FrameViews that are cached. Since their
@@ -124,7 +129,7 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo
// able to report correct values.
int horizontalPageStep = max(max<int>(frameRect().width() * Scrollbar::minFractionToStepWhenPaging(), frameRect().width() - Scrollbar::maxOverlapBetweenPages()), 1);
- gtk_adjustment_configure(m_horizontalAdjustment,
+ gtk_adjustment_configure(m_horizontalAdjustment.get(),
resetValues ? 0 : scrollOffset().width(), 0,
resetValues ? 0 : contentsSize().width(),
resetValues ? 0 : Scrollbar::pixelsPerLineStep(),
@@ -132,7 +137,7 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo
resetValues ? 0 : frameRect().width());
int verticalPageStep = max(max<int>(frameRect().height() * Scrollbar::minFractionToStepWhenPaging(), frameRect().height() - Scrollbar::maxOverlapBetweenPages()), 1);
- gtk_adjustment_configure(m_verticalAdjustment,
+ gtk_adjustment_configure(m_verticalAdjustment.get(),
resetValues ? 0 : scrollOffset().height(), 0,
resetValues ? 0 : contentsSize().height(),
resetValues ? 0 : Scrollbar::pixelsPerLineStep(),
@@ -142,72 +147,73 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo
void ScrollView::platformAddChild(Widget* child)
{
- if (!GTK_IS_SOCKET(child->platformWidget()))
- gtk_container_add(GTK_CONTAINER(hostWindow()->platformPageClient()), child->platformWidget());
}
void ScrollView::platformRemoveChild(Widget* child)
{
- GtkWidget* parent;
-
- // HostWindow can be NULL here. If that's the case
- // let's grab the child's parent instead.
- if (hostWindow())
- parent = GTK_WIDGET(hostWindow()->platformPageClient());
- else
- parent = GTK_WIDGET(gtk_widget_get_parent(child->platformWidget()));
-
- if (GTK_IS_CONTAINER(parent) && parent == gtk_widget_get_parent(child->platformWidget()))
- gtk_container_remove(GTK_CONTAINER(parent), child->platformWidget());
}
IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
{
- if (!m_horizontalAdjustment)
+ // If we are an interior frame scrollbar or are in some sort of transition
+ // state, just calculate our size based on what the GTK+ theme says the
+ // scrollbar width should be.
+ if (parent() || !hostWindow() || !hostWindow()->platformPageClient()) {
return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()),
IntSize(max(0, width() - (verticalScrollbar() && !includeScrollbars ? verticalScrollbar()->width() : 0)),
max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0))));
+ }
- // Main frame.
+ // We don't have a parent, so we are the main frame and thus have
+ // a parent widget which we can use to measure the visible region.
GtkWidget* measuredWidget = hostWindow()->platformPageClient();
- GtkWidget* parent = gtk_widget_get_parent(measuredWidget);
+ GtkWidget* parentWidget = gtk_widget_get_parent(measuredWidget);
// We may not be in a widget that displays scrollbars, but we may
// have other kinds of decoration that make us smaller.
- if (parent && includeScrollbars)
- measuredWidget = parent;
+ if (parentWidget && includeScrollbars)
+ measuredWidget = parentWidget;
GtkAllocation allocation;
-#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_get_allocation(measuredWidget, &allocation);
-#else
- allocation = measuredWidget->allocation;
-#endif
return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()),
IntSize(allocation.width, allocation.height));
}
-void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode, bool, bool)
+void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode, bool horizontalLock, bool verticalLock)
{
- if (horizontalMode == m_horizontalScrollbarMode && verticalMode == m_verticalScrollbarMode)
- return;
+ // FIXME: Restructure the ScrollView abstraction so that we do not have to
+ // copy this verbatim from ScrollView.cpp. Until then, we should make sure this
+ // is kept in sync.
+ bool needsUpdate = false;
+
+ if (horizontalMode != horizontalScrollbarMode() && !m_horizontalScrollbarLock) {
+ m_horizontalScrollbarMode = horizontalMode;
+ needsUpdate = true;
+ }
- m_horizontalScrollbarMode = horizontalMode;
- m_verticalScrollbarMode = verticalMode;
+ if (verticalMode != verticalScrollbarMode() && !m_verticalScrollbarLock) {
+ m_verticalScrollbarMode = verticalMode;
+ needsUpdate = true;
+ }
- // We don't really care about reporting policy changes on frames
- // that have no adjustments attached to them.
- if (!m_horizontalAdjustment) {
+ if (horizontalLock)
+ setHorizontalScrollbarLock();
+
+ if (verticalLock)
+ setVerticalScrollbarLock();
+
+ if (needsUpdate)
updateScrollbars(scrollOffset());
- return;
- }
- if (!isFrameView())
+ // We don't need to report policy changes on ScrollView's unless this
+ // one has an adjustment attached and it is a main frame.
+ if (!m_horizontalAdjustment || parent() || !isFrameView())
return;
// For frames that do have adjustments attached, we want to report
// policy changes, so that they may be applied to the widget to
- // which the WebView has been added, for instance.
+ // which the WebView's container (e.g. GtkScrolledWindow).
if (hostWindow())
hostWindow()->scrollbarsModeDidChange();
}
diff --git a/WebCore/platform/gtk/ScrollbarGtk.cpp b/WebCore/platform/gtk/ScrollbarGtk.cpp
deleted file mode 100644
index 8a1c4fa..0000000
--- a/WebCore/platform/gtk/ScrollbarGtk.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2007, 2009 Holger Hans Peter Freyther zecke@selfish.org
- * Copyright (C) 2010 Gustavo Noronha Silva <gns@gnome.org>
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "ScrollbarGtk.h"
-
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "GtkVersioning.h"
-#include "IntRect.h"
-#include "ScrollbarTheme.h"
-
-#include <gtk/gtk.h>
-
-using namespace WebCore;
-
-PassRefPtr<Scrollbar> Scrollbar::createNativeScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size)
-{
- return adoptRef(new ScrollbarGtk(client, orientation, size));
-}
-
-PassRefPtr<ScrollbarGtk> ScrollbarGtk::createScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, GtkAdjustment* adj)
-{
- return adoptRef(new ScrollbarGtk(client, orientation, adj));
-}
-
-static gboolean gtkScrollEventCallback(GtkWidget* widget, GdkEventScroll* event, ScrollbarGtk*)
-{
- /* Scroll only if our parent rejects the scroll event. The rationale for
- * this is that we want the main frame to scroll when we move the mouse
- * wheel over a child scrollbar in most cases. */
- return gtk_widget_event(gtk_widget_get_parent(widget), reinterpret_cast<GdkEvent*>(event));
-}
-
-ScrollbarGtk::ScrollbarGtk(ScrollbarClient* client, ScrollbarOrientation orientation,
- ScrollbarControlSize controlSize)
- : Scrollbar(client, orientation, controlSize)
- , m_adjustment(GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)))
-{
- GtkWidget* scrollBar = orientation == HorizontalScrollbar ?
- gtk_hscrollbar_new(m_adjustment):
- gtk_vscrollbar_new(m_adjustment);
- gtk_widget_show(scrollBar);
- g_object_ref(m_adjustment);
- g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
- g_signal_connect(scrollBar, "scroll-event", G_CALLBACK(gtkScrollEventCallback), this);
-
- setPlatformWidget(scrollBar);
-
- /*
- * assign a sane default width and height to the Scrollbar, otherwise
- * we will end up with a 0 width scrollbar.
- */
- resize(ScrollbarTheme::nativeTheme()->scrollbarThickness(),
- ScrollbarTheme::nativeTheme()->scrollbarThickness());
-}
-
-// Create a ScrollbarGtk on top of an existing GtkAdjustment but do not create a
-// GtkScrollbar on top of this adjustment. The goal is to have a WebCore::Scrollbar
-// that will manipulate the GtkAdjustment properties, will react to the changed
-// value but will not consume any space on the screen and will not be painted
-// at all. It is achieved by not calling setPlatformWidget.
-ScrollbarGtk::ScrollbarGtk(ScrollbarClient* client, ScrollbarOrientation orientation, GtkAdjustment* adjustment)
- : Scrollbar(client, orientation, RegularScrollbar)
- , m_adjustment(adjustment)
-{
- if (m_adjustment) {
- g_object_ref(m_adjustment);
- g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
- }
-
- // We have nothing to show as we are solely operating on the GtkAdjustment
- resize(0, 0);
-}
-
-ScrollbarGtk::~ScrollbarGtk()
-{
- if (m_adjustment)
- detachAdjustment();
-}
-
-void ScrollbarGtk::attachAdjustment(GtkAdjustment* adjustment)
-{
- if (platformWidget())
- return;
-
- if (m_adjustment)
- detachAdjustment();
-
- m_adjustment = adjustment;
-
- if (m_adjustment) {
- g_object_ref(m_adjustment);
- g_signal_connect(m_adjustment, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
- }
-
- updateThumbProportion();
- updateThumbPosition();
-}
-
-void ScrollbarGtk::detachAdjustment()
-{
- if (!m_adjustment)
- return;
-
- g_signal_handlers_disconnect_by_func(G_OBJECT(m_adjustment), (gpointer)ScrollbarGtk::gtkValueChanged, this);
-
- // For the case where we only operate on the GtkAdjustment it is best to
- // reset the values so that the surrounding scrollbar gets updated, or
- // e.g. for a GtkScrolledWindow the scrollbar gets hidden.
- gtk_adjustment_configure(m_adjustment, 0, 0, 0, 0, 0, 0);
-
- g_object_unref(m_adjustment);
- m_adjustment = 0;
-}
-
-IntPoint ScrollbarGtk::getLocationInParentWindow(const IntRect& rect)
-{
- IntPoint loc;
-
- if (parent()->isScrollViewScrollbar(this))
- loc = parent()->convertToContainingWindow(rect.location());
- else
- loc = parent()->contentsToWindow(rect.location());
-
- return loc;
-}
-
-void ScrollbarGtk::frameRectsChanged()
-{
- if (!parent() || !platformWidget())
- return;
-
- IntPoint loc = getLocationInParentWindow(frameRect());
-
- // Don't allow the allocation size to be negative
- IntSize sz = frameRect().size();
- sz.clampNegativeToZero();
-
- GtkAllocation allocation = { loc.x(), loc.y(), sz.width(), sz.height() };
- gtk_widget_size_allocate(platformWidget(), &allocation);
-}
-
-void ScrollbarGtk::updateThumbPosition()
-{
- if (!m_adjustment)
- return;
-
- if (gtk_adjustment_get_value(m_adjustment) != m_currentPos)
- gtk_adjustment_set_value(m_adjustment, m_currentPos);
-}
-
-void ScrollbarGtk::updateThumbProportion()
-{
- if (!m_adjustment)
- return;
-
- gtk_adjustment_configure(m_adjustment,
- gtk_adjustment_get_value(m_adjustment),
- gtk_adjustment_get_lower(m_adjustment),
- m_totalSize,
- m_lineStep,
- m_pageStep,
- m_visibleSize);
-}
-
-void ScrollbarGtk::setFrameRect(const IntRect& rect)
-{
- Widget::setFrameRect(rect);
- frameRectsChanged();
-}
-
-void ScrollbarGtk::gtkValueChanged(GtkAdjustment*, ScrollbarGtk* that)
-{
- that->setValue(static_cast<int>(gtk_adjustment_get_value(that->m_adjustment)));
-}
-
-void ScrollbarGtk::setEnabled(bool shouldEnable)
-{
- if (enabled() == shouldEnable)
- return;
-
- Scrollbar::setEnabled(shouldEnable);
- if (platformWidget())
- gtk_widget_set_sensitive(platformWidget(), shouldEnable);
-}
-
-/*
- * Strategy to painting a Widget:
- * 1.) do not paint if there is no GtkWidget set
- * 2.) We assume that the widget has no window and that frameRectsChanged positioned
- * the widget correctly. ATM we do not honor the GraphicsContext translation.
- */
-void ScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect)
-{
- if (!platformWidget())
- return;
-
- if (!context->gdkExposeEvent())
- return;
-
- GtkWidget* widget = platformWidget();
- ASSERT(!gtk_widget_get_has_window(widget));
-
- GdkEvent* event = gdk_event_new(GDK_EXPOSE);
- event->expose = *context->gdkExposeEvent();
- event->expose.area = static_cast<GdkRectangle>(rect);
-
- IntPoint loc = getLocationInParentWindow(rect);
-
- event->expose.area.x = loc.x();
- event->expose.area.y = loc.y();
-
-#ifdef GTK_API_VERSION_2
- event->expose.region = gdk_region_rectangle(&event->expose.area);
-#else
- event->expose.region = cairo_region_create_rectangle(&event->expose.area);
-#endif
-
- /*
- * This will be unref'ed by gdk_event_free.
- */
- g_object_ref(event->expose.window);
-
- /*
- * If we are going to paint do the translation and GtkAllocation manipulation.
- */
-#ifdef GTK_API_VERSION_2
- if (!gdk_region_empty(event->expose.region))
-#else
- if (!cairo_region_is_empty(event->expose.region))
-#endif
- gtk_widget_send_expose(widget, event);
-
- gdk_event_free(event);
-}
diff --git a/WebCore/platform/gtk/ScrollbarGtk.h b/WebCore/platform/gtk/ScrollbarGtk.h
deleted file mode 100644
index 1a078c9..0000000
--- a/WebCore/platform/gtk/ScrollbarGtk.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ScrollbarGtk_h
-#define ScrollbarGtk_h
-
-#include "Scrollbar.h"
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-class ScrollbarGtk : public Scrollbar {
-public:
- friend class Scrollbar;
- friend class ScrollView;
- ~ScrollbarGtk();
-
- virtual void setFrameRect(const IntRect&);
- virtual void paint(GraphicsContext*, const IntRect&);
-
- virtual bool handleMouseMoveEvent(const PlatformMouseEvent&) { return false; }
- virtual bool handleMouseOutEvent(const PlatformMouseEvent&) { return false; }
- virtual bool handleMousePressEvent(const PlatformMouseEvent&) { return false; }
- virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&) { return false; }
-
- virtual void setEnabled(bool);
-
- virtual void frameRectsChanged();
-
-protected:
- static PassRefPtr<ScrollbarGtk> createScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, GtkAdjustment*);
-
- ScrollbarGtk(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize);
- ScrollbarGtk(ScrollbarClient*, ScrollbarOrientation, GtkAdjustment*);
-
- virtual void updateThumbPosition();
- virtual void updateThumbProportion();
-
- void detachAdjustment();
- void attachAdjustment(GtkAdjustment*);
-private:
- static void gtkValueChanged(GtkAdjustment*, ScrollbarGtk*);
- IntPoint getLocationInParentWindow(const IntRect&);
- GtkAdjustment* m_adjustment;
-};
-
-}
-
-#endif // ScrollbarGtk_h
diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
index b6efe54..2e942fe 100644
--- a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
+++ b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
@@ -82,6 +82,8 @@ void ScrollbarThemeGtk::updateThemeProperties()
m_stepperSpacing = metrics.stepper_spacing;
m_minThumbLength = metrics.min_slider_size;
m_troughUnderSteppers = metrics.trough_under_steppers;
+ m_hasForwardButtonStartPart = metrics.has_secondary_forward_stepper;
+ m_hasBackButtonEndPart = metrics.has_secondary_backward_stepper;
if (!gScrollbars)
return;
@@ -120,30 +122,45 @@ bool ScrollbarThemeGtk::hasThumb(Scrollbar* scrollbar)
IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
{
- // We do not support multiple steppers per end yet.
- if (part == BackButtonEndPart)
+ if (part == BackButtonEndPart && !m_hasBackButtonEndPart)
return IntRect();
+ int x = scrollbar->x() + m_troughBorderWidth;
+ int y = scrollbar->y() + m_troughBorderWidth;
IntSize size = buttonSize(scrollbar);
- return IntRect(scrollbar->x() + m_troughBorderWidth, scrollbar->y() + m_troughBorderWidth, size.width(), size.height());
+ if (part == BackButtonStartPart)
+ return IntRect(x, y, size.width(), size.height());
+
+ // BackButtonEndPart (alternate button)
+ if (scrollbar->orientation() == HorizontalScrollbar)
+ return IntRect(scrollbar->x() + scrollbar->width() - m_troughBorderWidth - (2 * size.width()), y, size.width(), size.height());
+
+ // VerticalScrollbar alternate button
+ return IntRect(x, scrollbar->y() + scrollbar->height() - m_troughBorderWidth - (2 * size.height()), size.width(), size.height());
}
IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
{
- // We do not support multiple steppers per end yet.
- if (part == ForwardButtonStartPart)
+ if (part == ForwardButtonStartPart && !m_hasForwardButtonStartPart)
return IntRect();
IntSize size = buttonSize(scrollbar);
- int x, y;
if (scrollbar->orientation() == HorizontalScrollbar) {
- x = scrollbar->x() + scrollbar->width() - size.width() - m_troughBorderWidth;
- y = scrollbar->y() + m_troughBorderWidth;
- } else {
- x = scrollbar->x() + m_troughBorderWidth;
- y = scrollbar->y() + scrollbar->height() - size.height() - m_troughBorderWidth;
+ int y = scrollbar->y() + m_troughBorderWidth;
+ if (part == ForwardButtonEndPart)
+ return IntRect(scrollbar->x() + scrollbar->width() - size.width() - m_troughBorderWidth, y, size.width(), size.height());
+
+ // ForwardButtonStartPart (alternate button)
+ return IntRect(scrollbar->x() + m_troughBorderWidth + size.width(), y, size.width(), size.height());
}
- return IntRect(x, y, size.width(), size.height());
+
+ // VerticalScrollbar
+ int x = scrollbar->x() + m_troughBorderWidth;
+ if (part == ForwardButtonEndPart)
+ return IntRect(x, scrollbar->y() + scrollbar->height() - size.height() - m_troughBorderWidth, size.width(), size.height());
+
+ // ForwardButtonStartPart (alternate button)
+ return IntRect(x, scrollbar->y() + m_troughBorderWidth + size.height(), size.width(), size.height());
}
IntRect ScrollbarThemeGtk::trackRect(Scrollbar* scrollbar, bool)
@@ -157,17 +174,28 @@ IntRect ScrollbarThemeGtk::trackRect(Scrollbar* scrollbar, bool)
// The fatness of the scrollbar on the non-movement axis.
int thickness = scrollbarThickness(scrollbar->controlSize());
+ int alternateButtonOffset = 0;
+ int alternateButtonWidth = 0;
+ if (m_hasForwardButtonStartPart) {
+ alternateButtonOffset += m_stepperSize;
+ alternateButtonWidth += m_stepperSize;
+ }
+ if (m_hasBackButtonEndPart)
+ alternateButtonWidth += m_stepperSize;
+
if (scrollbar->orientation() == HorizontalScrollbar) {
// Once the scrollbar becomes smaller than the natural size of the
// two buttons, the track disappears.
if (scrollbar->width() < 2 * thickness)
return IntRect();
- return IntRect(scrollbar->x() + movementAxisPadding, scrollbar->y(), scrollbar->width() - (2 * movementAxisPadding), thickness);
+ return IntRect(scrollbar->x() + movementAxisPadding + alternateButtonOffset, scrollbar->y(),
+ scrollbar->width() - (2 * movementAxisPadding) - alternateButtonWidth, thickness);
}
if (scrollbar->height() < 2 * thickness)
return IntRect();
- return IntRect(scrollbar->x(), scrollbar->y() + movementAxisPadding, thickness, scrollbar->height() - (2 * movementAxisPadding));
+ return IntRect(scrollbar->x(), scrollbar->y() + movementAxisPadding + alternateButtonOffset,
+ thickness, scrollbar->height() - (2 * movementAxisPadding) - alternateButtonWidth);
}
void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
@@ -304,10 +332,10 @@ void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollb
if (scrollbar->orientation() == VerticalScrollbar)
flags |= MOZ_GTK_STEPPER_VERTICAL;
- if (part == ForwardButtonEndPart) {
+ if (part == ForwardButtonEndPart)
+ flags |= (MOZ_GTK_STEPPER_DOWN | MOZ_GTK_STEPPER_BOTTOM);
+ if (part == ForwardButtonStartPart)
flags |= MOZ_GTK_STEPPER_DOWN;
- flags |= MOZ_GTK_STEPPER_BOTTOM;
- }
GtkWidgetState state;
state.focused = TRUE;
@@ -315,7 +343,9 @@ void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollb
state.canDefault = TRUE;
if ((BackButtonStartPart == part && scrollbar->currentPos())
- || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum())) {
+ || (BackButtonEndPart == part && scrollbar->currentPos())
+ || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum())
+ || (ForwardButtonStartPart == part && scrollbar->currentPos() != scrollbar->maximum())) {
state.disabled = FALSE;
state.active = part == scrollbar->pressedPart();
state.inHover = part == scrollbar->hoveredPart();
diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.h b/WebCore/platform/gtk/ScrollbarThemeGtk.h
index eff2fee..8f990d5 100644
--- a/WebCore/platform/gtk/ScrollbarThemeGtk.h
+++ b/WebCore/platform/gtk/ScrollbarThemeGtk.h
@@ -68,6 +68,8 @@ protected:
int m_stepperSpacing;
int m_minThumbLength;
bool m_troughUnderSteppers;
+ bool m_hasForwardButtonStartPart;
+ bool m_hasBackButtonEndPart;
};
}
diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c
index b33fb1f..ba69cdc 100644
--- a/WebCore/platform/gtk/gtk2drawing.c
+++ b/WebCore/platform/gtk/gtk2drawing.c
@@ -3079,6 +3079,8 @@ moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
"stepper_size", &metrics->stepper_size,
"stepper_spacing", &metrics->stepper_spacing,
"trough_under_steppers", &metrics->trough_under_steppers,
+ "has_secondary_forward_stepper", &metrics->has_secondary_forward_stepper,
+ "has_secondary_backward_stepper", &metrics->has_secondary_backward_stepper,
NULL);
metrics->min_slider_size = gtk_range_get_min_slider_size(GTK_RANGE(gParts->horizScrollbarWidget));
diff --git a/WebCore/platform/gtk/gtkdrawing.h b/WebCore/platform/gtk/gtkdrawing.h
index 9d06d5d..c00da97 100644
--- a/WebCore/platform/gtk/gtkdrawing.h
+++ b/WebCore/platform/gtk/gtkdrawing.h
@@ -76,6 +76,8 @@ typedef struct {
gint stepper_spacing;
gint min_slider_size;
gboolean trough_under_steppers;
+ gboolean has_secondary_forward_stepper;
+ gboolean has_secondary_backward_stepper;
} MozGtkScrollbarMetrics;
typedef struct _GtkThemeParts {
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 786f1b6..406a375 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -226,7 +226,7 @@ void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncod
FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);
// Add the content type if it is available.
- if (value.blob()->type().isEmpty())
+ if (!value.blob()->type().isEmpty())
FormDataBuilder::addContentTypeToMultiPartHeader(header, value.blob()->type().latin1());
}
diff --git a/WebCore/platform/network/android/ResourceHandleAndroid.cpp b/WebCore/platform/network/android/ResourceHandleAndroid.cpp
index 2cd1ba9..2a2ea74 100644
--- a/WebCore/platform/network/android/ResourceHandleAndroid.cpp
+++ b/WebCore/platform/network/android/ResourceHandleAndroid.cpp
@@ -27,7 +27,7 @@
#include "ResourceHandle.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "DocumentLoader.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -51,6 +51,7 @@ ResourceHandle::~ResourceHandle()
bool ResourceHandle::start(Frame* frame)
{
+<<<<<<< HEAD
DocumentLoader* docLoader = frame->loader()->activeDocumentLoader();
MainResourceLoader* mainLoader = docLoader->mainResourceLoader();
bool isMainResource =
@@ -58,6 +59,11 @@ bool ResourceHandle::start(Frame* frame)
bool isPrivateBrowsing = false;
if (frame->settings())
isPrivateBrowsing = frame->settings()->privateBrowsingEnabled();
+=======
+ DocumentLoader* documentLoader = frame->loader()->activeDocumentLoader();
+ MainResourceLoader* mainLoader = documentLoader->mainResourceLoader();
+ bool isMainResource = mainLoader && (mainLoader->handle() == this);
+>>>>>>> webkit.org at r67178
PassRefPtr<ResourceLoaderAndroid> loader = ResourceLoaderAndroid::start(this, d->m_firstRequest, frame->loader()->client(), isMainResource, false, isPrivateBrowsing);
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index 419e397..209906e 100644
--- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -34,7 +34,7 @@
#include "Base64.h"
#include "CookieStorageWin.h"
#include "CredentialStorage.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "FormDataStreamCFNet.h"
#include "Frame.h"
#include "FrameLoader.h"
diff --git a/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
index a4c1f8e..096905d 100644
--- a/WebCore/platform/network/curl/ResourceHandleCurl.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
@@ -28,7 +28,7 @@
#include "config.h"
#include "ResourceHandle.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "NotImplemented.h"
#include "ResourceHandleInternal.h"
#include "ResourceHandleManager.h"
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
index ba68351..8d2a1bf 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -612,7 +612,8 @@ static void parseDataUrl(ResourceHandle* handle)
// WebCore's decoder fails on Acid3 test 97 (whitespace).
Vector<char> out;
- if (base64Decode(data.latin1().data(), data.latin1().length(), out) && out.size() > 0)
+ CString latin1 = data.latin1();
+ if (base64Decode(latin1.data(), latin1.length(), out) && out.size() > 0)
client->didReceiveData(handle, out.data(), out.size(), 0);
} else {
// We have to convert to UTF-16 early due to limitations in KURL
diff --git a/WebCore/platform/network/curl/ResourceRequest.h b/WebCore/platform/network/curl/ResourceRequest.h
index 40e1e8f..12dc214 100644
--- a/WebCore/platform/network/curl/ResourceRequest.h
+++ b/WebCore/platform/network/curl/ResourceRequest.h
@@ -56,6 +56,11 @@ namespace WebCore {
{
}
+ ResourceRequest(CFURLRequestRef)
+ : ResourceRequestBase()
+ {
+ }
+
// Needed for compatibility.
CFURLRequestRef cfURLRequest() const { return 0; }
diff --git a/WebCore/platform/network/curl/ResourceResponse.h b/WebCore/platform/network/curl/ResourceResponse.h
index 6195f61..860e902 100644
--- a/WebCore/platform/network/curl/ResourceResponse.h
+++ b/WebCore/platform/network/curl/ResourceResponse.h
@@ -28,6 +28,8 @@
#include "ResourceResponseBase.h"
+typedef const struct _CFURLResponse* CFURLResponseRef;
+
namespace WebCore {
class ResourceResponse : public ResourceResponseBase {
@@ -46,6 +48,9 @@ public:
void setResponseFired(bool fired) { m_responseFired = fired; }
bool responseFired() { return m_responseFired; }
+ // Needed for compatibility.
+ CFURLResponseRef cfURLResponse() const { return 0; }
+
private:
bool m_responseFired;
};
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index d014bb3..0af86d0 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -32,7 +32,7 @@
#import "BlobRegistry.h"
#import "BlockExceptions.h"
#import "CredentialStorage.h"
-#import "DocLoader.h"
+#import "CachedResourceLoader.h"
#import "EmptyProtocolDefinitions.h"
#import "FormDataStreamMac.h"
#import "Frame.h"
diff --git a/WebCore/platform/network/qt/ResourceHandleQt.cpp b/WebCore/platform/network/qt/ResourceHandleQt.cpp
index f91eecb..3548467 100644
--- a/WebCore/platform/network/qt/ResourceHandleQt.cpp
+++ b/WebCore/platform/network/qt/ResourceHandleQt.cpp
@@ -31,7 +31,7 @@
#include "ResourceHandle.h"
#include "ChromeClientQt.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Frame.h"
#include "FrameLoaderClientQt.h"
#include "NotImplemented.h"
diff --git a/WebCore/platform/network/qt/ResourceRequestQt.cpp b/WebCore/platform/network/qt/ResourceRequestQt.cpp
index 637c71f..4d576c7 100644
--- a/WebCore/platform/network/qt/ResourceRequestQt.cpp
+++ b/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -64,6 +64,11 @@ QNetworkRequest ResourceRequest::toNetworkRequest(QObject* originatingFrame) con
request.setRawHeader(name, "");
}
+ // Make sure we always have an Accept header; some sites require this to
+ // serve subresources
+ if (!request.hasRawHeader("Accept"))
+ request.setRawHeader("Accept", "*/*");
+
switch (cachePolicy()) {
case ReloadIgnoringCacheData:
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 96a2f25..dadbd22 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -31,7 +31,7 @@
#include "CString.h"
#include "ChromeClient.h"
#include "CookieJarSoup.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "FileSystem.h"
#include "Frame.h"
#include "GOwnPtrSoup.h"
diff --git a/WebCore/platform/network/soup/SocketStreamHandle.h b/WebCore/platform/network/soup/SocketStreamHandle.h
index 64139e5..2ba4504 100644
--- a/WebCore/platform/network/soup/SocketStreamHandle.h
+++ b/WebCore/platform/network/soup/SocketStreamHandle.h
@@ -32,8 +32,8 @@
#ifndef SocketStreamHandle_h
#define SocketStreamHandle_h
+#include "GRefPtr.h"
#include "SocketStreamHandleBase.h"
-
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -48,12 +48,21 @@ namespace WebCore {
static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
virtual ~SocketStreamHandle();
+ void connected(GSocketConnection*, GError*);
+ void readBytes(signed long, GError*);
+ void writeReady();
protected:
virtual int platformSend(const char* data, int length);
virtual void platformClose();
private:
+ PlatformRefPtr<GSocketConnection> m_socketConnection;
+ PlatformRefPtr<GInputStream> m_inputStream;
+ PlatformRefPtr<GOutputStream> m_outputStream;
+ PlatformRefPtr<GSource> m_writeReadySource;
+ char* m_readBuffer;
+
SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
// No authentication for streams per se, but proxy may ask for credentials.
@@ -61,6 +70,8 @@ namespace WebCore {
void receivedCredential(const AuthenticationChallenge&, const Credential&);
void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
void receivedCancellation(const AuthenticationChallenge&);
+ void beginWaitingForSocketWritability();
+ void stopWaitingForSocketWritability();
};
} // namespace WebCore
diff --git a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
index 6aa33fc..d73b499 100644
--- a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
+++ b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
@@ -31,38 +31,161 @@
#include "config.h"
#include "SocketStreamHandle.h"
+#include "CString.h"
+#include "GOwnPtr.h"
#include "KURL.h"
#include "Logging.h"
+#include "NotFound.h"
#include "NotImplemented.h"
+#include "SocketStreamError.h"
#include "SocketStreamHandleClient.h"
+#include "Vector.h"
+#include <gio/gio.h>
+#include <glib.h>
+
+#define READ_BUFFER_SIZE 1024
namespace WebCore {
+// These functions immediately call the similarly named SocketStreamHandle methods.
+static void connectedCallback(GSocketClient*, GAsyncResult*, SocketStreamHandle*);
+static void readReadyCallback(GInputStream*, GAsyncResult*, SocketStreamHandle*);
+static gboolean writeReadyCallback(GSocket*, GIOCondition, SocketStreamHandle*);
+
+// Having a list of active handles means that we do not have to worry about WebCore
+// reference counting in GLib callbacks. Once the handle is off the active handles list
+// we just ignore it in the callback. We avoid a lot of extra checks and tricky
+// situations this way.
+static Vector<SocketStreamHandle*> gActiveHandles;
+bool isActiveHandle(SocketStreamHandle* handle)
+{
+ return gActiveHandles.find(handle) != notFound;
+}
+
+void deactivateHandle(SocketStreamHandle* handle)
+{
+ size_t handleIndex = gActiveHandles.find(handle);
+ if (handleIndex != notFound)
+ gActiveHandles.remove(handleIndex);
+}
+
SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
: SocketStreamHandleBase(url, client)
+ , m_readBuffer(0)
{
- LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
- notImplemented();
+ // No support for SSL sockets yet.
+ if (url.protocolIs("wss"))
+ return;
+ unsigned int port = url.hasPort() ? url.port() : 80;
+
+ gActiveHandles.append(this);
+ PlatformRefPtr<GSocketClient> socketClient = adoptPlatformRef(g_socket_client_new());
+ g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0,
+ reinterpret_cast<GAsyncReadyCallback>(connectedCallback), this);
}
SocketStreamHandle::~SocketStreamHandle()
{
- LOG(Network, "SocketStreamHandle %p delete", this);
+ // If for some reason we were destroyed without closing, ensure that we are deactivated.
+ deactivateHandle(this);
setClient(0);
- notImplemented();
}
-int SocketStreamHandle::platformSend(const char*, int)
+void SocketStreamHandle::connected(GSocketConnection* socketConnection, GError* error)
{
- LOG(Network, "SocketStreamHandle %p platformSend", this);
- notImplemented();
- return 0;
+ if (error) {
+ m_client->didFail(this, SocketStreamError(error->code));
+ return;
+ }
+
+ m_socketConnection = adoptPlatformRef(socketConnection);
+ m_outputStream = g_io_stream_get_output_stream(G_IO_STREAM(m_socketConnection.get()));
+ m_inputStream = g_io_stream_get_input_stream(G_IO_STREAM(m_socketConnection.get()));
+
+ m_readBuffer = new char[READ_BUFFER_SIZE];
+ g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
+ reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);
+
+ // The client can close the handle, potentially removing the last reference.
+ RefPtr<SocketStreamHandle> protect(this);
+ m_state = Open;
+ m_client->didOpen(this);
+ if (!m_socketConnection) // Client closed the connection.
+ return;
+}
+
+void SocketStreamHandle::readBytes(signed long bytesRead, GError* error)
+{
+ if (error) {
+ m_client->didFail(this, SocketStreamError(error->code));
+ return;
+ }
+
+ if (!bytesRead) {
+ close();
+ return;
+ }
+
+ // The client can close the handle, potentially removing the last reference.
+ RefPtr<SocketStreamHandle> protect(this);
+ m_client->didReceiveData(this, m_readBuffer, bytesRead);
+ if (m_inputStream) // The client may have closed the connection.
+ g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
+ reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);
+}
+
+void SocketStreamHandle::writeReady()
+{
+ // We no longer have buffered data, so stop waiting for the socket to be writable.
+ if (!bufferedAmount()) {
+ stopWaitingForSocketWritability();
+ return;
+ }
+
+ sendPendingData();
+}
+
+int SocketStreamHandle::platformSend(const char* data, int length)
+{
+ if (!g_socket_condition_check(g_socket_connection_get_socket(m_socketConnection.get()), G_IO_OUT)) {
+ beginWaitingForSocketWritability();
+ return 0;
+ }
+
+ GOwnPtr<GError> error;
+ gssize written = g_output_stream_write(m_outputStream.get(), data, length, 0, &error.outPtr());
+ if (error) {
+ m_client->didFail(this, SocketStreamError(error->code)); // FIXME: Provide a sensible error.
+ return 0;
+ }
+
+ // If we did not send all the bytes we were given, we know that
+ // SocketStreamHandleBase will need to send more in the future.
+ if (written < length)
+ beginWaitingForSocketWritability();
+
+ return written;
}
void SocketStreamHandle::platformClose()
{
- LOG(Network, "SocketStreamHandle %p platformClose", this);
- notImplemented();
+ // We remove this handle from the active handles list first, to disable all callbacks.
+ deactivateHandle(this);
+ stopWaitingForSocketWritability();
+
+ if (m_socketConnection) {
+ GOwnPtr<GError> error;
+ g_io_stream_close(G_IO_STREAM(m_socketConnection.get()), 0, &error.outPtr());
+ if (error)
+ m_client->didFail(this, SocketStreamError(error->code)); // FIXME: Provide a sensible error.
+ m_socketConnection = 0;
+ }
+
+ m_outputStream = 0;
+ m_inputStream = 0;
+ delete m_readBuffer;
+
+ m_client->didClose(this);
}
void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
@@ -85,4 +208,70 @@ void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
notImplemented();
}
+void SocketStreamHandle::beginWaitingForSocketWritability()
+{
+ if (m_writeReadySource) // Already waiting.
+ return;
+
+ m_writeReadySource = adoptPlatformRef(g_socket_create_source(
+ g_socket_connection_get_socket(m_socketConnection.get()), static_cast<GIOCondition>(G_IO_OUT), 0));
+ g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), this, 0);
+ g_source_attach(m_writeReadySource.get(), 0);
+}
+
+void SocketStreamHandle::stopWaitingForSocketWritability()
+{
+ if (!m_writeReadySource) // Not waiting.
+ return;
+
+ g_source_remove(g_source_get_id(m_writeReadySource.get()));
+ m_writeReadySource = 0;
+}
+
+static void connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandle* handle)
+{
+ // Always finish the connection, even if this SocketStreamHandle was deactivated earlier.
+ GOwnPtr<GError> error;
+ GSocketConnection* socketConnection = g_socket_client_connect_to_host_finish(client, result, &error.outPtr());
+
+ // The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors.
+ if (!isActiveHandle(handle)) {
+ g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr());
+ return;
+ }
+
+ handle->connected(socketConnection, error.get());
+}
+
+static void readReadyCallback(GInputStream* stream, GAsyncResult* result, SocketStreamHandle* handle)
+{
+ // Always finish the read, even if this SocketStreamHandle was deactivated earlier.
+ GOwnPtr<GError> error;
+ gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr());
+
+ if (!isActiveHandle(handle))
+ return;
+ handle->readBytes(bytesRead, error.get());
+}
+
+static gboolean writeReadyCallback(GSocket*, GIOCondition condition, SocketStreamHandle* handle)
+{
+ if (!isActiveHandle(handle))
+ return FALSE;
+
+ // G_IO_HUP and G_IO_ERR are are always active. See:
+ // http://library.gnome.org/devel/gio/stable/GSocket.html#g-socket-create-source
+ if (condition & G_IO_HUP) {
+ handle->close();
+ return FALSE;
+ }
+ if (condition & G_IO_ERR) {
+ handle->client()->didFail(handle, SocketStreamError(0)); // FIXME: Provide a sensible error.
+ return FALSE;
+ }
+ if (condition & G_IO_OUT)
+ handle->writeReady();
+ return TRUE;
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/network/win/ResourceHandleWin.cpp b/WebCore/platform/network/win/ResourceHandleWin.cpp
index 3dabd91..2af03c0 100644
--- a/WebCore/platform/network/win/ResourceHandleWin.cpp
+++ b/WebCore/platform/network/win/ResourceHandleWin.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "ResourceHandle.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "Frame.h"
#include "FrameLoader.h"
diff --git a/WebCore/platform/qt/ClipboardQt.cpp b/WebCore/platform/qt/ClipboardQt.cpp
index f677d28..6cbde0c 100644
--- a/WebCore/platform/qt/ClipboardQt.cpp
+++ b/WebCore/platform/qt/ClipboardQt.cpp
@@ -315,7 +315,7 @@ void ClipboardQt::writeRange(Range* range, Frame* frame)
if (!m_writableData)
m_writableData = new QMimeData;
- QString text = frame->selectedText();
+ QString text = frame->editor()->selectedText();
text.replace(QChar(0xa0), QLatin1Char(' '));
m_writableData->setText(text);
m_writableData->setHtml(createMarkup(range, 0, AnnotateForInterchange, false, AbsoluteURLs));
diff --git a/WebCore/platform/qt/PasteboardQt.cpp b/WebCore/platform/qt/PasteboardQt.cpp
index fc53124..ac54fdb 100644
--- a/WebCore/platform/qt/PasteboardQt.cpp
+++ b/WebCore/platform/qt/PasteboardQt.cpp
@@ -61,7 +61,7 @@ Pasteboard* Pasteboard::generalPasteboard()
void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
QMimeData* md = new QMimeData;
- QString text = frame->selectedText();
+ QString text = frame->editor()->selectedText();
text.replace(QChar(0xa0), QLatin1Char(' '));
md->setText(text);
diff --git a/WebCore/platform/qt/ScrollbarQt.cpp b/WebCore/platform/qt/ScrollbarQt.cpp
index 85dc107..a517064 100644
--- a/WebCore/platform/qt/ScrollbarQt.cpp
+++ b/WebCore/platform/qt/ScrollbarQt.cpp
@@ -76,11 +76,11 @@ bool Scrollbar::contextMenu(const PlatformMouseEvent& event)
const QPoint pos = convertFromContainingWindow(event.pos());
moveThumb(horizontal ? pos.x() : pos.y());
} else if (actionSelected == actScrollTop)
- setValue(0);
+ scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByDocument);
else if (actionSelected == actScrollBottom)
- setValue(maximum());
+ scroll(horizontal ? ScrollRight : ScrollDown, ScrollByDocument);
else if (actionSelected == actPageUp)
- scroll(horizontal ? ScrollLeft: ScrollUp, ScrollByPage);
+ scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByPage);
else if (actionSelected == actPageDown)
scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage);
else if (actionSelected == actScrollUp)
diff --git a/WebCore/platform/text/CharacterNames.h b/WebCore/platform/text/CharacterNames.h
index f06246c..9f8f807 100644
--- a/WebCore/platform/text/CharacterNames.h
+++ b/WebCore/platform/text/CharacterNames.h
@@ -52,6 +52,7 @@ const UChar leftSingleQuotationMark = 0x2018;
const UChar leftToRightEmbed = 0x202A;
const UChar leftToRightMark = 0x200E;
const UChar leftToRightOverride = 0x202D;
+const UChar minusSign = 0x2212;
const UChar newlineCharacter = 0x000A;
const UChar noBreakSpace = 0x00A0;
const UChar objectReplacementCharacter = 0xFFFC;
diff --git a/WebCore/platform/text/wince/TextCodecWinCE.cpp b/WebCore/platform/text/wince/TextCodecWinCE.cpp
index 578f789..2789148 100644
--- a/WebCore/platform/text/wince/TextCodecWinCE.cpp
+++ b/WebCore/platform/text/wince/TextCodecWinCE.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "TextCodecWinCE.h"
-#include "ce_textcodecs.h"
#include "FontCache.h"
#include "PlatformString.h"
#include <mlang.h>
@@ -43,7 +42,6 @@ struct CharsetInfo {
String m_friendlyName;
UINT m_codePage;
Vector<CString> m_aliases;
- bool m_usesNativeCodec;
};
class LanguageManager {
@@ -82,45 +80,8 @@ static LanguageManager& languageManager()
return lm;
}
-static void addCharset(UINT codePage, const char* charsetName, const wchar_t* friendlyName, const char* charsetAliases, bool nativeSupport = false)
-{
- CharsetInfo info;
- info.m_codePage = codePage;
- info.m_name = charsetName;
- info.m_friendlyName = friendlyName;
- info.m_usesNativeCodec = nativeSupport;
- const char* begin = charsetAliases;
- for (;;) {
- const char* end = strchr(begin, '|');
- CString alias = end ? CString(begin, end - begin) : begin;
- if (alias.length())
- info.m_aliases.append(alias);
- if (!end)
- break;
- begin = end + 1;
- }
- knownCharsets().set(info.m_name.data(), info);
- if (codePage != CP_ACP)
- codePageCharsets().set(codePage, info.m_name);
-}
-
LanguageManager::LanguageManager()
{
- // 437, 708, 709, 710, 720, 737, 775, 850, 852
- addCharset(932, "SHIFT_JIS", L"Japanese (SHIFT_JIS)", "shift_jis");
- addCharset(936, "GBK", L"Chinese Simplified (GBK)", "gbk|gb2312");
- addCharset(949, "KSC5601", L"Korean (KSC5601)", "ks_c_5601-1987|ksc5601|euc-kr|euckr|x-euc-kr");
- addCharset(950, "BIG5", L"Chinese Traditional (BIG5)", "big5");
- addCharset(1361, "JOHAB", L"Korean (Johab)", "johab|korean.johab");
- addCharset(51932, "EUC-JP", L"Japanese (EUC)", "euc-jp|eucjp|x-euc-jp", true);
- addCharset(874, "CP874", L"Thai (Windows)", "cp874|windows-874", true);
- addCharset(CP_ACP, "TIS620", L"Thai (TIS 620)", "tis620|ISO-8859-11|ISO-IR-166|TIS-620|TIS620-0TIS620.2529-1|TIS620.2533-0|TIS620.2533-1|thai8", true);
- addCharset(CP_ACP, "MACTHAI", L"Thai (Mac OS)", "macthai|x-mac-thai|mac-thai", true);
- supportedCharsets().add("EUC-JP");
- supportedCharsets().add("CP874");
- supportedCharsets().add("TIS620");
- supportedCharsets().add("MACTHAI");
-
IEnumCodePage* enumInterface;
IMultiLanguage* mli = FontCache::getMultiLanguageInterface();
if (mli && S_OK == mli->EnumCodePages(MIMECONTF_BROWSER, &enumInterface)) {
@@ -148,7 +109,6 @@ LanguageManager::LanguageManager()
info.m_aliases.append(name);
info.m_aliases.append(String(cpInfo.wszHeaderCharset).latin1());
info.m_aliases.append(String(cpInfo.wszBodyCharset).latin1());
- info.m_usesNativeCodec = false;
String cpName = String::format("cp%d", cpInfo.uiCodePage);
info.m_aliases.append(cpName.latin1());
supportedCharsets().add(i->second.data());
@@ -265,52 +225,6 @@ static void decode(Vector<UChar, 8192>& result, const char* encodingName, const
codePage = CP_UTF8;
else
codePage = CP_ACP;
- } else {
- codePage = i->second.m_codePage;
- if (i->second.m_usesNativeCodec) {
- typedef int (*FuncEucMbToWc)(wchar_t *pwc, const unsigned char *s, int n);
- FuncEucMbToWc encMbToWc = 0;
- if (!strcmp(encodingName, "EUC-JP"))
- encMbToWc = TextCodecsCE::euc_jp_mbtowc;
- else if (!strcmp(encodingName, "CP874"))
- encMbToWc = TextCodecsCE::cp874_mbtowc;
- else if (!strcmp(encodingName, "TIS620"))
- encMbToWc = TextCodecsCE::tis620_mbtowc;
- else if (!strcmp(encodingName, "MACTHAI"))
- encMbToWc = TextCodecsCE::mac_thai_mbtowc;
-
- if (encMbToWc) {
- const char* const srcStart = bytes;
- const char* const srcEnd = bytes + length;
- int lastSize = result.size();
- result.resize(lastSize + length);
- for (;;) {
- UChar* dst = result.data() + lastSize;
- const UChar* const dstEnd = result.data() + result.size();
- for (; dst < dstEnd && bytes < srcEnd; ++dst) {
- int numberEncoded = encMbToWc(dst, (const unsigned char*)bytes, srcEnd - bytes);
- if (numberEncoded >= 0)
- bytes += numberEncoded;
- else {
- if (numberEncoded == RET_ILSEQ)
- sawInvalidChar = true;
- break;
- }
- }
- if (bytes == srcEnd || dst != dstEnd) {
- *left = srcEnd - bytes;
- result.resize(dst - result.data());
- return;
- }
- lastSize = result.size();
- result.resize(result.size() + 256);
- }
- } else {
- *left = 0;
- result.append(bytes, length);
- return;
- }
- }
}
DWORD flags = getCodePageFlags(codePage);
diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp
index 2915f9d..6d9930c 100644
--- a/WebCore/platform/win/ClipboardWin.cpp
+++ b/WebCore/platform/win/ClipboardWin.cpp
@@ -776,7 +776,7 @@ void ClipboardWin::writeRange(Range* selectedRange, Frame* frame)
if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
::GlobalFree(medium.hGlobal);
- String str = frame->selectedText();
+ String str = frame->editor()->selectedText();
replaceNewlinesWithWindowsStyleNewlines(str);
replaceNBSPWithSpace(str);
medium.hGlobal = createGlobalData(str);
diff --git a/WebCore/platform/win/PasteboardWin.cpp b/WebCore/platform/win/PasteboardWin.cpp
index c065f04..4b20adb 100644
--- a/WebCore/platform/win/PasteboardWin.cpp
+++ b/WebCore/platform/win/PasteboardWin.cpp
@@ -131,7 +131,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
}
// Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well
- String str = frame->selectedText();
+ String str = frame->editor()->selectedText();
replaceNewlinesWithWindowsStyleNewlines(str);
replaceNBSPWithSpace(str);
if (::OpenClipboard(m_owner)) {
diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp
index 6e22024..a782b03 100644
--- a/WebCore/platform/win/PopupMenuWin.cpp
+++ b/WebCore/platform/win/PopupMenuWin.cpp
@@ -531,12 +531,12 @@ bool PopupMenuWin::scrollToRevealSelection()
int index = focusedIndex();
if (index < m_scrollOffset) {
- m_scrollbar->setValue(index);
+ m_scrollbar->setValue(index, Scrollbar::NotFromScrollAnimator);
return true;
}
if (index >= m_scrollOffset + visibleItems()) {
- m_scrollbar->setValue(index - visibleItems() + 1);
+ m_scrollbar->setValue(index - visibleItems() + 1, Scrollbar::NotFromScrollAnimator);
return true;
}
@@ -664,6 +664,17 @@ void PopupMenuWin::paint(const IntRect& damageRect, HDC hdc)
::ReleaseDC(m_popup, localDC);
}
+int PopupMenuWin::scrollSize(ScrollbarOrientation orientation) const
+{
+ return ((orientation == VerticalScrollbar) && m_scrollbar) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
+}
+
+void PopupMenuWin::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+ if (m_scrollbar)
+ m_scrollbar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void PopupMenuWin::valueChanged(Scrollbar* scrollBar)
{
ASSERT(m_scrollbar);
diff --git a/WebCore/platform/win/PopupMenuWin.h b/WebCore/platform/win/PopupMenuWin.h
index d4a4255..bfec7aa 100644
--- a/WebCore/platform/win/PopupMenuWin.h
+++ b/WebCore/platform/win/PopupMenuWin.h
@@ -91,6 +91,8 @@ private:
void setScrollbarCapturingMouse(bool b) { m_scrollbarCapturingMouse = b; }
// ScrollBarClient
+ virtual int scrollSize(ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&);
virtual void valueChanged(Scrollbar*);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
virtual bool isActive() const { return true; }
diff --git a/WebCore/platform/win/ScrollbarThemeWin.cpp b/WebCore/platform/win/ScrollbarThemeWin.cpp
index a8d374a..ff3aaa4 100644
--- a/WebCore/platform/win/ScrollbarThemeWin.cpp
+++ b/WebCore/platform/win/ScrollbarThemeWin.cpp
@@ -27,6 +27,7 @@
#include "ScrollbarThemeWin.h"
#include "GraphicsContext.h"
+#include "LocalWindowsContext.h"
#include "PlatformMouseEvent.h"
#include "Scrollbar.h"
#include "SoftLinking.h"
@@ -240,14 +241,17 @@ void ScrollbarThemeWin::paintTrackPiece(GraphicsContext* context, Scrollbar* scr
bool alphaBlend = false;
if (scrollbarTheme)
alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state);
- HDC hdc = context->getWindowsContext(rect, alphaBlend);
+
+ LocalWindowsContext windowsContext(context, rect, alphaBlend);
RECT themeRect(rect);
+
if (scrollbarTheme)
- DrawThemeBackground(scrollbarTheme, hdc, part, state, &themeRect, 0);
+ DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), part, state, &themeRect, 0);
else {
DWORD color3DFace = ::GetSysColor(COLOR_3DFACE);
DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
DWORD colorWindow = ::GetSysColor(COLOR_WINDOW);
+ HDC hdc = windowsContext.hdc();
if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar))
::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1));
else {
@@ -265,7 +269,6 @@ void ScrollbarThemeWin::paintTrackPiece(GraphicsContext* context, Scrollbar* scr
::DeleteObject(patternBitmap);
}
}
- context->releaseWindowsContext(hdc, rect, alphaBlend);
}
void ScrollbarThemeWin::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
@@ -308,14 +311,13 @@ void ScrollbarThemeWin::paintButton(GraphicsContext* context, Scrollbar* scrollb
bool alphaBlend = false;
if (scrollbarTheme)
alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState);
- HDC hdc = context->getWindowsContext(rect, alphaBlend);
+ LocalWindowsContext windowsContext(context, rect, alphaBlend);
RECT themeRect(rect);
if (scrollbarTheme)
- DrawThemeBackground(scrollbarTheme, hdc, SP_BUTTON, xpState, &themeRect, 0);
+ DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), SP_BUTTON, xpState, &themeRect, 0);
else
- ::DrawFrameControl(hdc, &themeRect, DFC_SCROLL, classicState);
- context->releaseWindowsContext(hdc, rect, alphaBlend);
+ ::DrawFrameControl(windowsContext.hdc(), &themeRect, DFC_SCROLL, classicState);
}
static IntRect gripperRect(int thickness, const IntRect& thumbRect)
diff --git a/WebCore/plugins/PluginDatabase.cpp b/WebCore/plugins/PluginDatabase.cpp
index 77c84eb..2426f78 100644
--- a/WebCore/plugins/PluginDatabase.cpp
+++ b/WebCore/plugins/PluginDatabase.cpp
@@ -517,7 +517,7 @@ static bool readTime(time_t& resultTime, char*& start, const char* end)
if (start + sizeof(time_t) >= end)
return false;
- resultTime = *reinterpret_cast<time_t*>(start);
+ resultTime = *reinterpret_cast_ptr<time_t*>(start);
start += sizeof(time_t);
return true;
diff --git a/WebCore/plugins/PluginPackage.cpp b/WebCore/plugins/PluginPackage.cpp
index 168d45a..660d8f0 100644
--- a/WebCore/plugins/PluginPackage.cpp
+++ b/WebCore/plugins/PluginPackage.cpp
@@ -221,6 +221,13 @@ void PluginPackage::determineQuirks(const String& mimeType)
m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages);
m_quirks.add(PluginQuirkFlashURLNotifyBug);
}
+
+#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
+ // Passing a 32-bit depth pixmap to NPAPI plugins is too inefficient. Instead, pass a X Pixmap
+ // that has same depth as the screen depth since graphics operations are optimized
+ // for this depth.
+ m_quirks.add(PluginQuirkRequiresDefaultScreenDepth);
+#endif
}
#endif
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index d410948..c657523 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -182,9 +182,9 @@ void PluginView::handleEvent(Event* event)
handleFocusEvent(true);
#endif
#if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API)
- else if (event->type() == eventNames().DOMFocusOutEvent)
+ else if (event->type() == eventNames().DOMFocusOutEvent || event->type() == eventNames().focusoutEvent)
handleFocusOutEvent();
- else if (event->type() == eventNames().DOMFocusInEvent)
+ else if (event->type() == eventNames().DOMFocusInEvent || event->type() == eventNames().focusinEvent)
handleFocusInEvent();
#endif
}
@@ -562,7 +562,7 @@ NPError PluginView::load(const FrameLoadRequest& frameLoadRequest, bool sendNoti
// For security reasons, only allow JS requests to be made on the frame that contains the plug-in.
if (!targetFrameName.isNull() && m_parentFrame->tree()->find(targetFrameName) != m_parentFrame)
return NPERR_INVALID_PARAM;
- } else if (!SecurityOrigin::canLoad(url, String(), m_parentFrame->document()))
+ } else if (!SecurityOrigin::canDisplay(url, String(), m_parentFrame->document()))
return NPERR_GENERIC_ERROR;
PluginRequest* request = new PluginRequest(frameLoadRequest, sendNotification, notifyData, arePopupsAllowed());
diff --git a/WebCore/plugins/gtk/PluginViewGtk.cpp b/WebCore/plugins/gtk/PluginViewGtk.cpp
index ab43bf4..6d631e3 100644
--- a/WebCore/plugins/gtk/PluginViewGtk.cpp
+++ b/WebCore/plugins/gtk/PluginViewGtk.cpp
@@ -33,6 +33,7 @@
#include "Document.h"
#include "DocumentLoader.h"
#include "Element.h"
+#include "FocusController.h"
#include "FrameLoader.h"
#include "FrameLoadRequest.h"
#include "FrameTree.h"
@@ -299,6 +300,7 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event)
NPEvent xEvent;
#if defined(XP_UNIX)
+ initXEvent(&xEvent);
GdkEventKey* gdkEvent = event->keyEvent()->gdkEventKey();
xEvent.type = (event->type() == eventNames().keydownEvent) ? 2 : 3; // KeyPress/Release get unset somewhere
@@ -306,7 +308,7 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event)
xEvent.xkey.subwindow = 0; // we have no child window
xEvent.xkey.time = event->timeStamp();
xEvent.xkey.state = gdkEvent->state; // GdkModifierType mirrors xlib state masks
- xEvent.xkey.keycode = gdkEvent->hardware_keycode;
+ xEvent.xkey.keycode = gdkEvent->keyval;
xEvent.xkey.same_screen = true;
// NOTE: As the XEvents sent to the plug-in are synthesized and there is not a native window
@@ -421,6 +423,12 @@ void PluginView::handleMouseEvent(MouseEvent* event)
if (m_isWindowed)
return;
+ if (event->type() == eventNames().mousedownEvent) {
+ if (Page* page = m_parentFrame->page())
+ page->focusController()->setActive(true);
+ focusPluginElement();
+ }
+
NPEvent xEvent;
#if defined(XP_UNIX)
initXEvent(&xEvent);
diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp
index f60885d..e2df392 100644
--- a/WebCore/plugins/qt/PluginViewQt.cpp
+++ b/WebCore/plugins/qt/PluginViewQt.cpp
@@ -154,13 +154,6 @@ void PluginView::setFocus(bool focused)
} else {
Widget::setFocus(focused);
}
- if (!m_isWindowed) {
- XEvent npEvent;
- initXEvent(&npEvent);
- npEvent.type = (focused) ? 9 : 10; // ints as Qt unsets FocusIn and FocusOut
- if (!dispatchNPEvent(npEvent))
- LOG(Events, "PluginView::setFocus(%d): Focus event not accepted", focused);
- }
}
void PluginView::show()
diff --git a/WebCore/plugins/win/PluginViewWin.cpp b/WebCore/plugins/win/PluginViewWin.cpp
index 8dbb04b..84d2984 100644
--- a/WebCore/plugins/win/PluginViewWin.cpp
+++ b/WebCore/plugins/win/PluginViewWin.cpp
@@ -50,6 +50,7 @@
#include "JSDOMBinding.h"
#include "JSDOMWindow.h"
#include "KeyboardEvent.h"
+#include "LocalWindowsContext.h"
#include "MIMETypeRegistry.h"
#include "MouseEvent.h"
#include "Page.h"
@@ -563,7 +564,7 @@ void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const
ASSERT(parent()->isFrameView());
IntPoint locationInWindow = static_cast<FrameView*>(parent())->contentsToWindow(frameRect().location());
- HDC hdc = context->getWindowsContext(frameRect(), false);
+ LocalWindowsContext windowsContext(context, frameRect(), false);
#if PLATFORM(CAIRO)
// Must flush drawings up to this point to the backing metafile, otherwise the
@@ -573,6 +574,7 @@ void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const
cairo_show_page(ctx);
#endif
+ HDC hdc = windowsContext.hdc();
XFORM originalTransform;
GetWorldTransform(hdc, &originalTransform);
@@ -587,8 +589,6 @@ void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const
paintIntoTransformedContext(hdc);
SetWorldTransform(hdc, &originalTransform);
-
- context->releaseWindowsContext(hdc, frameRect(), false);
#endif
}
@@ -617,7 +617,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
ASSERT(parent()->isFrameView());
IntRect rectInWindow = static_cast<FrameView*>(parent())->contentsToWindow(frameRect());
- HDC hdc = context->getWindowsContext(rectInWindow, m_isTransparent);
+ LocalWindowsContext windowsContext(context, rectInWindow, m_isTransparent);
// On Safari/Windows without transparency layers the GraphicsContext returns the HDC
// of the window and the plugin expects that the passed in DC has window coordinates.
@@ -626,16 +626,14 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
#if !PLATFORM(QT) && !OS(WINCE)
if (!context->inTransparencyLayer()) {
XFORM transform;
- GetWorldTransform(hdc, &transform);
+ GetWorldTransform(windowsContext.hdc(), &transform);
transform.eDx = 0;
transform.eDy = 0;
- SetWorldTransform(hdc, &transform);
+ SetWorldTransform(windowsContext.hdc(), &transform);
}
#endif
- paintIntoTransformedContext(hdc);
-
- context->releaseWindowsContext(hdc, frameRect(), m_isTransparent);
+ paintIntoTransformedContext(windowsContext.hdc());
}
void PluginView::handleKeyboardEvent(KeyboardEvent* event)
diff --git a/WebCore/rendering/ColumnInfo.h b/WebCore/rendering/ColumnInfo.h
new file mode 100644
index 0000000..883287b
--- /dev/null
+++ b/WebCore/rendering/ColumnInfo.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ColumnInfo_h
+#define ColumnInfo_h
+
+#include <wtf/Vector.h>
+#include "IntRect.h"
+
+namespace WebCore {
+
+class ColumnInfo : public Noncopyable {
+public:
+ ColumnInfo()
+ : m_desiredColumnWidth(0)
+ , m_desiredColumnCount(1)
+ { }
+
+ int desiredColumnWidth() const { return m_desiredColumnWidth; }
+ void setDesiredColumnWidth(int width) { m_desiredColumnWidth = width; }
+
+ unsigned desiredColumnCount() const { return m_desiredColumnCount; }
+ void setDesiredColumnCount(unsigned count) { m_desiredColumnCount = count; }
+
+ // Encapsulated for the future where we can avoid storing the rects and just compute them dynamically.
+ size_t columnCount() const { return m_columnRects.size(); }
+ const IntRect& columnRectAt(size_t i) const { return m_columnRects[i]; }
+
+ void clearColumns() { m_columnRects.clear(); }
+
+ // FIXME: Will go away once we don't use the Vector.
+ void addColumnRect(const IntRect& rect) { m_columnRects.append(rect); }
+
+private:
+ int m_desiredColumnWidth;
+ unsigned m_desiredColumnCount;
+ Vector<IntRect> m_columnRects;
+};
+
+}
+
+#endif
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index c74fe1e..eb5947c 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -866,7 +866,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, co
renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
- if (renderer()->frame()->markedTextMatchesAreHighlighted()) {
+ if (renderer()->frame()->editor()->markedTextMatchesAreHighlighted()) {
Color color = marker.activeMatch ?
renderer()->theme()->platformActiveTextSearchHighlightColor() :
renderer()->theme()->platformInactiveTextSearchHighlightColor();
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index d66336d..52f5c52 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "RenderBlock.h"
+#include "ColumnInfo.h"
#include "Document.h"
#include "Element.h"
#include "FloatQuad.h"
@@ -65,16 +66,6 @@ static const int verticalLineClickFudgeFactor = 3;
using namespace HTMLNames;
-struct ColumnInfo : public Noncopyable {
- ColumnInfo()
- : m_desiredColumnWidth(0)
- , m_desiredColumnCount(1)
- { }
- int m_desiredColumnWidth;
- unsigned m_desiredColumnCount;
- Vector<IntRect> m_columnRects;
-};
-
typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
static ColumnInfoMap* gColumnInfoMap = 0;
@@ -2020,13 +2011,13 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
return;
// We need to do multiple passes, breaking up our child painting into strips.
- Vector<IntRect>* colRects = columnRects();
- unsigned colCount = colRects->size();
+ ColumnInfo* colInfo = columnInfo();
+ unsigned colCount = colInfo->columnCount();
int currXOffset = style()->direction() == LTR ? 0 : contentWidth();
int ruleAdd = borderLeft() + paddingLeft();
int ruleX = style()->direction() == LTR ? 0 : contentWidth();
for (unsigned i = 0; i < colCount; i++) {
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
// Move to the next position.
if (style()->direction() == LTR) {
@@ -2056,15 +2047,15 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool
// We need to do multiple passes, breaking up our child painting into strips.
GraphicsContext* context = paintInfo.context;
int colGap = columnGap();
- Vector<IntRect>* colRects = columnRects();
- unsigned colCount = colRects->size();
+ ColumnInfo* colInfo = columnInfo();
+ unsigned colCount = colInfo->columnCount();
if (!colCount)
return;
- int currXOffset = style()->direction() == LTR ? 0 : contentWidth() - colRects->at(0).width();
+ int currXOffset = style()->direction() == LTR ? 0 : contentWidth() - colInfo->columnRectAt(0).width();
int currYOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
colRect.move(tx, ty);
PaintInfo info(paintInfo);
info.rect.intersect(colRect);
@@ -3181,9 +3172,9 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
}
if (hasColumns()) {
- Vector<IntRect>* colRects = columnRects();
- for (unsigned i = 0; i < colRects->size(); i++)
- bottom = max(bottom, colRects->at(i).bottom() + relativeOffset);
+ ColumnInfo* colInfo = columnInfo();
+ for (unsigned i = 0; i < colInfo->columnCount(); i++)
+ bottom = max(bottom, colInfo->columnRectAt(i).bottom() + relativeOffset);
return bottom;
}
@@ -3275,8 +3266,11 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
if (hasColumns()) {
// This only matters for LTR
- if (style()->direction() == LTR)
- right = max(columnRects()->last().right() + relativeOffset, right);
+ if (style()->direction() == LTR) {
+ ColumnInfo* colInfo = columnInfo();
+ if (colInfo->columnCount())
+ right = max(colInfo->columnRectAt(colInfo->columnCount() - 1).right() + relativeOffset, right);
+ }
return right;
}
@@ -3372,8 +3366,11 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
if (hasColumns()) {
// This only matters for RTL
- if (style()->direction() == RTL)
- left = min(columnRects()->last().x() + relativeOffset, left);
+ if (style()->direction() == RTL) {
+ ColumnInfo* colInfo = columnInfo();
+ if (colInfo->columnCount())
+ left = min(colInfo->columnRectAt(colInfo->columnCount() - 1).x() + relativeOffset, left);
+ }
return left;
}
@@ -3809,37 +3806,17 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
// Hit test contents if we don't have columns.
- if (!hasColumns() && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
- updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
- return true;
- }
-
- // Hit test our columns if we do have them.
- if (hasColumns() && hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
+ if (!hasColumns()) {
+ if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
+ updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+ return true;
+ }
+ if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
+ return true;
+ } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
return true;
}
-
- // Hit test floats.
- if (hitTestAction == HitTestFloat && m_floatingObjects) {
- if (isRenderView()) {
- scrolledX += toRenderView(this)->frameView()->scrollX();
- scrolledY += toRenderView(this)->frameView()->scrollY();
- }
-
- FloatingObject* o;
- DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
- for (it.toLast(); (o = it.current()); --it) {
- if (o->m_shouldPaint && !o->m_renderer->hasSelfPaintingLayer()) {
- int xoffset = scrolledX + o->m_left + o->m_renderer->marginLeft() - o->m_renderer->x();
- int yoffset = scrolledY + o->m_top + o->m_renderer->marginTop() - o->m_renderer->y();
- if (o->m_renderer->hitTest(request, result, IntPoint(_x, _y), xoffset, yoffset)) {
- updateHitTestResult(result, IntPoint(_x - xoffset, _y - yoffset));
- return true;
- }
- }
- }
- }
}
// Now hit test our background
@@ -3855,20 +3832,46 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
return false;
}
+bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
+{
+ if (!m_floatingObjects)
+ return false;
+
+ if (isRenderView()) {
+ tx += toRenderView(this)->frameView()->scrollX();
+ ty += toRenderView(this)->frameView()->scrollY();
+ }
+
+ FloatingObject* floatingObject;
+ DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
+ for (it.toLast(); (floatingObject = it.current()); --it) {
+ if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
+ int xOffset = tx + floatingObject->m_left + floatingObject->m_renderer->marginLeft() - floatingObject->m_renderer->x();
+ int yOffset = ty + floatingObject->m_top + floatingObject->m_renderer->marginTop() - floatingObject->m_renderer->y();
+ if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), xOffset, yOffset)) {
+ updateHitTestResult(result, IntPoint(x - xOffset, y - yOffset));
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
// We need to do multiple passes, breaking up our hit testing into strips.
- Vector<IntRect>* colRects = columnRects();
- int colCount = colRects->size();
+ ColumnInfo* colInfo = columnInfo();
+ int colCount = colInfo->columnCount();
if (!colCount)
return false;
int left = borderLeft() + paddingLeft();
int currYOffset = 0;
int i;
for (i = 0; i < colCount; i++)
- currYOffset -= colRects->at(i).height();
+ currYOffset -= colInfo->columnRectAt(i).height();
for (i = colCount - 1; i >= 0; i--) {
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
int currXOffset = colRect.x() - left;
currYOffset += colRect.height();
colRect.move(tx, ty);
@@ -3882,7 +3885,7 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
if (result.isRectBasedTest() && !colRect.contains(result.rectFromPoint(x, y)))
hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
else
- return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
+ return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
}
}
@@ -4180,8 +4183,8 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
gColumnInfoMap->add(this, info);
setHasColumns(true);
}
- info->m_desiredColumnCount = count;
- info->m_desiredColumnWidth = width;
+ info->setDesiredColumnCount(count);
+ info->setDesiredColumnWidth(width);
}
}
@@ -4189,21 +4192,21 @@ int RenderBlock::desiredColumnWidth() const
{
if (!hasColumns())
return contentWidth();
- return gColumnInfoMap->get(this)->m_desiredColumnWidth;
+ return gColumnInfoMap->get(this)->desiredColumnWidth();
}
unsigned RenderBlock::desiredColumnCount() const
{
if (!hasColumns())
return 1;
- return gColumnInfoMap->get(this)->m_desiredColumnCount;
+ return gColumnInfoMap->get(this)->desiredColumnCount();
}
-Vector<IntRect>* RenderBlock::columnRects() const
+ColumnInfo* RenderBlock::columnInfo() const
{
if (!hasColumns())
return 0;
- return &gColumnInfoMap->get(this)->m_columnRects;
+ return gColumnInfoMap->get(this);
}
int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
@@ -4213,9 +4216,8 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
return -1;
ColumnInfo* info = gColumnInfoMap->get(this);
- int desiredColumnWidth = info->m_desiredColumnWidth;
- int desiredColumnCount = info->m_desiredColumnCount;
- Vector<IntRect>* columnRects = &info->m_columnRects;
+ int desiredColumnWidth = info->desiredColumnWidth();
+ int desiredColumnCount = info->desiredColumnCount();
bool computeIntrinsicHeight = (endOfContent == -1);
@@ -4236,7 +4238,7 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
int colGap = columnGap();
// Compute a collection of column rects.
- columnRects->clear();
+ info->clearColumns();
// Then we do a simulated "paint" into the column slices and allow the content to slightly adjust our individual column rects.
// FIXME: We need to take into account layers that are affected by the columns as well here so that they can have an opportunity
@@ -4305,7 +4307,7 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
maxColBottom = max(colRect.bottom(), maxColBottom);
- columnRects->append(colRect);
+ info->addColumnRect(colRect);
// Start adding in more columns as long as there's still content left.
if (currY < endOfContent && i == colCount - 1 && (computeIntrinsicHeight || contentHeight()))
@@ -4331,7 +4333,7 @@ int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
v->setPrintRect(IntRect());
v->setTruncatedAt(0);
- ASSERT(colCount == columnRects->size());
+ ASSERT(colCount == info->columnCount());
return contentBottom;
}
@@ -4342,16 +4344,18 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
if (!hasColumns())
return;
- Vector<IntRect>* colRects = columnRects();
+ ColumnInfo* colInfo = columnInfo();
+ if (!colInfo->columnCount())
+ return;
// Determine which columns we intersect.
int colGap = columnGap();
int leftGap = colGap / 2;
- IntPoint columnPoint(colRects->at(0).location());
+ IntPoint columnPoint(colInfo->columnRectAt(0).location());
int yOffset = 0;
- for (unsigned i = 0; i < colRects->size(); i++) {
+ for (unsigned i = 0; i < colInfo->columnCount(); i++) {
// Add in half the column gap to the left and right of the rect.
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.right()) {
@@ -4383,13 +4387,13 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
if (!hasColumns())
return;
- Vector<IntRect>* colRects = columnRects();
+ ColumnInfo* colInfo = columnInfo();
// Begin with a result rect that is empty.
IntRect result;
// Determine which columns we intersect.
- unsigned colCount = colRects->size();
+ unsigned colCount = colInfo->columnCount();
if (!colCount)
return;
@@ -4397,7 +4401,7 @@ void RenderBlock::adjustRectForColumns(IntRect& r) const
int currYOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
int currXOffset = colRect.x() - left;
IntRect repaintRect = r;
@@ -4419,13 +4423,13 @@ void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
if (!hasColumns())
return;
- Vector<IntRect>& columnRects = *this->columnRects();
-
+ ColumnInfo* colInfo = columnInfo();
+
int left = borderLeft() + paddingLeft();
int yOffset = 0;
- size_t columnCount = columnRects.size();
+ size_t columnCount = colInfo->columnCount();
for (size_t i = 0; i < columnCount; ++i) {
- IntRect columnRect = columnRects[i];
+ IntRect columnRect = colInfo->columnRectAt(i);
int xOffset = columnRect.x() - left;
if (point.y() < columnRect.bottom() + yOffset) {
offset.expand(xOffset, -yOffset);
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 95d0c29..6ed0d7b 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -32,6 +32,7 @@
namespace WebCore {
+class ColumnInfo;
class InlineIterator;
class RenderInline;
@@ -148,7 +149,7 @@ public:
static void appendRunsForObject(int start, int end, RenderObject*, InlineBidiResolver&);
static bool requiresLineBox(const InlineIterator&, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
- Vector<IntRect>* columnRects() const;
+ ColumnInfo* columnInfo() const;
int columnGap() const;
protected:
@@ -352,6 +353,7 @@ private:
int leftOffset() const;
virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+ bool hitTestFloats(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty);
diff --git a/WebCore/rendering/RenderDataGrid.cpp b/WebCore/rendering/RenderDataGrid.cpp
index 916d253..63a21cd 100644
--- a/WebCore/rendering/RenderDataGrid.cpp
+++ b/WebCore/rendering/RenderDataGrid.cpp
@@ -170,6 +170,17 @@ void RenderDataGrid::paintColumnHeader(DataGridColumn*, PaintInfo&, int, int)
}
// Scrolling implementation functions
+int RenderDataGrid::scrollSize(ScrollbarOrientation orientation) const
+{
+ return ((orientation == VerticallScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
+}
+
+void RenderDataGrid::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+ if (m_vBar)
+ m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void RenderDataGrid::valueChanged(Scrollbar*)
{
// FIXME: Implement.
diff --git a/WebCore/rendering/RenderDataGrid.h b/WebCore/rendering/RenderDataGrid.h
index ce221ea..c4b54df 100644
--- a/WebCore/rendering/RenderDataGrid.h
+++ b/WebCore/rendering/RenderDataGrid.h
@@ -67,6 +67,8 @@ private:
HTMLDataGridElement* gridElement() const { return static_cast<HTMLDataGridElement*>(node()); }
// ScrollbarClient interface.
+ virtual int scrollSize(ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&);
virtual void valueChanged(Scrollbar*);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
virtual bool isActive() const;
diff --git a/WebCore/rendering/RenderEmbeddedObject.cpp b/WebCore/rendering/RenderEmbeddedObject.cpp
index b1b253a..d08174d 100644
--- a/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -102,275 +102,6 @@ bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
}
#endif
-// FIXME: This belongs in HTMLPluginElement.cpp to be shared by HTMLObjectElement and HTMLEmbedElement.
-static bool isURLAllowed(Document* doc, const String& url)
-{
- if (doc->frame()->page()->frameCount() >= Page::maxNumberOfFrames)
- return false;
-
- // We allow one level of self-reference because some sites depend on that.
- // But we don't allow more than one.
- KURL completeURL = doc->completeURL(url);
- bool foundSelfReference = false;
- for (Frame* frame = doc->frame(); frame; frame = frame->tree()->parent()) {
- if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
- if (foundSelfReference)
- return false;
- foundSelfReference = true;
- }
- }
- return true;
-}
-
-typedef HashMap<String, String, CaseFoldingHash> ClassIdToTypeMap;
-
-// FIXME: This belongs in HTMLObjectElement.cpp
-static ClassIdToTypeMap* createClassIdToTypeMap()
-{
- ClassIdToTypeMap* map = new ClassIdToTypeMap;
- map->add("clsid:D27CDB6E-AE6D-11CF-96B8-444553540000", "application/x-shockwave-flash");
- map->add("clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA", "audio/x-pn-realaudio-plugin");
- map->add("clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B", "video/quicktime");
- map->add("clsid:166B1BCA-3F9C-11CF-8075-444553540000", "application/x-director");
- map->add("clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6", "application/x-mplayer2");
- map->add("clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95", "application/x-mplayer2");
- return map;
-}
-
-// FIXME: This belongs in HTMLObjectElement.cpp
-static String serviceTypeForClassId(const String& classId)
-{
- // Return early if classId is empty (since we won't do anything below).
- // Furthermore, if classId is null, calling get() below will crash.
- if (classId.isEmpty())
- return String();
-
- static ClassIdToTypeMap* map = createClassIdToTypeMap();
- return map->get(classId);
-}
-
-// FIXME: This belongs in HTMLObjectElement.cpp
-static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
-{
- // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
- // require "src" attribute).
- int srcIndex = -1, dataIndex = -1;
- for (unsigned int i = 0; i < paramNames->size(); ++i) {
- if (equalIgnoringCase((*paramNames)[i], "src"))
- srcIndex = i;
- else if (equalIgnoringCase((*paramNames)[i], "data"))
- dataIndex = i;
- }
-
- if (srcIndex == -1 && dataIndex != -1) {
- paramNames->append("src");
- paramValues->append((*paramValues)[dataIndex]);
- }
-}
-
-// FIXME: This belongs in some loader header?
-static bool isNetscapePlugin(Frame* frame, const String& url, const String& serviceType)
-{
- KURL completedURL;
- if (!url.isEmpty())
- completedURL = frame->loader()->completeURL(url);
-
- if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
- return true;
- return false;
-}
-
-// FIXME: This belongs on HTMLObjectElement.
-static bool hasFallbackContent(HTMLObjectElement* objectElement)
-{
- for (Node* child = objectElement->firstChild(); child; child = child->nextSibling()) {
- if ((!child->isTextNode() && !child->hasTagName(paramTag)) // Discount <param>
- || (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
- return true;
- }
- return false;
-}
-
-// FIXME: This belongs on HTMLObjectElement.
-static void parametersFromObject(HTMLObjectElement* objectElement, Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
-{
- HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
-
- // 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.
- Node* child = objectElement->firstChild();
- while (child) {
- if (child->hasTagName(paramTag)) {
- HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
- String name = p->name();
- if (url.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
- url = deprecatedParseURL(p->value());
- // FIXME: serviceType calculation does not belong in this function.
- if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
- serviceType = p->value();
- size_t pos = serviceType.find(";");
- if (pos != notFound)
- serviceType = serviceType.left(pos);
- }
- if (!name.isEmpty()) {
- uniqueParamNames.add(name.impl());
- paramNames.append(p->name());
- paramValues.append(p->value());
- }
- }
- child = child->nextSibling();
- }
-
- // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
- // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
- // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
- // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
- // else our Java plugin will misinterpret it. [4004531]
- String codebase;
- if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
- codebase = "codebase";
- uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
- }
-
- // Turn the attributes of the <object> element into arrays, but don't override <param> values.
- NamedNodeMap* attributes = objectElement->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- const AtomicString& name = it->name().localName();
- if (!uniqueParamNames.contains(name.impl())) {
- paramNames.append(name.string());
- paramValues.append(it->value().string());
- }
- }
- }
-
- mapDataParamToSrc(&paramNames, &paramValues);
-
- // If we still don't have a type, try to map from a specific CLASSID to a type.
- if (serviceType.isEmpty())
- serviceType = serviceTypeForClassId(objectElement->classId());
-}
-
-// FIXME: This belongs on HTMLObjectElement, HTMLPluginElement or HTMLFrameOwnerElement.
-static void updateWidgetForObjectElement(HTMLObjectElement* objectElement, bool onlyCreateNonNetscapePlugins)
-{
- objectElement->setNeedsWidgetUpdate(false);
- if (!objectElement->isFinishedParsingChildren())
- return;
-
- Frame* frame = objectElement->document()->frame();
- String url = objectElement->url();
- String serviceType = objectElement->serviceType();
-
- Vector<String> paramNames;
- Vector<String> paramValues;
- parametersFromObject(objectElement, paramNames, paramValues, url, serviceType);
-
- if (!isURLAllowed(objectElement->document(), url))
- return;
-
- bool fallbackContent = hasFallbackContent(objectElement);
- objectElement->renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
-
- if (onlyCreateNonNetscapePlugins && isNetscapePlugin(frame, url, serviceType))
- return;
-
- bool beforeLoadAllowedLoad = objectElement->dispatchBeforeLoadEvent(url);
-
- // beforeload events can modify the DOM, potentially causing
- // RenderWidget::destroy() to be called. Ensure we haven't been
- // destroyed before continuing.
- // FIXME: Should this render fallback content?
- if (!objectElement->renderer())
- return;
-
- bool success = beforeLoadAllowedLoad && frame->loader()->subframeLoader()->requestObject(objectElement, url, objectElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
-
- if (!success && fallbackContent)
- objectElement->renderFallbackContent();
-}
-
-// FIXME: This belongs on HTMLEmbedElement.
-static void parametersFromEmbed(HTMLEmbedElement* embedElement, Vector<String>& paramNames, Vector<String>& paramValues)
-{
- NamedNodeMap* attributes = embedElement->attributes();
- if (attributes) {
- for (unsigned i = 0; i < attributes->length(); ++i) {
- Attribute* it = attributes->attributeItem(i);
- paramNames.append(it->name().localName().string());
- paramValues.append(it->value().string());
- }
- }
-}
-
-// FIXME: This belongs on HTMLEmbedElement, HTMLPluginElement or HTMLFrameOwnerElement.
-static void updateWidgetForEmbedElement(HTMLEmbedElement* embedElement, bool onlyCreateNonNetscapePlugins)
-{
- Frame* frame = embedElement->document()->frame();
- String url = embedElement->url();
- String serviceType = embedElement->serviceType();
-
- embedElement->setNeedsWidgetUpdate(false);
-
- if (url.isEmpty() && serviceType.isEmpty())
- return;
- if (!isURLAllowed(embedElement->document(), url))
- return;
-
- Vector<String> paramNames;
- Vector<String> paramValues;
- parametersFromEmbed(embedElement, paramNames, paramValues);
-
- if (onlyCreateNonNetscapePlugins && isNetscapePlugin(frame, url, serviceType))
- return;
-
- if (embedElement->dispatchBeforeLoadEvent(url)) {
- // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
- frame->loader()->subframeLoader()->requestObject(embedElement, url, embedElement->getAttribute(nameAttr), serviceType, paramNames, paramValues);
- }
-}
-
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
-// FIXME: This belongs on HTMLMediaElement.
-static void updateWidgetForMediaElement(HTMLMediaElement* mediaElement, bool ignored)
-{
- Vector<String> paramNames;
- Vector<String> paramValues;
- KURL kurl;
-
- mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
- mediaElement->setNeedWidgetUpdate(false);
- frame->loader()->subframeLoader()->loadMediaPlayerProxyPlugin(mediaElement, kurl, paramNames, paramValues);
-}
-#endif
-
-void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
-{
- if (!m_replacementText.isNull() || !node()) // Check the node in case destroy() has been called.
- return;
-
- // The calls to SubframeLoader::requestObject within this function can result in a plug-in being initialized.
- // This can run cause arbitrary JavaScript to run and may result in this RenderObject being detached from
- // the render tree and destroyed, causing a crash like <rdar://problem/6954546>. By extending our lifetime
- // artifically to ensure that we remain alive for the duration of plug-in initialization.
- RenderWidgetProtector protector(this);
-
- if (node()->hasTagName(objectTag)) {
- HTMLObjectElement* objectElement = static_cast<HTMLObjectElement*>(node());
- updateWidgetForObjectElement(objectElement, onlyCreateNonNetscapePlugins);
- } else if (node()->hasTagName(embedTag)) {
- HTMLEmbedElement* embedElement = static_cast<HTMLEmbedElement*>(node());
- updateWidgetForEmbedElement(embedElement, onlyCreateNonNetscapePlugins);
- }
-#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
- else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
- HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(node());
- updateWidgetForMediaElement(mediaElement, onlyCreateNonNetscapePlugins);
- }
-#endif
-}
-
void RenderEmbeddedObject::setShowsMissingPluginIndicator()
{
ASSERT(m_replacementText.isEmpty());
@@ -384,6 +115,11 @@ void RenderEmbeddedObject::setShowsCrashedPluginIndicator()
m_replacementText = crashedPluginText();
}
+bool RenderEmbeddedObject::pluginCrashedOrWasMissing() const
+{
+ return !m_replacementText.isNull();
+}
+
void RenderEmbeddedObject::setMissingPluginIndicatorIsPressed(bool pressed)
{
if (m_missingPluginIndicatorIsPressed == pressed)
@@ -395,7 +131,7 @@ void RenderEmbeddedObject::setMissingPluginIndicatorIsPressed(bool pressed)
void RenderEmbeddedObject::paint(PaintInfo& paintInfo, int tx, int ty)
{
- if (!m_replacementText.isNull()) {
+ if (pluginCrashedOrWasMissing()) {
RenderReplaced::paint(paintInfo, tx, ty);
return;
}
@@ -405,7 +141,7 @@ void RenderEmbeddedObject::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
{
- if (!m_replacementText)
+ if (pluginCrashedOrWasMissing())
return;
if (paintInfo.phase == PaintPhaseSelection)
diff --git a/WebCore/rendering/RenderEmbeddedObject.h b/WebCore/rendering/RenderEmbeddedObject.h
index 6376f93..8d09ede 100644
--- a/WebCore/rendering/RenderEmbeddedObject.h
+++ b/WebCore/rendering/RenderEmbeddedObject.h
@@ -36,7 +36,8 @@ public:
RenderEmbeddedObject(Element*);
virtual ~RenderEmbeddedObject();
- void updateWidget(bool onlyCreateNonNetscapePlugins);
+ bool pluginCrashedOrWasMissing() const;
+
void setShowsMissingPluginIndicator();
void setShowsCrashedPluginIndicator();
bool showsMissingPluginIndicator() const { return m_showsMissingPluginIndicator; }
diff --git a/WebCore/rendering/RenderIndicator.cpp b/WebCore/rendering/RenderIndicator.cpp
index afff9c2..32ef916 100644
--- a/WebCore/rendering/RenderIndicator.cpp
+++ b/WebCore/rendering/RenderIndicator.cpp
@@ -51,31 +51,12 @@ void RenderIndicator::layout()
setNeedsLayout(false);
}
-void RenderIndicator::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
- requestLayoutForParts();
-}
-
void RenderIndicator::updateFromElement()
{
- requestLayoutForParts();
+ setNeedsLayout(true);
repaint();
}
-bool RenderIndicator::hasParts() const
-{
- if (RenderObject* last = lastChild())
- return last->isRenderBlock();
- return false;
-}
-
-void RenderIndicator::requestLayoutForParts()
-{
- if (shouldHaveParts() || hasParts())
- setNeedsLayout(true);
-}
-
} // namespace WebCore
#endif
diff --git a/WebCore/rendering/RenderIndicator.h b/WebCore/rendering/RenderIndicator.h
index 2d82a09..b1f4acf 100644
--- a/WebCore/rendering/RenderIndicator.h
+++ b/WebCore/rendering/RenderIndicator.h
@@ -34,15 +34,10 @@ public:
protected:
virtual void layout();
virtual void updateFromElement();
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
virtual void layoutParts() = 0;
virtual bool shouldHaveParts() const = 0;
-
-private:
- void requestLayoutForParts();
- bool hasParts() const;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 331750c..63ce830 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -44,6 +44,7 @@
#include "config.h"
#include "RenderLayer.h"
+#include "ColumnInfo.h"
#include "CSSPropertyNames.h"
#include "CSSStyleDeclaration.h"
#include "CSSStyleSelector.h"
@@ -1373,9 +1374,9 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
if (updateScrollbars) {
if (m_hBar)
- m_hBar->setValue(scrollXOffset());
+ m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
if (m_vBar)
- m_vBar->setValue(m_scrollY);
+ m_vBar->setValue(m_scrollY, Scrollbar::NotFromScrollAnimator);
}
// Schedule the scroll DOM event.
@@ -1628,6 +1629,20 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset
// FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
}
+int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
+{
+ Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
+ return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
+}
+
+void RenderLayer::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+ if (m_hBar)
+ m_hBar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
+ if (m_vBar)
+ m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void RenderLayer::valueChanged(Scrollbar*)
{
// Update scroll position from scrollbars.
@@ -2101,7 +2116,7 @@ RenderLayer::updateScrollInfoAfterLayout()
// so this is needed to keep everything working (see how scrollXOffset()
// differs from scrollYOffset() to get an idea of why the horizontal and
// vertical scrollbars need to be treated differently).
- m_hBar->setValue(scrollXOffset());
+ m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
}
if (m_vBar) {
int clientHeight = box->clientHeight();
@@ -2572,12 +2587,12 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
int layerY = 0;
columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
- Vector<IntRect>* colRects = columnBlock->columnRects();
- unsigned colCount = colRects->size();
+ ColumnInfo* colInfo = columnBlock->columnInfo();
+ unsigned colCount = colInfo->columnCount();
int currYOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
colRect.move(layerX, layerY);
@@ -3038,18 +3053,18 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
int layerY = 0;
columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
- Vector<IntRect>* colRects = columnBlock->columnRects();
- int colCount = colRects->size();
+ ColumnInfo* colInfo = columnBlock->columnInfo();
+ int colCount = colInfo->columnCount();
// We have to go backwards from the last column to the first.
int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
int currYOffset = 0;
int i;
for (i = 0; i < colCount; i++)
- currYOffset -= colRects->at(i).height();
+ currYOffset -= colInfo->columnRectAt(i).height();
for (i = colCount - 1; i >= 0; i--) {
// For each rect, we clip to the rect, and then we adjust our coords.
- IntRect colRect = colRects->at(i);
+ IntRect colRect = colInfo->columnRectAt(i);
int currXOffset = colRect.x() - left;
currYOffset += colRect.height();
colRect.move(layerX, layerY);
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 3f0ac7c..3d9445d 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -529,6 +529,8 @@ private:
bool shouldBeNormalFlowOnly() const;
// ScrollBarClient interface
+ virtual int scrollSize(ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&);
virtual void valueChanged(Scrollbar*);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
virtual bool isActive() const;
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 449466d..480d94b 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -27,8 +27,11 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerBacking.h"
+
#include "AnimationController.h"
#include "CanvasRenderingContext.h"
+#include "CanvasRenderingContext2D.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "FrameView.h"
@@ -51,8 +54,7 @@
#include "RenderVideo.h"
#include "RenderView.h"
#include "Settings.h"
-
-#include "RenderLayerBacking.h"
+#include "WebGLRenderingContext.h"
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
#include "GraphicsLayerAndroid.h"
@@ -262,9 +264,8 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
else if (isAcceleratedCanvas(renderer())) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
if (CanvasRenderingContext* context = canvas->renderingContext())
- if (context->graphicsContext3D())
- if (PlatformLayer* pl = context->graphicsContext3D()->platformLayer())
- m_graphicsLayer->setContentsToCanvas(pl);
+ m_graphicsLayer->setContentsToCanvas(context->platformLayer());
+ layerConfigChanged = true;
}
#endif
@@ -1173,12 +1174,12 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
continue;
// get timing function
- const TimingFunction* tf = keyframeStyle->hasAnimations() ? &((*keyframeStyle->animations()).animation(0)->timingFunction()) : 0;
+ RefPtr<TimingFunction> tf = keyframeStyle->hasAnimations() ? (*keyframeStyle->animations()).animation(0)->timingFunction() : 0;
- if (currentKeyframe.containsProperty(AnimatedPropertyWebkitTransform))
+ if (currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
transformVector.insert(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf));
- if (currentKeyframe.containsProperty(AnimatedPropertyOpacity))
+ if (currentKeyframe.containsProperty(CSSPropertyOpacity))
opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
}
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index d125a24..fd38f30 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -218,7 +218,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
return;
bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
- if (!updateRoot) {
+ if (!updateRoot || m_compositingConsultsOverlap) {
// Only clear the flag if we're updating the entire hierarchy.
m_compositingLayersNeedRebuild = false;
updateRoot = rootRenderLayer();
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 2ecc2d0..aa31b6c 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -500,7 +500,7 @@ bool RenderListBox::scrollToRevealElementAtListIndex(int index)
m_indexOffset = newOffset;
if (m_vBar)
- m_vBar->setValue(m_indexOffset);
+ m_vBar->setValue(m_indexOffset, Scrollbar::NotFromScrollAnimator);
return true;
}
@@ -523,6 +523,17 @@ void RenderListBox::valueChanged(unsigned listIndex)
element->dispatchFormControlChangeEvent();
}
+int RenderListBox::scrollSize(ScrollbarOrientation orientation) const
+{
+ return ((orientation == VerticalScrollbar) && m_vBar) ? (m_vBar->totalSize() - m_vBar->visibleSize()) : 0;
+}
+
+void RenderListBox::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+ if (m_vBar)
+ m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void RenderListBox::valueChanged(Scrollbar*)
{
int newOffset = m_vBar->value();
@@ -578,7 +589,7 @@ void RenderListBox::setScrollTop(int newTop)
return;
m_indexOffset = index;
if (m_vBar)
- m_vBar->setValue(index);
+ m_vBar->setValue(index, Scrollbar::NotFromScrollAnimator);
}
bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
diff --git a/WebCore/rendering/RenderListBox.h b/WebCore/rendering/RenderListBox.h
index 36cb87a..dcee739 100644
--- a/WebCore/rendering/RenderListBox.h
+++ b/WebCore/rendering/RenderListBox.h
@@ -96,6 +96,8 @@ private:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
// ScrollbarClient interface.
+ virtual int scrollSize(ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&);
virtual void valueChanged(Scrollbar*);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
virtual bool isActive() const;
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 9fbaf91..c369db8 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -28,6 +28,7 @@
#include "AffineTransform.h"
#include "CachedResourceClient.h"
+#include "CSSPrimitiveValue.h"
#include "Document.h"
#include "Element.h"
#include "FloatQuad.h"
@@ -319,6 +320,7 @@ public:
virtual bool isSVGImage() const { return false; }
virtual bool isSVGForeignObject() const { return false; }
virtual bool isSVGResourceContainer() const { return false; }
+ virtual bool isSVGResourceFilterPrimitive() const { return false; }
virtual bool isSVGShadowTreeRootContainer() const { return false; }
virtual RenderSVGResourceContainer* toRenderSVGResourceContainer();
@@ -986,13 +988,14 @@ inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRenderi
inline int adjustForAbsoluteZoom(int value, RenderObject* renderer)
{
- float zoomFactor = renderer->style()->effectiveZoom();
+ double zoomFactor = renderer->style()->effectiveZoom();
if (zoomFactor == 1)
return value;
// Needed because computeLengthInt truncates (rather than rounds) when scaling up.
if (zoomFactor > 1)
value++;
- return static_cast<int>(value / zoomFactor);
+
+ return roundForImpreciseConversion<int, INT_MAX, INT_MIN>(value / zoomFactor);
}
inline void adjustIntRectForAbsoluteZoom(IntRect& rect, RenderObject* renderer)
diff --git a/WebCore/rendering/RenderSVGAllInOne.cpp b/WebCore/rendering/RenderSVGAllInOne.cpp
index 2d44ca2..9c30d88 100644
--- a/WebCore/rendering/RenderSVGAllInOne.cpp
+++ b/WebCore/rendering/RenderSVGAllInOne.cpp
@@ -37,6 +37,7 @@
#include "RenderSVGResourceClipper.cpp"
#include "RenderSVGResourceContainer.cpp"
#include "RenderSVGResourceFilter.cpp"
+#include "RenderSVGResourceFilterPrimitive.cpp"
#include "RenderSVGResourceGradient.cpp"
#include "RenderSVGResourceLinearGradient.cpp"
#include "RenderSVGResourceMarker.cpp"
diff --git a/WebCore/rendering/RenderSVGResourceContainer.cpp b/WebCore/rendering/RenderSVGResourceContainer.cpp
index f33eb85..41ab91f 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.cpp
+++ b/WebCore/rendering/RenderSVGResourceContainer.cpp
@@ -160,14 +160,14 @@ void RenderSVGResourceContainer::registerResource()
return;
}
- OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
+ OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions->removePendingResource(m_id));
// Cache us with the new id.
extensions->addResource(m_id, this);
// Update cached resources of pending clients.
- const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
- for (HashSet<SVGStyledElement*>::const_iterator it = clients->begin(); it != end; ++it) {
+ const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
+ for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
RenderObject* renderer = (*it)->renderer();
if (!renderer)
continue;
diff --git a/WebCore/rendering/RenderSVGResourceFilterPrimitive.cpp b/WebCore/rendering/RenderSVGResourceFilterPrimitive.cpp
new file mode 100644
index 0000000..f7381fa
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceFilterPrimitive.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG) && ENABLE(FILTERS)
+#include "RenderSVGResourceFilterPrimitive.h"
+
+namespace WebCore {
+
+RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes* filterPrimitiveElement)
+ : RenderSVGHiddenContainer(filterPrimitiveElement)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG) && ENABLE(FILTERS)
diff --git a/WebCore/rendering/RenderSVGResourceFilterPrimitive.h b/WebCore/rendering/RenderSVGResourceFilterPrimitive.h
new file mode 100644
index 0000000..96e2c5e
--- /dev/null
+++ b/WebCore/rendering/RenderSVGResourceFilterPrimitive.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 RenderSVGResourceFilterPrimitive_h
+#define RenderSVGResourceFilterPrimitive_h
+
+#if ENABLE(SVG) && ENABLE(FILTERS)
+
+#include "RenderSVGHiddenContainer.h"
+#include "SVGFilterPrimitiveStandardAttributes.h"
+
+namespace WebCore {
+
+class RenderSVGResourceFilterPrimitive : public RenderSVGHiddenContainer {
+public:
+ RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes* filterPrimitiveElement);
+
+private:
+ virtual bool isSVGResourceFilterPrimitive() const { return true; }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG) && ENABLE(FILTERS)
+
+#endif // RenderSVGResourceFilterPrimitive_h
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 3fd439c..4e23c42 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -349,8 +349,16 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
}
}
- // Spec: Only graphical elements can be targeted by the mouse, so we don't check self here.
- // 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched."
+ // If we didn't early exit above, we've just hit the container <svg> element. Unlike SVG 1.1, 2nd Edition allows container elements to be hit.
+ if (hitTestAction == HitTestBlockBackground) {
+ // Only return true here, if the last hit testing phase 'BlockBackground' is executed. If we'd return true in the 'Foreground' phase,
+ // hit testing would stop immediately. For SVG only trees this doesn't matter. Though when we have a <foreignObject> subtree we need
+ // to be able to detect hits on the background of a <div> element. If we'd return true here in the 'Foreground' phase, we are not able
+ // to detect these hits anymore.
+ updateHitTestResult(result, roundedIntPoint(localPoint));
+ return true;
+ }
+
return false;
}
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 976d1ac..d3fe3f6 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -58,7 +58,7 @@ void RenderTextControlMultiLine::subtreeHasChanged()
node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
if (Frame* frame = this->frame())
- frame->textDidChangeInTextArea(textArea);
+ frame->editor()->textDidChangeInTextArea(textArea);
}
bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index b27a91a..e49fa4c 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -170,7 +170,13 @@ void RenderTextControlSingleLine::subtreeHasChanged()
// InputElement::handleBeforeTextInsertedEvent() has already called
// sanitizeUserInputValue().
// sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
- input->setValueFromRenderer(input->sanitizeValue(text()));
+ String value = text();
+ if (input->isAcceptableValue(value))
+ input->setValueFromRenderer(input->sanitizeValue(value));
+ if (node()->isHTMLElement()) {
+ // Recalc for :invalid and hasUnacceptableValue() change.
+ static_cast<HTMLInputElement*>(input)->setNeedsStyleRecalc();
+ }
if (m_cancelButton)
updateCancelButtonVisibility();
@@ -181,12 +187,12 @@ void RenderTextControlSingleLine::subtreeHasChanged()
if (!wasChanged && node()->focused()) {
if (Frame* frame = this->frame())
- frame->textFieldDidBeginEditing(static_cast<Element*>(node()));
+ frame->editor()->textFieldDidBeginEditing(static_cast<Element*>(node()));
}
if (node()->focused()) {
if (Frame* frame = document()->frame())
- frame->textDidChangeInTextField(static_cast<Element*>(node()));
+ frame->editor()->textDidChangeInTextField(static_cast<Element*>(node()));
}
}
@@ -378,18 +384,19 @@ void RenderTextControlSingleLine::forwardEvent(Event* event)
return;
}
- FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
- int textRight = innerTextRenderer->borderBoxRect().right();
-
#if ENABLE(INPUT_SPEECH)
if (RenderBox* speechBox = m_speechButton ? m_speechButton->renderBox() : 0) {
- if (localPoint.x() >= speechBox->x() && localPoint.x() < speechBox->x() + speechBox->width()) {
+ FloatPoint pointInTextControlCoords = absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
+ if (speechBox->frameRect().contains(roundedIntPoint(pointInTextControlCoords))) {
m_speechButton->defaultEventHandler(event);
return;
}
}
#endif
+ FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
+ int textRight = innerTextRenderer->borderBoxRect().right();
+
if (m_resultsButton && localPoint.x() < innerTextRenderer->borderBoxRect().x())
m_resultsButton->defaultEventHandler(event);
else if (m_cancelButton && localPoint.x() > textRight)
@@ -680,7 +687,10 @@ void RenderTextControlSingleLine::updateFromElement()
} else {
if (!inputElement()->suggestedValue().isNull())
setInnerTextValue(inputElement()->suggestedValue());
- else
+ else if (!node()->isHTMLElement() || !static_cast<HTMLInputElement*>(node())->formControlValueMatchesRenderer())
+ // For HTMLInputElement, update the renderer value only if the
+ // formControlValueMatchesRenderer() flag is false. It protects an
+ // unacceptable renderer value from being overwritten with the DOM value.
setInnerTextValue(inputElement()->value());
}
diff --git a/WebCore/rendering/RenderTextFragment.cpp b/WebCore/rendering/RenderTextFragment.cpp
index 0556284..b14308d 100644
--- a/WebCore/rendering/RenderTextFragment.cpp
+++ b/WebCore/rendering/RenderTextFragment.cpp
@@ -48,9 +48,9 @@ PassRefPtr<StringImpl> RenderTextFragment::originalText() const
{
Node* e = node();
RefPtr<StringImpl> result = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
- if (result && (start() > 0 || start() < result->length()))
- result = result->substring(start(), end());
- return result.release();
+ if (!result)
+ return 0;
+ return result->substring(start(), end());
}
void RenderTextFragment::destroy()
@@ -81,7 +81,7 @@ UChar RenderTextFragment::previousCharacter() const
if (start()) {
Node* e = node();
StringImpl* original = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
- if (original)
+ if (original && start() <= original->length())
return (*original)[start() - 1];
}
diff --git a/WebCore/rendering/RenderThemeChromiumWin.cpp b/WebCore/rendering/RenderThemeChromiumWin.cpp
index 3023798..be670ff 100644
--- a/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -56,6 +56,10 @@
namespace WebCore {
+// The standard width for the menu list drop-down button when run under
+// layout test mode. Use the value that's currently captured in most baselines.
+static const int kStandardMenuListButtonWidth = 17;
+
namespace {
class ThemePainter {
public:
@@ -437,6 +441,12 @@ bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const PaintInfo&
return paintSliderTrack(o, i, r);
}
+static int menuListButtonWidth()
+{
+ static int width = ChromiumBridge::layoutTestMode() ? kStandardMenuListButtonWidth : GetSystemMetrics(SM_CXVSCROLL);
+ return width;
+}
+
// Used to paint unstyled menulists (i.e. with the default border)
bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
@@ -461,7 +471,7 @@ bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i,
// Take padding and border into account. If the MenuList is smaller than
// the size of a button, make sure to shrink it appropriately and not put
// its x position to the left of the menulist.
- const int buttonWidth = GetSystemMetrics(SM_CXVSCROLL);
+ const int buttonWidth = menuListButtonWidth();
int spacingLeft = borderLeft + box->paddingLeft();
int spacingRight = borderRight + box->paddingRight();
int spacingTop = borderTop + box->paddingTop();
diff --git a/WebCore/rendering/RenderThemeWin.cpp b/WebCore/rendering/RenderThemeWin.cpp
index 45965e6..8a33173 100644
--- a/WebCore/rendering/RenderThemeWin.cpp
+++ b/WebCore/rendering/RenderThemeWin.cpp
@@ -26,6 +26,7 @@
#include "Element.h"
#include "Frame.h"
#include "GraphicsContext.h"
+#include "LocalWindowsContext.h"
#include "RenderSlider.h"
#include "Settings.h"
#include "SoftLinking.h"
@@ -558,11 +559,12 @@ static void drawControl(GraphicsContext* context, RenderObject* o, HANDLE theme,
bool alphaBlend = false;
if (theme)
alphaBlend = IsThemeBackgroundPartiallyTransparent(theme, themeData.m_part, themeData.m_state);
- HDC hdc = context->getWindowsContext(r, alphaBlend);
+ LocalWindowsContext windowsContext(context, r, alphaBlend);
RECT widgetRect = r;
if (theme)
- DrawThemeBackground(theme, hdc, themeData.m_part, themeData.m_state, &widgetRect, NULL);
+ DrawThemeBackground(theme, windowsContext.hdc(), themeData.m_part, themeData.m_state, &widgetRect, 0);
else {
+ HDC hdc = windowsContext.hdc();
if (themeData.m_part == TFP_TEXTFIELD) {
::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
if (themeData.m_state == TS_DISABLED || themeData.m_state == TFS_READONLY)
@@ -608,7 +610,6 @@ static void drawControl(GraphicsContext* context, RenderObject* o, HANDLE theme,
::DrawFrameControl(hdc, &widgetRect, themeData.m_part, themeData.m_state);
}
}
- context->releaseWindowsContext(hdc, r, alphaBlend);
}
bool RenderThemeWin::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index acb8487..eba3468 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -250,7 +250,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int)
// or there is a transform on the <html>.
// Only fill with the base background color (typically white) if we're the root document,
// since iframes/frames with no background in the child document should show the parent's background.
- if (view()->isTransparent()) // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
+ if (frameView()->isTransparent()) // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
frameView()->setUseSlowRepaints(); // The parent must show behind the child.
else {
Color baseColor = frameView()->baseBackgroundColor();
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index 0c9b7e1..20d7220 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -676,6 +676,9 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i
void writeSVGContainer(TextStream& ts, const RenderObject& container, int indent)
{
+ // Currently RenderSVGResourceFilterPrimitive has no meaningful output.
+ if (container.isSVGResourceFilterPrimitive())
+ return;
writeStandardPrefix(ts, container, indent);
writePositionAndStyle(ts, container);
ts << "\n";
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 1939133..e5228f0 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -395,6 +395,12 @@ PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(
void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
{
+ // For privacy reasons, only allow clicks directly coming from the user.
+ if (!event->fromUserGesture()) {
+ HTMLDivElement::defaultEventHandler(event);
+ return;
+ }
+
// On mouse down, select the text and set focus.
HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index 68c8113..a78321f 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -303,8 +303,6 @@ enum EAnimPlayState {
AnimPlayStatePaused = 0x1
};
-enum ETimingFunctionType { LinearTimingFunction, CubicBezierTimingFunction };
-
enum EWhiteSpace {
NORMAL, PRE, PRE_WRAP, PRE_LINE, NOWRAP, KHTML_NOWRAP
};
diff --git a/WebCore/storage/DatabaseAuthorizer.cpp b/WebCore/storage/DatabaseAuthorizer.cpp
index 79e47d4..e287dee 100644
--- a/WebCore/storage/DatabaseAuthorizer.cpp
+++ b/WebCore/storage/DatabaseAuthorizer.cpp
@@ -29,6 +29,8 @@
#include "config.h"
#include "DatabaseAuthorizer.h"
+#if ENABLE(DATABASE)
+
#include "PlatformString.h"
#include <wtf/PassRefPtr.h>
@@ -419,3 +421,5 @@ int DatabaseAuthorizer::updateDeletesBasedOnTableName(const String& tableName)
}
} // namespace WebCore
+
+#endif
diff --git a/WebCore/storage/IDBAny.cpp b/WebCore/storage/IDBAny.cpp
index 93d2633..7303fd6 100644
--- a/WebCore/storage/IDBAny.cpp
+++ b/WebCore/storage/IDBAny.cpp
@@ -37,11 +37,18 @@
namespace WebCore {
-PassRefPtr<IDBAny> IDBAny::create()
+PassRefPtr<IDBAny> IDBAny::createInvalid()
{
return adoptRef(new IDBAny());
}
+PassRefPtr<IDBAny> IDBAny::createNull()
+{
+ RefPtr<IDBAny> idbAny = adoptRef(new IDBAny());
+ idbAny->setNull();
+ return idbAny.release();
+}
+
IDBAny::IDBAny()
: m_type(UndefinedType)
{
@@ -93,7 +100,7 @@ PassRefPtr<SerializedScriptValue> IDBAny::serializedScriptValue()
return m_serializedScriptValue;
}
-void IDBAny::set()
+void IDBAny::setNull()
{
ASSERT(m_type == UndefinedType);
m_type = NullType;
diff --git a/WebCore/storage/IDBAny.h b/WebCore/storage/IDBAny.h
index 950660a..9066e13 100644
--- a/WebCore/storage/IDBAny.h
+++ b/WebCore/storage/IDBAny.h
@@ -44,11 +44,19 @@ class SerializedScriptValue;
class IDBAny : public RefCounted<IDBAny> {
public:
- static PassRefPtr<IDBAny> create();
+ static PassRefPtr<IDBAny> createInvalid();
+ static PassRefPtr<IDBAny> createNull();
template<typename T>
static PassRefPtr<IDBAny> create(T* idbObject)
{
- RefPtr<IDBAny> any = IDBAny::create();
+ RefPtr<IDBAny> any = IDBAny::createInvalid();
+ any->set(idbObject);
+ return any.release();
+ }
+ template<typename T>
+ static PassRefPtr<IDBAny> create(PassRefPtr<T> idbObject)
+ {
+ RefPtr<IDBAny> any = IDBAny::createInvalid();
any->set(idbObject);
return any.release();
}
@@ -77,7 +85,7 @@ public:
PassRefPtr<SerializedScriptValue> serializedScriptValue();
// Set can only be called once.
- void set(); // For "null".
+ void setNull();
void set(PassRefPtr<IDBCursor>);
void set(PassRefPtr<IDBDatabase>);
void set(PassRefPtr<IDBFactory>);
diff --git a/WebCore/storage/IDBCursor.cpp b/WebCore/storage/IDBCursor.cpp
index ae0d127..52945f8 100644
--- a/WebCore/storage/IDBCursor.cpp
+++ b/WebCore/storage/IDBCursor.cpp
@@ -38,8 +38,9 @@
namespace WebCore {
-IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend)
+IDBCursor::IDBCursor(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request)
: m_backend(backend)
+ , m_request(request)
{
}
@@ -69,11 +70,13 @@ PassRefPtr<IDBRequest> IDBCursor::update(ScriptExecutionContext* context, PassRe
return request.release();
}
-PassRefPtr<IDBRequest> IDBCursor::continueFunction(ScriptExecutionContext* context, PassRefPtr<IDBKey> key)
+void IDBCursor::continueFunction(PassRefPtr<IDBKey> key)
{
- RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this));
- m_backend->continueFunction(key, request);
- return request.release();
+ // FIXME: We're not using the context from when continue was called, which means the callback
+ // will be on the original context openCursor was called on. Is this right?
+ if (m_request->resetReadyState())
+ m_backend->continueFunction(key, m_request);
+ // FIXME: Else throw?
}
PassRefPtr<IDBRequest> IDBCursor::remove(ScriptExecutionContext* context)
diff --git a/WebCore/storage/IDBCursor.h b/WebCore/storage/IDBCursor.h
index ccce001..0c438c4 100644
--- a/WebCore/storage/IDBCursor.h
+++ b/WebCore/storage/IDBCursor.h
@@ -31,7 +31,6 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#include <wtf/Threading.h>
namespace WebCore {
@@ -43,7 +42,7 @@ class IDBRequest;
class ScriptExecutionContext;
class SerializedScriptValue;
-class IDBCursor : public ThreadSafeShared<IDBCursor> {
+class IDBCursor : public RefCounted<IDBCursor> {
public:
enum Direction {
NEXT = 0,
@@ -51,24 +50,25 @@ public:
PREV = 2,
PREV_NO_DUPLICATE = 3,
};
- static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend)
+ static PassRefPtr<IDBCursor> create(PassRefPtr<IDBCursorBackendInterface> backend, IDBRequest* request)
{
- return adoptRef(new IDBCursor(backend));
+ return adoptRef(new IDBCursor(backend, request));
}
- virtual ~IDBCursor();
+ ~IDBCursor();
// Implement the IDL
- virtual unsigned short direction() const;
- virtual PassRefPtr<IDBKey> key() const;
- virtual PassRefPtr<IDBAny> value() const;
- virtual PassRefPtr<IDBRequest> update(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);
- virtual PassRefPtr<IDBRequest> continueFunction(ScriptExecutionContext*, PassRefPtr<IDBKey> = 0);
- virtual PassRefPtr<IDBRequest> remove(ScriptExecutionContext*);
+ unsigned short direction() const;
+ PassRefPtr<IDBKey> key() const;
+ PassRefPtr<IDBAny> value() const;
+ PassRefPtr<IDBRequest> update(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);
+ void continueFunction(PassRefPtr<IDBKey> = 0);
+ PassRefPtr<IDBRequest> remove(ScriptExecutionContext*);
private:
- explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>);
+ explicit IDBCursor(PassRefPtr<IDBCursorBackendInterface>, IDBRequest*);
RefPtr<IDBCursorBackendInterface> m_backend;
+ RefPtr<IDBRequest> m_request;
};
} // namespace WebCore
diff --git a/WebCore/storage/IDBCursor.idl b/WebCore/storage/IDBCursor.idl
index 3702ef3..232842b 100644
--- a/WebCore/storage/IDBCursor.idl
+++ b/WebCore/storage/IDBCursor.idl
@@ -38,7 +38,7 @@ module storage {
readonly attribute IDBAny value;
[CallWith=ScriptExecutionContext] IDBRequest update(in SerializedScriptValue value);
- [CallWith=ScriptExecutionContext, ImplementationFunction=continueFunction] IDBRequest continue(in [Optional] IDBKey key);
+ [ImplementationFunction=continueFunction] void continue(in [Optional] IDBKey key);
[CallWith=ScriptExecutionContext] IDBRequest remove();
};
}
diff --git a/WebCore/storage/IDBDatabaseBackendImpl.cpp b/WebCore/storage/IDBDatabaseBackendImpl.cpp
index f4f2934..021f70a 100644
--- a/WebCore/storage/IDBDatabaseBackendImpl.cpp
+++ b/WebCore/storage/IDBDatabaseBackendImpl.cpp
@@ -177,8 +177,8 @@ void IDBDatabaseBackendImpl::removeObjectStore(const String& name, PassRefPtr<ID
transaction.begin();
doDelete(sqliteDatabase(), "DELETE FROM ObjectStores WHERE id = ?", objectStore->id());
doDelete(sqliteDatabase(), "DELETE FROM ObjectStoreData WHERE objectStoreId = ?", objectStore->id());
+ doDelete(sqliteDatabase(), "DELETE FROM IndexData WHERE indexId IN (SELECT id FROM Indexes WHERE objectStoreId = ?)", objectStore->id());
doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE objectStoreId = ?", objectStore->id());
- // FIXME: Delete index data as well.
transaction.commit();
m_objectStores.remove(name);
diff --git a/WebCore/storage/IDBFactoryBackendImpl.cpp b/WebCore/storage/IDBFactoryBackendImpl.cpp
index d656128..50cf778 100644
--- a/WebCore/storage/IDBFactoryBackendImpl.cpp
+++ b/WebCore/storage/IDBFactoryBackendImpl.cpp
@@ -83,19 +83,28 @@ static bool createTables(SQLiteDatabase* sqliteDatabase)
"CREATE TABLE IF NOT EXISTS MetaData (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL, version TEXT NOT NULL)",
"DROP TABLE IF EXISTS ObjectStores",
- "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL, keyPath TEXT, doAutoIncrement INTEGER NOT NULL)",
+ "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, keyPath TEXT, doAutoIncrement INTEGER NOT NULL)",
"DROP INDEX IF EXISTS ObjectStores_name",
"CREATE UNIQUE INDEX IF NOT EXISTS ObjectStores_name ON ObjectStores(name)",
"DROP TABLE IF EXISTS Indexes",
- "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL, keyPath TEXT, isUnique INTEGER NOT NULL)",
+ "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL UNIQUE, keyPath TEXT, isUnique INTEGER NOT NULL)",
"DROP INDEX IF EXISTS Indexes_composit",
"CREATE UNIQUE INDEX IF NOT EXISTS Indexes_composit ON Indexes(objectStoreId, name)",
"DROP TABLE IF EXISTS ObjectStoreData",
- "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, value TEXT NOT NULL)",
+ "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT UNIQUE, keyDate INTEGER UNIQUE, keyNumber INTEGER UNIQUE, value TEXT NOT NULL)",
"DROP INDEX IF EXISTS ObjectStoreData_composit",
- "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectStoreData(keyString, keyDate, keyNumber, objectStoreId)"
+ "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectStoreData(keyString, keyDate, keyNumber, objectStoreId)",
+
+ "DROP TABLE IF EXISTS IndexData",
+ "CREATE TABLE IF NOT EXISTS IndexData (id INTEGER PRIMARY KEY, indexId INTEGER NOT NULL REFERENCES Indexs(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, objectStoreDataId INTEGER NOT NULL UNIQUE REFERENCES ObjectStoreData(id))",
+ "DROP INDEX IF EXISTS IndexData_composit",
+ "CREATE UNIQUE INDEX IF NOT EXISTS IndexData_composit ON IndexData(keyString, keyDate, keyNumber, indexId)",
+ "DROP INDEX IF EXISTS IndexData_objectStoreDataId",
+ "CREATE UNIQUE INDEX IF NOT EXISTS IndexData_objectStoreDataId ON IndexData(objectStoreDataId)",
+ "DROP INDEX IF EXISTS IndexData_indexId",
+ "CREATE UNIQUE INDEX IF NOT EXISTS IndexData_indexId ON IndexData(indexId)"
};
for (size_t i = 0; i < arraysize(commands); ++i) {
diff --git a/WebCore/storage/IDBIndex.idl b/WebCore/storage/IDBIndex.idl
index e796b03..629481e 100644
--- a/WebCore/storage/IDBIndex.idl
+++ b/WebCore/storage/IDBIndex.idl
@@ -28,11 +28,16 @@ module storage {
interface [
Conditional=INDEXED_DATABASE
] IDBIndex {
- // FIXME: Complete this file.
-
readonly attribute DOMString name;
+ // FIXME: Add "storeName".
readonly attribute DOMString keyPath;
readonly attribute boolean unique;
+
+ // FIXME: Implement.
+ //IDBRequest openObjectCursor(in [Optional] IDBKeyRange range, in [Optional] unsigned short direction) raises (DOMException);
+ //IDBRequest openCursor(in [Optional] IDBKeyRange range, in [Optional] unsigned short direction) raises (DOMException);
+ //IDBRequest getObject(in IDBKey key) raises (DOMException);
+ //IDBRequest get(in IDBKey key) raises (DOMException);
};
}
diff --git a/WebCore/storage/IDBIndexBackendImpl.cpp b/WebCore/storage/IDBIndexBackendImpl.cpp
index 180ff1d..42aa62b 100644
--- a/WebCore/storage/IDBIndexBackendImpl.cpp
+++ b/WebCore/storage/IDBIndexBackendImpl.cpp
@@ -30,7 +30,7 @@
#include "IDBDatabaseBackendImpl.h"
#include "IDBObjectStoreBackendImpl.h"
-#include "SQLiteDatabase.h"
+#include "SQLiteStatement.h"
namespace WebCore {
@@ -47,6 +47,31 @@ IDBIndexBackendImpl::~IDBIndexBackendImpl()
{
}
+static String whereClause(IDBKey* key)
+{
+ return "WHERE indexId = ? AND " + key->whereSyntax();
+}
+
+static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key)
+{
+ query.bindInt64(1, id);
+ key->bind(query, 2);
+}
+
+bool IDBIndexBackendImpl::addingKeyAllowed(IDBKey* key)
+{
+ if (!m_unique)
+ return true;
+
+ SQLiteStatement query(sqliteDatabase(), "SELECT id FROM IndexData " + whereClause(key));
+ bool ok = query.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+ bindWhereClause(query, m_id, key);
+ bool existingValue = query.step() == SQLResultRow;
+
+ return !existingValue;
+}
+
SQLiteDatabase& IDBIndexBackendImpl::sqliteDatabase() const
{
return m_objectStore->database()->sqliteDatabase();
diff --git a/WebCore/storage/IDBIndexBackendImpl.h b/WebCore/storage/IDBIndexBackendImpl.h
index acf6b1f..97c65f9 100644
--- a/WebCore/storage/IDBIndexBackendImpl.h
+++ b/WebCore/storage/IDBIndexBackendImpl.h
@@ -32,6 +32,7 @@
namespace WebCore {
+class IDBKey;
class IDBObjectStoreBackendImpl;
class SQLiteDatabase;
@@ -43,6 +44,9 @@ public:
}
virtual ~IDBIndexBackendImpl();
+ int64_t id() { return m_id; }
+ bool addingKeyAllowed(IDBKey*);
+
// Implements IDBIndexBackendInterface.
virtual String name() { return m_name; }
virtual String keyPath() { return m_keyPath; }
diff --git a/WebCore/storage/IDBKey.cpp b/WebCore/storage/IDBKey.cpp
index 50c4c46..6ae79ba 100644
--- a/WebCore/storage/IDBKey.cpp
+++ b/WebCore/storage/IDBKey.cpp
@@ -28,6 +28,7 @@
#if ENABLE(INDEXED_DATABASE)
+#include "SQLiteStatement.h"
#include "SerializedScriptValue.h"
namespace WebCore {
@@ -72,6 +73,63 @@ bool IDBKey::isEqual(IDBKey* other)
return false;
}
+String IDBKey::whereSyntax() const
+{
+ switch (m_type) {
+ case IDBKey::StringType:
+ return "keyString = ?";
+ case IDBKey::NumberType:
+ return "keyNumber = ?";
+ // FIXME: Implement date.
+ case IDBKey::NullType:
+ return "keyString IS NULL AND keyDate IS NULL AND keyNumber IS NULL";
+ }
+
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+// Returns the number of items bound.
+int IDBKey::bind(SQLiteStatement& query, int column) const
+{
+ switch (m_type) {
+ case IDBKey::StringType:
+ query.bindText(column, m_string);
+ return 1;
+ case IDBKey::NumberType:
+ query.bindInt(column, m_number);
+ return 1;
+ case IDBKey::NullType:
+ return 0;
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void IDBKey::bindWithNulls(SQLiteStatement& query, int baseColumn) const
+{
+ switch (m_type) {
+ case IDBKey::StringType:
+ query.bindText(baseColumn + 0, m_string);
+ query.bindNull(baseColumn + 1);
+ query.bindNull(baseColumn + 2);
+ break;
+ case IDBKey::NumberType:
+ query.bindNull(baseColumn + 0);
+ query.bindNull(baseColumn + 1);
+ query.bindInt(baseColumn + 2, m_number);
+ break;
+ case IDBKey::NullType:
+ query.bindNull(baseColumn + 0);
+ query.bindNull(baseColumn + 1);
+ query.bindNull(baseColumn + 2);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
} // namespace WebCore
#endif
diff --git a/WebCore/storage/IDBKey.h b/WebCore/storage/IDBKey.h
index 228b4a4..b9a0be7 100644
--- a/WebCore/storage/IDBKey.h
+++ b/WebCore/storage/IDBKey.h
@@ -33,6 +33,8 @@
namespace WebCore {
+class SQLiteStatement;
+
// FIXME: Add dates.
class IDBKey : public RefCounted<IDBKey> {
public:
@@ -72,6 +74,9 @@ public:
}
bool isEqual(IDBKey* other);
+ String whereSyntax() const;
+ int bind(SQLiteStatement& query, int column) const;
+ void bindWithNulls(SQLiteStatement& query, int baseColumn) const;
private:
IDBKey();
diff --git a/WebCore/storage/IDBKeyRange.idl b/WebCore/storage/IDBKeyRange.idl
index 6daaec1..8e4d61f 100644
--- a/WebCore/storage/IDBKeyRange.idl
+++ b/WebCore/storage/IDBKeyRange.idl
@@ -39,10 +39,11 @@ module storage {
readonly attribute IDBKey right;
readonly attribute unsigned short flags;
- IDBKeyRange only(in IDBKey value);
- IDBKeyRange leftBound(in IDBKey bound, in [Optional] boolean open);
- IDBKeyRange rightBound(in IDBKey bound, in [Optional] boolean open);
- IDBKeyRange bound(in IDBKey left, in IDBKey right, in [Optional] boolean openLeft, in [Optional] boolean openRight);
+ // FIXME: Make ClassMethod work for JSC as well.
+ [ClassMethod] IDBKeyRange only(in IDBKey value);
+ [ClassMethod] IDBKeyRange leftBound(in IDBKey bound, in [Optional] boolean open);
+ [ClassMethod] IDBKeyRange rightBound(in IDBKey bound, in [Optional] boolean open);
+ [ClassMethod] IDBKeyRange bound(in IDBKey left, in IDBKey right, in [Optional] boolean openLeft, in [Optional] boolean openRight);
};
}
diff --git a/WebCore/storage/IDBObjectStore.idl b/WebCore/storage/IDBObjectStore.idl
index 1649a1d..ccd0311 100644
--- a/WebCore/storage/IDBObjectStore.idl
+++ b/WebCore/storage/IDBObjectStore.idl
@@ -28,10 +28,8 @@ module storage {
interface [
Conditional=INDEXED_DATABASE
] IDBObjectStore {
+ // FIXME: Many of these should raise on certain errors.
[CallWith=ScriptExecutionContext] IDBRequest get(in IDBKey key);
- // FIXME: Come to concensus re getAll.
- // FIXME: SerializedScriptValue raises an exception if you pass in something that can't be serialized.
- // We need to instead "raise" this error via an error callback.
[CallWith=ScriptExecutionContext] IDBRequest add(in SerializedScriptValue value, in [Optional] IDBKey key);
[CallWith=ScriptExecutionContext] IDBRequest put(in SerializedScriptValue value, in [Optional] IDBKey key);
[CallWith=ScriptExecutionContext] IDBRequest remove(in IDBKey key);
diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.cpp b/WebCore/storage/IDBObjectStoreBackendImpl.cpp
index aeb3ced..86237de 100755
--- a/WebCore/storage/IDBObjectStoreBackendImpl.cpp
+++ b/WebCore/storage/IDBObjectStoreBackendImpl.cpp
@@ -38,6 +38,7 @@
#include "IDBKeyRange.h"
#include "SQLiteDatabase.h"
#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
#if ENABLE(INDEXED_DATABASE)
@@ -65,50 +66,20 @@ PassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const
return indexNames.release();
}
-static String whereClause(IDBKey::Type type)
+static String whereClause(IDBKey* key)
{
- switch (type) {
- case IDBKey::StringType:
- return "WHERE objectStoreId = ? AND keyString = ?";
- case IDBKey::NumberType:
- return "WHERE objectStoreId = ? AND keyNumber = ?";
- // FIXME: Implement date.
- case IDBKey::NullType:
- return "WHERE objectStoreId = ? AND keyString IS NULL AND keyDate IS NULL AND keyNumber IS NULL";
- }
-
- ASSERT_NOT_REACHED();
- return "";
-}
-
-// Returns number of items bound.
-static int bindKey(SQLiteStatement& query, int column, IDBKey* key)
-{
- switch (key->type()) {
- case IDBKey::StringType:
- query.bindText(column, key->string());
- return 1;
- case IDBKey::NumberType:
- query.bindInt(column, key->number());
- return 1;
- // FIXME: Implement date.
- case IDBKey::NullType:
- return 0;
- }
-
- ASSERT_NOT_REACHED();
- return 0;
+ return "WHERE objectStoreId = ? AND " + key->whereSyntax();
}
static void bindWhereClause(SQLiteStatement& query, int64_t id, IDBKey* key)
{
query.bindInt64(1, id);
- bindKey(query, 2, key);
+ key->bind(query, 2);
}
void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
{
- SQLiteStatement query(sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key->type()));
+ SQLiteStatement query(sqliteDatabase(), "SELECT keyString, keyDate, keyNumber, value FROM ObjectStoreData " + whereClause(key.get()));
bool ok = query.prepare() == SQLResultOk;
ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
@@ -126,6 +97,59 @@ void IDBObjectStoreBackendImpl::get(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallba
ASSERT(query.step() != SQLResultRow);
}
+static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const String& keyPath)
+{
+ Vector<RefPtr<SerializedScriptValue> > values;
+ values.append(value);
+ Vector<RefPtr<IDBKey> > keys;
+ IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(values, keyPath, keys);
+ if (keys.isEmpty())
+ return 0;
+ ASSERT(keys.size() == 1);
+ return keys[0].release();
+}
+
+static void putObjectStoreData(SQLiteDatabase& db, IDBKey* key, SerializedScriptValue* value, int64_t objectStoreId, int64_t* dataRowId)
+{
+ String sql = *dataRowId != -1 ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
+ : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)";
+ SQLiteStatement query(db, sql);
+ bool ok = query.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+ key->bindWithNulls(query, 1);
+ query.bindText(4, value->toWireString());
+ if (*dataRowId != -1)
+ query.bindInt(5, *dataRowId);
+ else
+ query.bindInt64(5, objectStoreId);
+
+ ok = query.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+
+ if (*dataRowId == -1)
+ *dataRowId = db.lastInsertRowID();
+}
+
+static void putIndexData(SQLiteDatabase& db, IDBKey* key, int64_t indexId, int64_t objectStoreDataId)
+{
+ SQLiteStatement deleteQuery(db, "DELETE FROM IndexData WHERE objectStoreDataId = ?");
+ bool ok = deleteQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+ deleteQuery.bindInt64(1, objectStoreDataId);
+ ok = deleteQuery.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+
+ SQLiteStatement putQuery(db, "INSERT INTO IndexData (keyString, keyDate, keyNumber, indexId, objectStoreDataId) VALUES (?, ?, ?, ?, ?)");
+ ok = putQuery.prepare() == SQLResultOk;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+ key->bindWithNulls(putQuery, 1);
+ putQuery.bindInt64(4, indexId);
+ putQuery.bindInt64(5, objectStoreDataId);
+
+ ok = putQuery.step() == SQLResultDone;
+ ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+}
+
void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue, PassRefPtr<IDBKey> prpKey, bool addOnly, PassRefPtr<IDBCallbacks> callbacks)
{
RefPtr<SerializedScriptValue> value = prpValue;
@@ -136,73 +160,56 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue,
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "A key was supplied for an objectStore that has a keyPath."));
return;
}
- Vector<RefPtr<SerializedScriptValue> > values;
- values.append(value);
- Vector<RefPtr<IDBKey> > idbKeys;
- IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(values, m_keyPath, idbKeys);
- if (idbKeys.isEmpty()) {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "An invalid keyPath was supplied for an objectStore."));
+ key = fetchKeyFromKeyPath(value.get(), m_keyPath);
+ if (!key) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from the keyPath."));
return;
}
- key = idbKeys[0];
- }
-
- if (!key) {
+ } else if (!key) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "No key supplied."));
return;
}
- SQLiteStatement getQuery(sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key->type()));
+ Vector<RefPtr<IDBKey> > indexKeys;
+ for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) {
+ RefPtr<IDBKey> key = fetchKeyFromKeyPath(value.get(), it->second->keyPath());
+ if (!key) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from an index's keyPath."));
+ return;
+ }
+ if (!it->second->addingKeyAllowed(key.get())) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements."));
+ return;
+ }
+ indexKeys.append(key.release());
+ }
+
+ SQLiteStatement getQuery(sqliteDatabase(), "SELECT id FROM ObjectStoreData " + whereClause(key.get()));
bool ok = getQuery.prepare() == SQLResultOk;
ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
bindWhereClause(getQuery, m_id, key.get());
- bool existingValue = getQuery.step() == SQLResultRow;
- if (addOnly && existingValue) {
+ bool isExistingValue = getQuery.step() == SQLResultRow;
+ if (addOnly && isExistingValue) {
callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store."));
return;
}
- String sql = existingValue ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
- : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)";
- SQLiteStatement putQuery(sqliteDatabase(), sql);
- ok = putQuery.prepare() == SQLResultOk;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
- switch (key->type()) {
- case IDBKey::StringType:
- putQuery.bindText(1, key->string());
- putQuery.bindNull(2);
- putQuery.bindNull(3);
- break;
- // FIXME: Implement date.
- case IDBKey::NumberType:
- putQuery.bindNull(1);
- putQuery.bindNull(2);
- putQuery.bindInt(3, key->number());
- break;
- case IDBKey::NullType:
- putQuery.bindNull(1);
- putQuery.bindNull(2);
- putQuery.bindNull(3);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- putQuery.bindText(4, value->toWireString());
- if (existingValue)
- putQuery.bindInt(5, getQuery.getColumnInt(0));
- else
- putQuery.bindInt64(5, m_id);
+ // Before this point, don't do any mutation. After this point, don't error out.
- ok = putQuery.step() == SQLResultDone;
- ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
+ int64_t dataRowId = isExistingValue ? getQuery.getColumnInt(0) : -1;
+ putObjectStoreData(sqliteDatabase(), key.get(), value.get(), m_id, &dataRowId);
+
+ int i = 0;
+ for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it, ++i)
+ putIndexData(sqliteDatabase(), indexKeys[i].get(), it->second->id(), dataRowId);
callbacks->onSuccess(key.get());
}
void IDBObjectStoreBackendImpl::remove(PassRefPtr<IDBKey> key, PassRefPtr<IDBCallbacks> callbacks)
{
- SQLiteStatement query(sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key->type()));
+ SQLiteStatement query(sqliteDatabase(), "DELETE FROM ObjectStoreData " + whereClause(key.get()));
bool ok = query.prepare() == SQLResultOk;
ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
@@ -233,10 +240,10 @@ void IDBObjectStoreBackendImpl::createIndex(const String& name, const String& ke
ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
int64_t id = sqliteDatabase().lastInsertRowID();
- RefPtr<IDBIndexBackendInterface> index = IDBIndexBackendImpl::create(this, id, name, keyPath, unique);
+ RefPtr<IDBIndexBackendImpl> index = IDBIndexBackendImpl::create(this, id, name, keyPath, unique);
ASSERT(index->name() == name);
m_indexes.set(name, index);
- callbacks->onSuccess(index.release());
+ callbacks->onSuccess(index.get());
}
PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::index(const String& name)
@@ -244,22 +251,29 @@ PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::index(const Stri
return m_indexes.get(name);
}
-void IDBObjectStoreBackendImpl::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks)
+static void doDelete(SQLiteDatabase& db, const char* sql, int64_t id)
{
- if (!m_indexes.contains(name)) {
- callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Index name does not exist."));
- return;
- }
-
- SQLiteStatement deleteQuery(sqliteDatabase(), "DELETE FROM Indexes WHERE name = ? AND objectStoreId = ?");
+ SQLiteStatement deleteQuery(db, sql);
bool ok = deleteQuery.prepare() == SQLResultOk;
ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
- deleteQuery.bindText(1, name);
- deleteQuery.bindInt64(2, m_id);
+ deleteQuery.bindInt64(1, id);
ok = deleteQuery.step() == SQLResultDone;
ASSERT_UNUSED(ok, ok); // FIXME: Better error handling.
+}
+
+void IDBObjectStoreBackendImpl::removeIndex(const String& name, PassRefPtr<IDBCallbacks> callbacks)
+{
+ RefPtr<IDBIndexBackendImpl> index = m_indexes.get(name);
+ if (!index) {
+ callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::NOT_FOUND_ERR, "Index name does not exist."));
+ return;
+ }
- // FIXME: Delete index data as well.
+ SQLiteTransaction transaction(sqliteDatabase());
+ transaction.begin();
+ doDelete(sqliteDatabase(), "DELETE FROM Indexes WHERE id = ?", index->id());
+ doDelete(sqliteDatabase(), "DELETE FROM IndexData WHERE indexId = ?", index->id());
+ transaction.commit();
m_indexes.remove(name);
callbacks->onSuccess();
@@ -337,9 +351,9 @@ void IDBObjectStoreBackendImpl::openCursor(PassRefPtr<IDBKeyRange> range, unsign
int currentColumn = 1;
if (range->flags() & IDBKeyRange::LEFT_BOUND || range->flags() == IDBKeyRange::SINGLE)
- currentColumn += bindKey(*query, currentColumn, range->left().get());
+ currentColumn += range->left()->bind(*query, currentColumn);
if (range->flags() & IDBKeyRange::RIGHT_BOUND || range->flags() == IDBKeyRange::SINGLE)
- currentColumn += bindKey(*query, currentColumn, range->right().get());
+ currentColumn += range->right()->bind(*query, currentColumn);
query->bindInt64(currentColumn, m_id);
if (query->step() != SQLResultRow) {
diff --git a/WebCore/storage/IDBObjectStoreBackendImpl.h b/WebCore/storage/IDBObjectStoreBackendImpl.h
index e1058c8..32ef920 100644
--- a/WebCore/storage/IDBObjectStoreBackendImpl.h
+++ b/WebCore/storage/IDBObjectStoreBackendImpl.h
@@ -35,6 +35,7 @@
namespace WebCore {
class IDBDatabaseBackendImpl;
+class IDBIndexBackendImpl;
class SQLiteDatabase;
class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface {
@@ -75,7 +76,7 @@ private:
String m_keyPath;
bool m_autoIncrement;
- typedef HashMap<String, RefPtr<IDBIndexBackendInterface> > IndexMap;
+ typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap;
IndexMap m_indexes;
};
diff --git a/WebCore/storage/IDBRequest.cpp b/WebCore/storage/IDBRequest.cpp
index 94ef7e5..3513c17 100644
--- a/WebCore/storage/IDBRequest.cpp
+++ b/WebCore/storage/IDBRequest.cpp
@@ -48,71 +48,72 @@ namespace WebCore {
IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> source)
: ActiveDOMObject(context, this)
, m_source(source)
- , m_result(IDBAny::create())
, m_timer(this, &IDBRequest::timerFired)
, m_aborted(false)
- , m_readyState(INITIAL)
+ , m_readyState(LOADING)
{
}
IDBRequest::~IDBRequest()
{
- if (m_readyState != DONE)
- abort();
+ abort();
+}
+
+bool IDBRequest::resetReadyState()
+{
+ if (m_aborted)
+ return false;
+ ASSERT(m_readyState == DONE);
+ m_readyState = LOADING;
+ return true;
}
void IDBRequest::onError(PassRefPtr<IDBDatabaseError> error)
{
- onEventCommon();
- m_error = error;
+ scheduleEvent(0, error);
}
void IDBRequest::onSuccess()
{
- onEventCommon();
- m_result->set();
+ scheduleEvent(IDBAny::createNull(), 0);
}
void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend)
{
- onEventCommon();
- m_result->set(IDBCursor::create(backend));
+ scheduleEvent(IDBAny::create(IDBCursor::create(backend, this)), 0);
}
void IDBRequest::onSuccess(PassRefPtr<IDBDatabaseBackendInterface> backend)
{
- onEventCommon();
- m_result->set(IDBDatabase::create(backend));
+ scheduleEvent(IDBAny::create(IDBDatabase::create(backend)), 0);
}
void IDBRequest::onSuccess(PassRefPtr<IDBIndexBackendInterface> backend)
{
- onEventCommon();
- m_result->set(IDBIndex::create(backend));
+ scheduleEvent(IDBAny::create(IDBIndex::create(backend)), 0);
}
void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey)
{
- onEventCommon();
- m_result->set(idbKey);
+ scheduleEvent(IDBAny::create(idbKey), 0);
}
void IDBRequest::onSuccess(PassRefPtr<IDBObjectStoreBackendInterface> backend)
{
- onEventCommon();
- m_result->set(IDBObjectStore::create(backend));
+ scheduleEvent(IDBAny::create(IDBObjectStore::create(backend)), 0);
}
void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptValue)
{
- onEventCommon();
- m_result->set(serializedScriptValue);
+ scheduleEvent(IDBAny::create(serializedScriptValue), 0);
}
void IDBRequest::abort()
{
m_timer.stop();
m_aborted = true;
+ m_pendingEvents.clear();
+
// FIXME: This should cancel any pending work being done in the backend.
}
@@ -140,38 +141,47 @@ EventTargetData* IDBRequest::ensureEventTargetData()
void IDBRequest::timerFired(Timer<IDBRequest>*)
{
- ASSERT(m_readyState == DONE);
ASSERT(m_selfRef);
ASSERT(!m_aborted);
+ ASSERT(m_pendingEvents.size());
// We need to keep self-referencing ourself, otherwise it's possible we'll be deleted.
// But in some cases, suspend() could be called while we're dispatching an event, so we
// need to make sure that resume() doesn't re-start the timer based on m_selfRef being set.
RefPtr<IDBRequest> selfRef = m_selfRef.release();
- if (m_error) {
- ASSERT(m_result->type() == IDBAny::UndefinedType);
- dispatchEvent(IDBErrorEvent::create(m_source, *m_error));
- } else {
- ASSERT(m_result->type() != IDBAny::UndefinedType);
- dispatchEvent(IDBSuccessEvent::create(m_source, m_result));
+ Vector<PendingEvent> pendingEvents;
+ pendingEvents.swap(m_pendingEvents);
+ for (size_t i = 0; i < pendingEvents.size(); ++i) {
+ PendingEvent pendingEvent = pendingEvents[i];
+ if (pendingEvent.m_error) {
+ ASSERT(!pendingEvent.m_result);
+ dispatchEvent(IDBErrorEvent::create(m_source, *pendingEvent.m_error));
+ } else {
+ ASSERT(pendingEvent.m_result->type() != IDBAny::UndefinedType);
+ dispatchEvent(IDBSuccessEvent::create(m_source, pendingEvent.m_result));
+ }
}
}
-void IDBRequest::onEventCommon()
+void IDBRequest::scheduleEvent(PassRefPtr<IDBAny> result, PassRefPtr<IDBDatabaseError> error)
{
ASSERT(m_readyState < DONE);
- ASSERT(m_result->type() == IDBAny::UndefinedType);
- ASSERT(!m_error);
- ASSERT(!m_selfRef);
- ASSERT(!m_timer.isActive());
+ ASSERT(!!m_selfRef == m_timer.isActive());
if (m_aborted)
return;
+ PendingEvent pendingEvent;
+ pendingEvent.m_result = result;
+ pendingEvent.m_error = error;
+ m_pendingEvents.append(pendingEvent);
+
m_readyState = DONE;
- m_selfRef = this;
- m_timer.startOneShot(0);
+ if (!m_timer.isActive()) {
+ m_selfRef = this;
+ m_timer.startOneShot(0);
+ }
}
} // namespace WebCore
diff --git a/WebCore/storage/IDBRequest.h b/WebCore/storage/IDBRequest.h
index ddfdcf3..9b0ea7e 100644
--- a/WebCore/storage/IDBRequest.h
+++ b/WebCore/storage/IDBRequest.h
@@ -38,6 +38,7 @@
#include "IDBAny.h"
#include "IDBCallbacks.h"
#include "Timer.h"
+#include <wtf/Vector.h>
namespace WebCore {
@@ -49,16 +50,15 @@ public:
// Defined in the IDL
void abort();
enum ReadyState {
- INITIAL = 0,
LOADING = 1,
DONE = 2
};
unsigned short readyState() const { return m_readyState; }
- PassRefPtr<IDBDatabaseError> error() const { return m_error; }
- PassRefPtr<IDBAny> result() { return m_result; }
DEFINE_ATTRIBUTE_EVENT_LISTENER(success);
DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ bool resetReadyState();
+
// IDBCallbacks
virtual void onError(PassRefPtr<IDBDatabaseError>);
virtual void onSuccess(); // For "null".
@@ -83,7 +83,7 @@ private:
IDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source);
void timerFired(Timer<IDBRequest>*);
- void onEventCommon();
+ void scheduleEvent(PassRefPtr<IDBAny> result, PassRefPtr<IDBDatabaseError>);
// EventTarget
virtual void refEventTarget() { ref(); }
@@ -93,8 +93,11 @@ private:
RefPtr<IDBAny> m_source;
- RefPtr<IDBAny> m_result;
- RefPtr<IDBDatabaseError> m_error;
+ struct PendingEvent {
+ RefPtr<IDBAny> m_result;
+ RefPtr<IDBDatabaseError> m_error;
+ };
+ Vector<PendingEvent> m_pendingEvents;
// Used to fire events asynchronously.
Timer<IDBRequest> m_timer;
diff --git a/WebCore/storage/IDBRequest.idl b/WebCore/storage/IDBRequest.idl
index 9d7e0e4..3036b6b 100644
--- a/WebCore/storage/IDBRequest.idl
+++ b/WebCore/storage/IDBRequest.idl
@@ -35,15 +35,10 @@ module storage {
void abort();
// States
- const unsigned short INITIAL = 0;
const unsigned short LOADING = 1;
const unsigned short DONE = 2;
readonly attribute unsigned short readyState;
- // Possible results
- readonly attribute IDBDatabaseError error;
- readonly attribute IDBAny result;
-
// Events
attribute EventListener onsuccess;
attribute EventListener onerror;
diff --git a/WebCore/storage/IDBTransaction.h b/WebCore/storage/IDBTransaction.h
index 3c7f9dd..0d6f3ea 100644
--- a/WebCore/storage/IDBTransaction.h
+++ b/WebCore/storage/IDBTransaction.h
@@ -54,7 +54,8 @@ public:
enum Mode {
READ_WRITE = 0,
READ_ONLY = 1,
- SNAPSHOT_READ = 2
+ SNAPSHOT_READ = 2,
+ VERSION_CHANGE = 3
};
unsigned short mode() const;
diff --git a/WebCore/storage/IDBTransaction.idl b/WebCore/storage/IDBTransaction.idl
index a3907dc..cdf9f63 100644
--- a/WebCore/storage/IDBTransaction.idl
+++ b/WebCore/storage/IDBTransaction.idl
@@ -33,6 +33,8 @@ module storage {
const unsigned short READ_WRITE = 0;
const unsigned short READ_ONLY = 1;
const unsigned short SNAPSHOT_READ = 2;
+ const unsigned short VERSION_CHANGE = 3;
+
// Properties
readonly attribute unsigned short mode;
readonly attribute IDBDatabase db;
diff --git a/WebCore/svg/SVGAnimateMotionElement.cpp b/WebCore/svg/SVGAnimateMotionElement.cpp
index ffa201b..b50a993 100644
--- a/WebCore/svg/SVGAnimateMotionElement.cpp
+++ b/WebCore/svg/SVGAnimateMotionElement.cpp
@@ -222,6 +222,10 @@ void SVGAnimateMotionElement::applyResultsToTarget()
if (RenderObject* renderer = targetElement->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+ AffineTransform* t = targetElement->supplementalTransform();
+ if (!t)
+ return;
+
// ...except in case where we have additional instances in <use> trees.
const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
@@ -229,7 +233,8 @@ void SVGAnimateMotionElement::applyResultsToTarget()
SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
ASSERT(shadowTreeElement);
AffineTransform* transform = shadowTreeElement->supplementalTransform();
- AffineTransform* t = targetElement->supplementalTransform();
+ if (!transform)
+ continue;
transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f());
if (RenderObject* renderer = shadowTreeElement->renderer()) {
renderer->setNeedsTransformUpdate();
diff --git a/WebCore/svg/SVGDocumentExtensions.cpp b/WebCore/svg/SVGDocumentExtensions.cpp
index 011859a..3fd9761 100644
--- a/WebCore/svg/SVGDocumentExtensions.cpp
+++ b/WebCore/svg/SVGDocumentExtensions.cpp
@@ -156,7 +156,7 @@ void SVGDocumentExtensions::reportError(const String& message)
reportMessage(m_document, ErrorMessageLevel, "Error: " + message);
}
-void SVGDocumentExtensions::addPendingResource(const AtomicString& id, SVGStyledElement* obj)
+void SVGDocumentExtensions::addPendingResource(const AtomicString& id, PassRefPtr<SVGStyledElement> obj)
{
ASSERT(obj);
@@ -166,7 +166,7 @@ void SVGDocumentExtensions::addPendingResource(const AtomicString& id, SVGStyled
if (m_pendingResources.contains(id))
m_pendingResources.get(id)->add(obj);
else {
- HashSet<SVGStyledElement*>* set = new HashSet<SVGStyledElement*>;
+ SVGPendingElements* set = new SVGPendingElements;
set->add(obj);
m_pendingResources.add(id, set);
@@ -181,11 +181,11 @@ bool SVGDocumentExtensions::isPendingResource(const AtomicString& id) const
return m_pendingResources.contains(id);
}
-PassOwnPtr<HashSet<SVGStyledElement*> > SVGDocumentExtensions::removePendingResource(const AtomicString& id)
+PassOwnPtr<HashSet<RefPtr<SVGStyledElement> > > SVGDocumentExtensions::removePendingResource(const AtomicString& id)
{
ASSERT(m_pendingResources.contains(id));
- OwnPtr<HashSet<SVGStyledElement*> > set(m_pendingResources.get(id));
+ OwnPtr<SVGPendingElements> set(m_pendingResources.get(id));
m_pendingResources.remove(id);
return set.release();
}
diff --git a/WebCore/svg/SVGDocumentExtensions.h b/WebCore/svg/SVGDocumentExtensions.h
index e716e10..a0cf2bb 100644
--- a/WebCore/svg/SVGDocumentExtensions.h
+++ b/WebCore/svg/SVGDocumentExtensions.h
@@ -40,6 +40,7 @@ class SVGSVGElement;
class SVGDocumentExtensions : public Noncopyable {
public:
+ typedef HashSet<RefPtr<SVGStyledElement> > SVGPendingElements;
SVGDocumentExtensions(Document*);
~SVGDocumentExtensions();
@@ -64,7 +65,7 @@ private:
Document* m_document; // weak reference
HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general.
HashMap<AtomicString, RenderSVGResourceContainer*> m_resources;
- HashMap<AtomicString, HashSet<SVGStyledElement*>*> m_pendingResources;
+ HashMap<AtomicString, SVGPendingElements*> m_pendingResources;
OwnPtr<SVGResourcesCache> m_resourcesCache;
SVGDocumentExtensions(const SVGDocumentExtensions&);
@@ -74,9 +75,9 @@ public:
// This HashMap contains a list of pending resources. Pending resources, are such
// which are referenced by any object in the SVG document, but do NOT exist yet.
// For instance, dynamically build gradients / patterns / clippers...
- void addPendingResource(const AtomicString& id, SVGStyledElement*);
+ void addPendingResource(const AtomicString& id, PassRefPtr<SVGStyledElement>);
bool isPendingResource(const AtomicString& id) const;
- PassOwnPtr<HashSet<SVGStyledElement*> > removePendingResource(const AtomicString& id);
+ PassOwnPtr<SVGPendingElements> removePendingResource(const AtomicString& id);
};
}
diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp
index ee16e8f..1b19f25 100644
--- a/WebCore/svg/SVGElement.cpp
+++ b/WebCore/svg/SVGElement.cpp
@@ -287,12 +287,12 @@ void SVGElement::insertedIntoDocument()
if (!extensions->isPendingResource(resourceId))
return;
- OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(resourceId));
+ OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions->removePendingResource(resourceId));
if (clients->isEmpty())
return;
- const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
- for (HashSet<SVGStyledElement*>::const_iterator it = clients->begin(); it != end; ++it)
+ const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
+ for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it)
(*it)->buildPendingResource();
}
diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/WebCore/svg/SVGFEDiffuseLightingElement.cpp
index 8c7e7ed..4349f27 100644
--- a/WebCore/svg/SVGFEDiffuseLightingElement.cpp
+++ b/WebCore/svg/SVGFEDiffuseLightingElement.cpp
@@ -75,7 +75,7 @@ void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrN
|| attrName == SVGNames::diffuseConstantAttr
|| attrName == SVGNames::kernelUnitLengthAttr
|| attrName == SVGNames::lighting_colorAttr)
- SVGFilterElement::invalidateFilter(this);
+ invalidate();
}
void SVGFEDiffuseLightingElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp
index 0808ad7..b9d1a3d 100644
--- a/WebCore/svg/SVGFEImageElement.cpp
+++ b/WebCore/svg/SVGFEImageElement.cpp
@@ -26,7 +26,7 @@
#include "Attr.h"
#include "CachedImage.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "RenderObject.h"
#include "RenderSVGResource.h"
@@ -64,7 +64,7 @@ void SVGFEImageElement::requestImageResource()
if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer())
return;
- m_cachedImage = ownerDocument()->docLoader()->requestImage(href());
+ m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(href());
if (m_cachedImage)
m_cachedImage->addClient(this);
diff --git a/WebCore/svg/SVGFELightElement.cpp b/WebCore/svg/SVGFELightElement.cpp
index dc10cf9..61d7df0 100644
--- a/WebCore/svg/SVGFELightElement.cpp
+++ b/WebCore/svg/SVGFELightElement.cpp
@@ -25,6 +25,7 @@
#include "SVGFELightElement.h"
#include "Attribute.h"
+#include "RenderSVGResource.h"
#include "SVGFilterElement.h"
#include "SVGNames.h"
@@ -76,8 +77,13 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
|| attrName == SVGNames::pointsAtYAttr
|| attrName == SVGNames::pointsAtZAttr
|| attrName == SVGNames::specularExponentAttr
- || attrName == SVGNames::limitingConeAngleAttr)
- SVGFilterElement::invalidateFilter(this);
+ || attrName == SVGNames::limitingConeAngleAttr) {
+ if (Node* parentNode = parent()) {
+ RenderObject* renderer = parentNode->renderer();
+ if (renderer && renderer->isSVGResourceFilterPrimitive())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+ }
+ }
}
void SVGFELightElement::synchronizeProperty(const QualifiedName& attrName)
@@ -124,8 +130,13 @@ void SVGFELightElement::childrenChanged(bool changedByParser, Node* beforeChange
{
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!changedByParser)
- SVGFilterElement::invalidateFilter(this);
+ if (!changedByParser) {
+ if (Node* parentNode = parent()) {
+ RenderObject* renderer = parentNode->renderer();
+ if (renderer && renderer->isSVGResourceFilterPrimitive())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+ }
+ }
}
}
diff --git a/WebCore/svg/SVGFEOffsetElement.cpp b/WebCore/svg/SVGFEOffsetElement.cpp
index b27db31..58b4a6a 100644
--- a/WebCore/svg/SVGFEOffsetElement.cpp
+++ b/WebCore/svg/SVGFEOffsetElement.cpp
@@ -57,7 +57,7 @@ void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName)
if (attrName == SVGNames::inAttr
|| attrName == SVGNames::dxAttr
|| attrName == SVGNames::dyAttr)
- SVGFilterElement::invalidateFilter(this);
+ invalidate();
}
void SVGFEOffsetElement::synchronizeProperty(const QualifiedName& attrName)
diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h
index 67d0a47..c228fe7 100644
--- a/WebCore/svg/SVGFilterElement.h
+++ b/WebCore/svg/SVGFilterElement.h
@@ -45,22 +45,6 @@ public:
void setFilterRes(unsigned long filterResX, unsigned long filterResY);
FloatRect filterBoundingBox(const FloatRect&) const;
- static void invalidateFilter(SVGElement* element)
- {
- ASSERT(element);
- if (!element->inDocument())
- return;
- Node* parent = element->parentNode();
- while (parent && !parent->hasTagName(SVGNames::filterTag))
- parent = parent->parentNode();
-
- if (!parent)
- return;
-
- if (RenderObject* object = parent->renderer())
- object->setNeedsLayout(true);
- }
-
private:
SVGFilterElement(const QualifiedName&, Document*);
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
index 07d9241..c2c443e 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -26,6 +26,7 @@
#include "Attribute.h"
#include "FilterEffect.h"
+#include "RenderSVGResourceFilterPrimitive.h"
#include "SVGLength.h"
#include "SVGNames.h"
#include "SVGStyledElement.h"
@@ -70,7 +71,7 @@ void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedNa
|| attrName == SVGNames::widthAttr
|| attrName == SVGNames::heightAttr
|| attrName == SVGNames::resultAttr)
- SVGFilterElement::invalidateFilter(this);
+ invalidate();
}
void SVGFilterPrimitiveStandardAttributes::synchronizeProperty(const QualifiedName& attrName)
@@ -103,7 +104,7 @@ void SVGFilterPrimitiveStandardAttributes::childrenChanged(bool changedByParser,
SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
if (!changedByParser)
- SVGFilterElement::invalidateFilter(this);
+ invalidate();
}
void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(bool primitiveBoundingBoxMode, FilterEffect* filterEffect) const
@@ -136,6 +137,11 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(bool primitiveB
filterEffect->setEffectBoundaries(effectBBox);
}
+RenderObject* SVGFilterPrimitiveStandardAttributes::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderSVGResourceFilterPrimitive(this);
+}
+
}
#endif // ENABLE(SVG)
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
index 2fb41ea..0ffa1c9 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
@@ -23,6 +23,7 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "FilterEffect.h"
+#include "RenderSVGResource.h"
#include "SVGFilterBuilder.h"
#include "SVGFilterElement.h"
#include "SVGNames.h"
@@ -47,10 +48,17 @@ protected:
virtual void synchronizeProperty(const QualifiedName&);
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+protected:
+ inline void invalidate()
+ {
+ if (RenderObject* primitiveRenderer = renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(primitiveRenderer);
+ }
+
private:
virtual bool isFilterEffect() const { return true; }
- virtual bool rendererIsNeeded(RenderStyle*) { return false; }
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::xAttr, SVGLength, X, x)
DECLARE_ANIMATED_PROPERTY(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, SVGLength, Y, y)
diff --git a/WebCore/svg/SVGFontFaceUriElement.cpp b/WebCore/svg/SVGFontFaceUriElement.cpp
index 4d03b2b..3ecba16 100644
--- a/WebCore/svg/SVGFontFaceUriElement.cpp
+++ b/WebCore/svg/SVGFontFaceUriElement.cpp
@@ -26,7 +26,7 @@
#include "Attribute.h"
#include "CSSFontFaceSrcValue.h"
#include "CachedFont.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "SVGFontFaceElement.h"
#include "SVGNames.h"
@@ -94,12 +94,12 @@ void SVGFontFaceUriElement::loadFont()
String href = getAttribute(XLinkNames::hrefAttr);
if (!href.isNull()) {
- DocLoader* docLoader = document()->docLoader();
- m_cachedFont = docLoader->requestFont(href);
+ CachedResourceLoader* cachedResourceLoader = document()->cachedResourceLoader();
+ m_cachedFont = cachedResourceLoader->requestFont(href);
if (m_cachedFont) {
m_cachedFont->setSVGFont(true);
m_cachedFont->addClient(this);
- m_cachedFont->beginLoadIfNeeded(docLoader);
+ m_cachedFont->beginLoadIfNeeded(cachedResourceLoader);
}
} else
m_cachedFont = 0;
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index fc6c9fc..782efa8 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -44,6 +44,7 @@
#include "SVGShadowTreeElements.h"
#include "SVGSymbolElement.h"
#include "XLinkNames.h"
+#include "XMLDocumentParser.h"
#include "XMLSerializer.h"
// Dump SVGElementInstance object tree - useful to debug instanceRoot problems
@@ -120,14 +121,14 @@ void SVGUseElement::insertedIntoDocument()
{
// This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied.
SVGStyledTransformableElement::insertedIntoDocument();
- ASSERT(!m_targetElementInstance);
+ ASSERT(!m_targetElementInstance || ((document()->isSVGDocument() || document()->isXHTMLDocument()) && !static_cast<XMLDocumentParser*>(document()->parser())->wellFormed()));
ASSERT(!m_isPendingResource);
}
void SVGUseElement::removedFromDocument()
{
- m_targetElementInstance = 0;
SVGStyledTransformableElement::removedFromDocument();
+ m_targetElementInstance = 0;
}
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -325,16 +326,16 @@ void SVGUseElement::recalcStyle(StyleChange change)
if (m_updatesBlocked)
ASSERT(!m_needsShadowTreeRecreation);
+ RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer());
+ if (!shadowRoot)
+ return;
+
bool needsStyleUpdate = !m_needsShadowTreeRecreation;
if (m_needsShadowTreeRecreation) {
- static_cast<RenderSVGShadowTreeRootContainer*>(renderer())->markShadowTreeForRecreation();
+ shadowRoot->markShadowTreeForRecreation();
m_needsShadowTreeRecreation = false;
}
- RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer());
- if (!shadowRoot)
- return;
-
shadowRoot->updateFromElement();
if (!needsStyleUpdate)
@@ -608,8 +609,8 @@ void SVGUseElement::attach()
void SVGUseElement::detach()
{
- m_targetElementInstance = 0;
SVGStyledTransformableElement::detach();
+ m_targetElementInstance = 0;
}
static bool isDirectReference(Node* n)
diff --git a/WebCore/thirdparty/README.txt b/WebCore/thirdparty/README.txt
new file mode 100644
index 0000000..311e10a
--- /dev/null
+++ b/WebCore/thirdparty/README.txt
@@ -0,0 +1,12 @@
+This directory is intended to contain copies of third-party libraries used
+by WebCore, in particular those which may require some modification in
+order to incorporate.
+
+The current convention is to fully scope the include paths of headers, in
+order to avoid collisions with other WebCore headers. For example, a file
+in WebCore using the GLU tessellator sources would use
+
+#include "thirdparty/glu/internal_glu.h"
+
+Header references in source files in this directory need to be similarly
+modified.
diff --git a/WebCore/thirdparty/glu/LICENSE.txt b/WebCore/thirdparty/glu/LICENSE.txt
new file mode 100644
index 0000000..e58ae38
--- /dev/null
+++ b/WebCore/thirdparty/glu/LICENSE.txt
@@ -0,0 +1,31 @@
+SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+
+Copyright (C) [dates of first publication] Silicon Graphics, Inc. All
+Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice including the dates of first publication
+and either this permission notice or a reference to HYPERLINK
+"http://oss.sgi.com/projects/FreeB/"http://oss.sgi.com/projects/FreeB/
+shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Silicon Graphics,
+Inc. shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from Silicon Graphics, Inc.
diff --git a/WebCore/thirdparty/glu/README.webkit b/WebCore/thirdparty/glu/README.webkit
new file mode 100644
index 0000000..3fcac84
--- /dev/null
+++ b/WebCore/thirdparty/glu/README.webkit
@@ -0,0 +1,33 @@
+This is a nearly verbatim copy of the GLU tessellator source code from
+SGI's OpenGL Sample Implementation at
+http://oss.sgi.com/projects/ogl-sample/ . Per
+http://oss.sgi.com/projects/FreeB/ , the code is covered under the SGI
+Free Software License B, version 2.0, a copy of which is in
+LICENSE.txt in this directory.
+
+The following changes were made in order to incorporate this code:
+
+ - The addition of a simplified gluos.h to eliminate operating system
+ dependencies.
+
+ - The removal of inclusion of GL/glu.h and replacement with an
+ include of internal_glu.h.
+
+ - Includes were modified to be scoped within thirdparty/glu/ and
+ thirdparty/glu/libtess/.
+
+ - The entry points to the tessellator were prefixed with internal_
+ to avoid symbol collisions with any host OS version of GLU.
+
+ - In tess.c, the obsolete entry points gluBeginPolygon,
+ gluNextContour and gluEndPolygon in tess.c were #if 0'd out.
+ Default branches were added to the switch statements in GotoState.
+
+ - In memalloc.h, the include of malloc.h was changed to an include
+ of stdlib.h.
+
+ - In normal.c, an unused variable "w" was removed from
+ __gl_projectPolygon. #if guards were placed around the definition
+ of the unused Normalize function.
+
+ - In priorityq-heap.c, an #include of <limits.h> was added.
diff --git a/WebCore/thirdparty/glu/gluos.h b/WebCore/thirdparty/glu/gluos.h
new file mode 100644
index 0000000..600dc0b
--- /dev/null
+++ b/WebCore/thirdparty/glu/gluos.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GLUOS_H_
+#define GLUOS_H_
+
+// This header provides the minimal definitions needed to compile the
+// GLU tessellator sources.
+#define GLAPIENTRY
+
+typedef unsigned char GLboolean;
+typedef double GLdouble;
+typedef unsigned int GLenum;
+typedef float GLfloat;
+typedef void GLvoid;
+
+#endif // GLUOS_H_
diff --git a/WebCore/thirdparty/glu/internal_glu.h b/WebCore/thirdparty/glu/internal_glu.h
new file mode 100644
index 0000000..d695b0b
--- /dev/null
+++ b/WebCore/thirdparty/glu/internal_glu.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This header is a skeleton substitute for GL/glu.h which contains
+// only the definitions, constants and function declarations necessary
+// to compile the GLU tessellator.
+
+#ifndef INTERNAL_GLU_H_
+#define INTERNAL_GLU_H_
+
+#include "thirdparty/glu/gluos.h"
+
+/* Primitives */
+#define GL_LINE_LOOP 0x0002
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+
+/* ErrorCode */
+#define GLU_INVALID_ENUM 100900
+#define GLU_INVALID_VALUE 100901
+#define GLU_OUT_OF_MEMORY 100902
+
+/* TessCallback */
+#define GLU_TESS_BEGIN 100100
+#define GLU_BEGIN 100100
+#define GLU_TESS_VERTEX 100101
+#define GLU_VERTEX 100101
+#define GLU_TESS_END 100102
+#define GLU_END 100102
+#define GLU_TESS_ERROR 100103
+#define GLU_TESS_EDGE_FLAG 100104
+#define GLU_EDGE_FLAG 100104
+#define GLU_TESS_COMBINE 100105
+#define GLU_TESS_BEGIN_DATA 100106
+#define GLU_TESS_VERTEX_DATA 100107
+#define GLU_TESS_END_DATA 100108
+#define GLU_TESS_ERROR_DATA 100109
+#define GLU_TESS_EDGE_FLAG_DATA 100110
+#define GLU_TESS_COMBINE_DATA 100111
+
+/* TessContour */
+#define GLU_CW 100120
+#define GLU_CCW 100121
+#define GLU_INTERIOR 100122
+#define GLU_EXTERIOR 100123
+#define GLU_UNKNOWN 100124
+
+/* TessProperty */
+#define GLU_TESS_WINDING_RULE 100140
+#define GLU_TESS_BOUNDARY_ONLY 100141
+#define GLU_TESS_TOLERANCE 100142
+
+/* TessError */
+#define GLU_TESS_ERROR1 100151
+#define GLU_TESS_ERROR2 100152
+#define GLU_TESS_ERROR3 100153
+#define GLU_TESS_ERROR4 100154
+#define GLU_TESS_ERROR5 100155
+#define GLU_TESS_ERROR6 100156
+#define GLU_TESS_ERROR7 100157
+#define GLU_TESS_ERROR8 100158
+#define GLU_TESS_MISSING_BEGIN_POLYGON 100151
+#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152
+#define GLU_TESS_MISSING_END_POLYGON 100153
+#define GLU_TESS_MISSING_END_CONTOUR 100154
+#define GLU_TESS_COORD_TOO_LARGE 100155
+#define GLU_TESS_NEED_COMBINE_CALLBACK 100156
+
+/* TessWinding */
+#define GLU_TESS_WINDING_ODD 100130
+#define GLU_TESS_WINDING_NONZERO 100131
+#define GLU_TESS_WINDING_POSITIVE 100132
+#define GLU_TESS_WINDING_NEGATIVE 100133
+#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134
+
+#define GLU_TESS_MAX_COORD 1.0e150
+
+typedef struct GLUtesselator GLUtesselator;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern GLUtesselator * GLAPIENTRY internal_gluNewTess(void);
+extern void GLAPIENTRY internal_gluDeleteTess(GLUtesselator *tess);
+extern void GLAPIENTRY internal_gluTessProperty(GLUtesselator *tess,
+ GLenum which,
+ GLdouble value);
+extern void GLAPIENTRY internal_gluGetTessProperty(GLUtesselator *tess,
+ GLenum which,
+ GLdouble *value);
+extern void GLAPIENTRY internal_gluTessNormal(GLUtesselator *tess,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+extern void GLAPIENTRY internal_gluTessCallback(GLUtesselator *tess,
+ GLenum which,
+ void (GLAPIENTRY *fn)());
+extern void GLAPIENTRY internal_gluTessVertex(GLUtesselator *tess,
+ GLdouble coords[3],
+ void *data);
+extern void GLAPIENTRY internal_gluTessBeginPolygon(GLUtesselator *tess,
+ void *data);
+extern void GLAPIENTRY internal_gluTessBeginContour(GLUtesselator *tess);
+extern void GLAPIENTRY internal_gluTessEndContour(GLUtesselator *tess);
+extern void GLAPIENTRY internal_gluTessEndPolygon(GLUtesselator *tess);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INTERNAL_GLU_H_
diff --git a/WebCore/thirdparty/glu/libtess/GNUmakefile b/WebCore/thirdparty/glu/libtess/GNUmakefile
new file mode 100644
index 0000000..0ae859f
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/GNUmakefile
@@ -0,0 +1,110 @@
+#!gmake
+#
+# License Applicability. Except to the extent portions of this file are
+# made subject to an alternative license as permitted in the SGI Free
+# Software License B, Version 1.1 (the "License"), the contents of this
+# file are subject only to the provisions of the License. You may not use
+# this file except in compliance with the License. You may obtain a copy
+# of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+# Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+#
+# http://oss.sgi.com/projects/FreeB
+#
+# Note that, as provided in the License, the Software is distributed on an
+# "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+# DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+# CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+# PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+#
+# Original Code. The Original Code is: OpenGL Sample Implementation,
+# Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+# Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+# Copyright in any portions created by third parties is as indicated
+# elsewhere herein. All Rights Reserved.
+#
+# Additional Notice Provisions: The application programming interfaces
+# established by SGI in conjunction with the Original Code are The
+# OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+# April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+# 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+# Window System(R) (Version 1.3), released October 19, 1998. This software
+# was created using the OpenGL(R) version 1.2.1 Sample Implementation
+# published by SGI, but has not been independently verified as being
+# compliant with the OpenGL(R) version 1.2.1 Specification.
+#
+# $Date$ $Revision$
+# $Header: //depot/main/gfx/lib/glu/libtess/GNUmakefile#9 $
+
+OBJECT_STYLE = N32
+
+include $(ROOT)/usr/include/make/commondefs
+
+TARGET = libtess.a
+
+TARGETS = $(TARGET)
+
+LCINCS = -I../include
+
+# Compilation flags:
+#
+# -DNDEBUG is for the production code; it removes all assertion checks
+# (note that <assert.h> looks at this symbol).
+#
+# -DNO_MALLOPT uses regular malloc instead of the mallopt() version.
+# ***** Unless you use this flag, you must use "-lmalloc" to link
+# ***** your application!
+#
+# -DMEMORY_DEBUG turns on the M_DEBUG option of mallopt; this can
+# increase the running time a LOT.
+#
+# -DGLU_TESS_API_FLOAT compiles a single-precision version of the library.
+#
+# -float prevents automatic promotion to double precision; this will produce
+# faster code when compiled with -DGLU_TESS_API_FLOAT.
+#
+# -DNO_BRANCH_CONDITIONS uses & and | instead of && and || on a couple
+# of heavily-used tests (VertEq and VertLeq); some compilers can generate
+# better code with these (use special instructions to avoid branching).
+#
+# -DFOR_TRITE_TEST_PROGRAM is *only* for use with the test program called
+# "trite". It uses some variables which are defined by the test program,
+# so you won't be able to link it with anything else.
+
+HFILES = \
+ dict.h \
+ dict-list.h \
+ geom.h \
+ memalloc.h \
+ mesh.h \
+ normal.h \
+ priorityq-heap.h \
+ priorityq-heap.c \
+ priorityq-sort.h \
+ priorityq.h \
+ render.h \
+ sweep.h \
+ tess.h \
+ tessmono.h \
+ $(NULL)
+
+CFILES = \
+ dict.c \
+ geom.c \
+ memalloc.c \
+ mesh.c \
+ normal.c \
+ priorityq.c \
+ render.c \
+ sweep.c \
+ tess.c \
+ tessmono.c \
+ $(NULL)
+
+default libs libs_install install: $(TARGET)
+
+headers headers_install apps:
+
+$(TARGET): $(OBJECTS)
+ $(AR) crl $@ $(OBJECTS);
+
+include $(COMMONRULES)
diff --git a/WebCore/thirdparty/glu/libtess/Imakefile b/WebCore/thirdparty/glu/libtess/Imakefile
new file mode 100644
index 0000000..fb99ce2
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/Imakefile
@@ -0,0 +1,61 @@
+XCOMM License Applicability. Except to the extent portions of this file are
+XCOMM made subject to an alternative license as permitted in the SGI Free
+XCOMM Software License B, Version 1.1 (the "License"), the contents of this
+XCOMM file are subject only to the provisions of the License. You may not use
+XCOMM this file except in compliance with the License. You may obtain a copy
+XCOMM of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+XCOMM Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+XCOMM
+XCOMM http://oss.sgi.com/projects/FreeB
+XCOMM
+XCOMM Note that, as provided in the License, the Software is distributed on an
+XCOMM "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+XCOMM DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+XCOMM CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+XCOMM PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+XCOMM
+XCOMM Original Code. The Original Code is: OpenGL Sample Implementation,
+XCOMM Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+XCOMM Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+XCOMM Copyright in any portions created by third parties is as indicated
+XCOMM elsewhere herein. All Rights Reserved.
+XCOMM
+XCOMM Additional Notice Provisions: The application programming interfaces
+XCOMM established by SGI in conjunction with the Original Code are The
+XCOMM OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+XCOMM April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+XCOMM 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+XCOMM Window System(R) (Version 1.3), released October 19, 1998. This software
+XCOMM was created using the OpenGL(R) version 1.2.1 Sample Implementation
+XCOMM published by SGI, but has not been independently verified as being
+XCOMM compliant with the OpenGL(R) version 1.2.1 Specification.
+XCOMM
+
+#include <Library.tmpl>
+
+OBJS = \
+ dict.o \
+ geom.o \
+ memalloc.o \
+ mesh.o \
+ normal.o \
+ priorityq.o \
+ render.o \
+ sweep.o \
+ tess.o \
+ tessmono.o
+
+INCLUDES = \
+ -I../include \
+ -I$(TOP)/include \
+ -I$(TOP)/include/GL
+
+DEFINES = \
+ -DNDEBUG
+
+NormalLibraryObjectRule()
+
+NormalLibraryTarget(tess, $(OBJS))
+
+DependTarget()
+CleanTarget()
diff --git a/WebCore/thirdparty/glu/libtess/README b/WebCore/thirdparty/glu/libtess/README
new file mode 100644
index 0000000..59f4ff2
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/README
@@ -0,0 +1,447 @@
+/*
+** $Header: /cvs/projects/ogl-sample/main/gfx/lib/glu/libtess/README,v 1.1 2000/04/26 05:53:59 ljp Exp $
+*/
+
+General Polygon Tesselation
+---------------------------
+
+ This note describes a tesselator for polygons consisting of one or
+ more closed contours. It is backward-compatible with the current
+ OpenGL Utilities tesselator, and is intended to replace it. Here is
+ a summary of the major differences:
+
+ - input contours can be intersecting, self-intersecting, or degenerate.
+
+ - supports a choice of several winding rules for determining which parts
+ of the polygon are on the "interior". This makes it possible to do
+ CSG operations on polygons.
+
+ - boundary extraction: instead of tesselating the polygon, returns a
+ set of closed contours which separate the interior from the exterior.
+
+ - returns the output as a small number of triangle fans and strips,
+ rather than a list of independent triangles (when possible).
+
+ - output is available as an explicit mesh (a quad-edge structure),
+ in addition to the normal callback interface.
+
+ - the algorithm used is extremely robust.
+
+
+The interface
+-------------
+
+ The tesselator state is maintained in a "tesselator object".
+ These are allocated and destroyed using
+
+ GLUtesselator *gluNewTess( void );
+ void gluDeleteTess( GLUtesselator *tess );
+
+ Several tesselator objects may be used simultaneously.
+
+ Inputs
+ ------
+
+ The input contours are specified with the following routines:
+
+ void gluTessBeginPolygon( GLUtesselator *tess );
+ void gluTessBeginContour( GLUtesselator *tess );
+ void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data );
+ void gluTessEndContour( GLUtesselator *tess );
+ void gluTessEndPolygon( GLUtesselator *tess );
+
+ Within each BeginPolygon/EndPolygon pair, there can be zero or more
+ calls to BeginContour/EndContour. Within each contour, there are zero
+ or more calls to gluTessVertex(). The vertices specify a closed
+ contour (the last vertex of each contour is automatically linked to
+ the first).
+
+ "coords" give the coordinates of the vertex in 3-space. For useful
+ results, all vertices should lie in some plane, since the vertices
+ are projected onto a plane before tesselation. "data" is a pointer
+ to a user-defined vertex structure, which typically contains other
+ information such as color, texture coordinates, normal, etc. It is
+ used to refer to the vertex during rendering.
+
+ The library can be compiled in single- or double-precision; the type
+ GLUcoord represents either "float" or "double" accordingly. The GLU
+ version will be available in double-precision only. Compile with
+ GLU_TESS_API_FLOAT defined to get the single-precision version.
+
+ When EndPolygon is called, the tesselation algorithm determines
+ which regions are interior to the given contours, according to one
+ of several "winding rules" described below. The interior regions
+ are then tesselated, and the output is provided as callbacks.
+
+
+ Rendering Callbacks
+ -------------------
+
+ Callbacks are specified by the client using
+
+ void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)());
+
+ If "fn" is NULL, any previously defined callback is discarded.
+
+ The callbacks used to provide output are: /* which == */
+
+ void begin( GLenum type ); /* GLU_TESS_BEGIN */
+ void edgeFlag( GLboolean flag ); /* GLU_TESS_EDGE_FLAG */
+ void vertex( void *data ); /* GLU_TESS_VERTEX */
+ void end( void ); /* GLU_TESS_END */
+
+ Any of the callbacks may be left undefined; if so, the corresponding
+ information will not be supplied during rendering.
+
+ The "begin" callback indicates the start of a primitive; type is one
+ of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the
+ notes on "boundary extraction" below).
+
+ It is followed by any number of "vertex" callbacks, which supply the
+ vertices in the same order as expected by the corresponding glBegin()
+ call. After the last vertex of a given primitive, there is a callback
+ to "end".
+
+ If the "edgeFlag" callback is provided, no triangle fans or strips
+ will be used. When edgeFlag is called, if "flag" is GL_TRUE then each
+ vertex which follows begins an edge which lies on the polygon boundary
+ (ie. an edge which separates an interior region from an exterior one).
+ If "flag" is GL_FALSE, each vertex which follows begins an edge which lies
+ in the polygon interior. "edgeFlag" will be called before the first
+ call to "vertex".
+
+ Other Callbacks
+ ---------------
+
+ void mesh( GLUmesh *mesh ); /* GLU_TESS_MESH */
+
+ - Returns an explicit mesh, represented using the quad-edge structure
+ (Guibas/Stolfi '85). Other implementations of this interface might
+ use a different mesh structure, so this is available only only as an
+ SGI extension. When the mesh is no longer needed, it should be freed
+ using
+
+ void gluDeleteMesh( GLUmesh *mesh );
+
+ There is a brief description of this data structure in the include
+ file "mesh.h". For the full details, see L. Guibas and J. Stolfi,
+ Primitives for the manipulation of general subdivisions and the
+ computation of Voronoi diagrams, ACM Transactions on Graphics,
+ 4(2):74-123, April 1985. For an introduction, see the course notes
+ for CS348a, "Mathematical Foundations of Computer Graphics",
+ available at the Stanford bookstore (and taught during the fall
+ quarter).
+
+ void error( GLenum errno ); /* GLU_TESS_ERROR */
+
+ - errno is one of GLU_TESS_MISSING_BEGIN_POLYGON,
+ GLU_TESS_MISSING_END_POLYGON,
+ GLU_TESS_MISSING_BEGIN_CONTOUR,
+ GLU_TESS_MISSING_END_CONTOUR,
+ GLU_TESS_COORD_TOO_LARGE,
+ GLU_TESS_NEED_COMBINE_CALLBACK
+
+ The first four are obvious. The interface recovers from these
+ errors by inserting the missing call(s).
+
+ GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded
+ the predefined constant GLU_TESS_MAX_COORD in absolute value, and
+ that the value has been clamped. (Coordinate values must be small
+ enough so that two can be multiplied together without overflow.)
+
+ GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an
+ intersection between two edges in the input data, and the "combine"
+ callback (below) was not provided. No output will be generated.
+
+
+ void combine( GLUcoord coords[3], void *data[4], /* GLU_TESS_COMBINE */
+ GLUcoord weight[4], void **outData );
+
+ - When the algorithm detects an intersection, or wishes to merge
+ features, it needs to create a new vertex. The vertex is defined
+ as a linear combination of up to 4 existing vertices, referenced
+ by data[0..3]. The coefficients of the linear combination are
+ given by weight[0..3]; these weights always sum to 1.0. All vertex
+ pointers are valid even when some of the weights are zero.
+ "coords" gives the location of the new vertex.
+
+ The user must allocate another vertex, interpolate parameters
+ using "data" and "weights", and return the new vertex pointer in
+ "outData". This handle is supplied during rendering callbacks.
+ For example, if the polygon lies in an arbitrary plane in 3-space,
+ and we associate a color with each vertex, the combine callback might
+ look like this:
+
+ void myCombine( GLUcoord coords[3], VERTEX *d[4],
+ GLUcoord w[4], VERTEX **dataOut )
+ {
+ VERTEX *new = new_vertex();
+
+ new->x = coords[0];
+ new->y = coords[1];
+ new->z = coords[2];
+ new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r;
+ new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g;
+ new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b;
+ new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a;
+ *dataOut = new;
+ }
+
+ If the algorithm detects an intersection, then the "combine" callback
+ must be defined, and must write a non-NULL pointer into "dataOut".
+ Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no
+ output is generated. This is the only error that can occur during
+ tesselation and rendering.
+
+
+ Control over Tesselation
+ ------------------------
+
+ void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value );
+
+ Properties defined:
+
+ - GLU_TESS_WINDING_RULE. Possible values:
+
+ GLU_TESS_WINDING_ODD
+ GLU_TESS_WINDING_NONZERO
+ GLU_TESS_WINDING_POSITIVE
+ GLU_TESS_WINDING_NEGATIVE
+ GLU_TESS_WINDING_ABS_GEQ_TWO
+
+ The input contours parition the plane into regions. A winding
+ rule determines which of these regions are inside the polygon.
+
+ For a single contour C, the winding number of a point x is simply
+ the signed number of revolutions we make around x as we travel
+ once around C (where CCW is positive). When there are several
+ contours, the individual winding numbers are summed. This
+ procedure associates a signed integer value with each point x in
+ the plane. Note that the winding number is the same for all
+ points in a single region.
+
+ The winding rule classifies a region as "inside" if its winding
+ number belongs to the chosen category (odd, nonzero, positive,
+ negative, or absolute value of at least two). The current GLU
+ tesselator implements the "odd" rule. The "nonzero" rule is another
+ common way to define the interior. The other three rules are
+ useful for polygon CSG operations (see below).
+
+ - GLU_TESS_BOUNDARY_ONLY. Values: TRUE (non-zero) or FALSE (zero).
+
+ If TRUE, returns a set of closed contours which separate the
+ polygon interior and exterior (rather than a tesselation).
+ Exterior contours are oriented CCW with respect to the normal,
+ interior contours are oriented CW. The GLU_TESS_BEGIN callback
+ uses the type GL_LINE_LOOP for each contour.
+
+ - GLU_TESS_TOLERANCE. Value: a real number between 0.0 and 1.0.
+
+ This specifies a tolerance for merging features to reduce the size
+ of the output. For example, two vertices which are very close to
+ each other might be replaced by a single vertex. The tolerance
+ is multiplied by the largest coordinate magnitude of any input vertex;
+ this specifies the maximum distance that any feature can move as the
+ result of a single merge operation. If a single feature takes part
+ in several merge operations, the total distance moved could be larger.
+
+ Feature merging is completely optional; the tolerance is only a hint.
+ The implementation is free to merge in some cases and not in others,
+ or to never merge features at all. The default tolerance is zero.
+
+ The current implementation merges vertices only if they are exactly
+ coincident, regardless of the current tolerance. A vertex is
+ spliced into an edge only if the implementation is unable to
+ distinguish which side of the edge the vertex lies on.
+ Two edges are merged only when both endpoints are identical.
+
+
+ void gluTessNormal( GLUtesselator *tess,
+ GLUcoord x, GLUcoord y, GLUcoord z )
+
+ - Lets the user supply the polygon normal, if known. All input data
+ is projected into a plane perpendicular to the normal before
+ tesselation. All output triangles are oriented CCW with
+ respect to the normal (CW orientation can be obtained by
+ reversing the sign of the supplied normal). For example, if
+ you know that all polygons lie in the x-y plane, call
+ "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons.
+
+ - If the supplied normal is (0,0,0) (the default value), the
+ normal is determined as follows. The direction of the normal,
+ up to its sign, is found by fitting a plane to the vertices,
+ without regard to how the vertices are connected. It is
+ expected that the input data lies approximately in plane;
+ otherwise projection perpendicular to the computed normal may
+ substantially change the geometry. The sign of the normal is
+ chosen so that the sum of the signed areas of all input contours
+ is non-negative (where a CCW contour has positive area).
+
+ - The supplied normal persists until it is changed by another
+ call to gluTessNormal.
+
+
+ Backward compatibility with the GLU tesselator
+ ----------------------------------------------
+
+ The preferred interface is the one described above. The following
+ routines are obsolete, and are provided only for backward compatibility:
+
+ typedef GLUtesselator GLUtriangulatorObj; /* obsolete name */
+
+ void gluBeginPolygon( GLUtesselator *tess );
+ void gluNextContour( GLUtesselator *tess, GLenum type );
+ void gluEndPolygon( GLUtesselator *tess );
+
+ "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or
+ GLU_UNKNOWN. It is ignored by the current GLU tesselator.
+
+ GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined
+ as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END,
+ GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG.
+
+
+Polygon CSG operations
+----------------------
+
+ The features of the tesselator make it easy to find the union, difference,
+ or intersection of several polygons.
+
+ First, assume that each polygon is defined so that the winding number
+ is 0 for each exterior region, and 1 for each interior region. Under
+ this model, CCW contours define the outer boundary of the polygon, and
+ CW contours define holes. Contours may be nested, but a nested
+ contour must be oriented oppositely from the contour that contains it.
+
+ If the original polygons do not satisfy this description, they can be
+ converted to this form by first running the tesselator with the
+ GLU_TESS_BOUNDARY_ONLY property turned on. This returns a list of
+ contours satisfying the restriction above. By allocating two
+ tesselator objects, the callbacks from one tesselator can be fed
+ directly to the input of another.
+
+ Given two or more polygons of the form above, CSG operations can be
+ implemented as follows:
+
+ Union
+ Draw all the input contours as a single polygon. The winding number
+ of each resulting region is the number of original polygons
+ which cover it. The union can be extracted using the
+ GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules.
+ Note that with the nonzero rule, we would get the same result if
+ all contour orientations were reversed.
+
+ Intersection (two polygons at a time only)
+ Draw a single polygon using the contours from both input polygons.
+ Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO. (Since this
+ winding rule looks at the absolute value, reversing all contour
+ orientations does not change the result.)
+
+ Difference
+
+ Suppose we want to compute A \ (B union C union D). Draw a single
+ polygon consisting of the unmodified contours from A, followed by
+ the contours of B,C,D with the vertex order reversed (this changes
+ the winding number of the interior regions to -1). To extract the
+ result, use the GLU_TESS_WINDING_POSITIVE rule.
+
+ If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an
+ alternative to reversing the vertex order is to reverse the sign of
+ the supplied normal. For example in the x-y plane, call
+ gluTessNormal( tess, 0.0, 0.0, -1.0 ).
+
+
+Performance
+-----------
+
+ The tesselator is not intended for immediate-mode rendering; when
+ possible the output should be cached in a user structure or display
+ list. General polygon tesselation is an inherently difficult problem,
+ especially given the goal of extreme robustness.
+
+ The implementation makes an effort to output a small number of fans
+ and strips; this should improve the rendering performance when the
+ output is used in a display list.
+
+ Single-contour input polygons are first tested to see whether they can
+ be rendered as a triangle fan with respect to the first vertex (to
+ avoid running the full decomposition algorithm on convex polygons).
+ Non-convex polygons may be rendered by this "fast path" as well, if
+ the algorithm gets lucky in its choice of a starting vertex.
+
+ For best performance follow these guidelines:
+
+ - supply the polygon normal, if available, using gluTessNormal().
+ This represents about 10% of the computation time. For example,
+ if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1).
+
+ - render many polygons using the same tesselator object, rather than
+ allocating a new tesselator for each one. (In a multi-threaded,
+ multi-processor environment you may get better performance using
+ several tesselators.)
+
+
+Comparison with the GLU tesselator
+----------------------------------
+
+ On polygons which make it through the "fast path", the tesselator is
+ 3 to 5 times faster than the GLU tesselator.
+
+ On polygons which don't make it through the fast path (but which don't
+ have self-intersections or degeneracies), it is about 2 times slower.
+
+ On polygons with self-intersections or degeneraces, there is nothing
+ to compare against.
+
+ The new tesselator generates many more fans and strips, reducing the
+ number of vertices that need to be sent to the hardware.
+
+ Key to the statistics:
+
+ vert number of input vertices on all contours
+ cntr number of input contours
+ tri number of triangles in all output primitives
+ strip number of triangle strips
+ fan number of triangle fans
+ ind number of independent triangles
+ ms number of milliseconds for tesselation
+ (on a 150MHz R4400 Indy)
+
+ Convex polygon examples:
+
+New: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.0459 ms
+Old: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.149 ms
+New: 4 vert, 1 cntr, 2 tri, 0 strip, 1 fan, 0 ind, 0.0459 ms
+Old: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.161 ms
+New: 36 vert, 1 cntr, 34 tri, 0 strip, 1 fan, 0 ind, 0.153 ms
+Old: 36 vert, 1 cntr, 34 tri, 0 strip, 0 fan, 34 ind, 0.621 ms
+
+ Concave single-contour polygons:
+
+New: 5 vert, 1 cntr, 3 tri, 0 strip, 1 fan, 0 ind, 0.052 ms
+Old: 5 vert, 1 cntr, 3 tri, 0 strip, 0 fan, 3 ind, 0.252 ms
+New: 19 vert, 1 cntr, 17 tri, 2 strip, 2 fan, 1 ind, 0.911 ms
+Old: 19 vert, 1 cntr, 17 tri, 0 strip, 0 fan, 17 ind, 0.529 ms
+New: 151 vert, 1 cntr, 149 tri, 13 strip, 18 fan, 3 ind, 6.82 ms
+Old: 151 vert, 1 cntr, 149 tri, 0 strip, 3 fan, 143 ind, 2.7 ms
+New: 574 vert, 1 cntr, 572 tri, 59 strip, 54 fan, 11 ind, 26.6 ms
+Old: 574 vert, 1 cntr, 572 tri, 0 strip, 31 fan, 499 ind, 12.4 ms
+
+ Multiple contours, but no intersections:
+
+New: 7 vert, 2 cntr, 7 tri, 1 strip, 0 fan, 0 ind, 0.527 ms
+Old: 7 vert, 2 cntr, 7 tri, 0 strip, 0 fan, 7 ind, 0.274 ms
+New: 81 vert, 6 cntr, 89 tri, 9 strip, 7 fan, 6 ind, 3.88 ms
+Old: 81 vert, 6 cntr, 89 tri, 0 strip, 13 fan, 61 ind, 2.2 ms
+New: 391 vert, 19 cntr, 413 tri, 37 strip, 32 fan, 26 ind, 20.2 ms
+Old: 391 vert, 19 cntr, 413 tri, 0 strip, 25 fan, 363 ind, 8.68 ms
+
+ Self-intersecting and degenerate examples:
+
+Bowtie: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.483 ms
+Star: 5 vert, 1 cntr, 5 tri, 0 strip, 0 fan, 5 ind, 0.91 ms
+Random: 24 vert, 7 cntr, 46 tri, 2 strip, 12 fan, 7 ind, 5.32 ms
+Font: 333 vert, 2 cntr, 331 tri, 32 strip, 16 fan, 3 ind, 14.1 ms
+: 167 vert, 35 cntr, 254 tri, 8 strip, 56 fan, 52 ind, 46.3 ms
+: 78 vert, 1 cntr, 2675 tri, 148 strip, 207 fan, 180 ind, 243 ms
+: 12480 vert, 2 cntr, 12478 tri, 736 strip,1275 fan, 5 ind, 1010 ms
diff --git a/WebCore/thirdparty/glu/libtess/alg-outline b/WebCore/thirdparty/glu/libtess/alg-outline
new file mode 100644
index 0000000..91ed7f3
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/alg-outline
@@ -0,0 +1,229 @@
+/*
+** $Header: /cvs/projects/ogl-sample/main/gfx/lib/glu/libtess/alg-outline,v 1.1 2000/04/26 05:53:59 ljp Exp $
+*/
+
+This is only a very brief overview. There is quite a bit of
+additional documentation in the source code itself.
+
+
+Goals of robust tesselation
+---------------------------
+
+The tesselation algorithm is fundamentally a 2D algorithm. We
+initially project all data into a plane; our goal is to robustly
+tesselate the projected data. The same topological tesselation is
+then applied to the input data.
+
+Topologically, the output should always be a tesselation. If the
+input is even slightly non-planar, then some triangles will
+necessarily be back-facing when viewed from some angles, but the goal
+is to minimize this effect.
+
+The algorithm needs some capability of cleaning up the input data as
+well as the numerical errors in its own calculations. One way to do
+this is to specify a tolerance as defined above, and clean up the
+input and output during the line sweep process. At the very least,
+the algorithm must handle coincident vertices, vertices incident to an
+edge, and coincident edges.
+
+
+Phases of the algorithm
+-----------------------
+
+1. Find the polygon normal N.
+2. Project the vertex data onto a plane. It does not need to be
+ perpendicular to the normal, eg. we can project onto the plane
+ perpendicular to the coordinate axis whose dot product with N
+ is largest.
+3. Using a line-sweep algorithm, partition the plane into x-monotone
+ regions. Any vertical line intersects an x-monotone region in
+ at most one interval.
+4. Triangulate the x-monotone regions.
+5. Group the triangles into strips and fans.
+
+
+Finding the normal vector
+-------------------------
+
+A common way to find a polygon normal is to compute the signed area
+when the polygon is projected along the three coordinate axes. We
+can't do this, since contours can have zero area without being
+degenerate (eg. a bowtie).
+
+We fit a plane to the vertex data, ignoring how they are connected
+into contours. Ideally this would be a least-squares fit; however for
+our purpose the accuracy of the normal is not important. Instead we
+find three vertices which are widely separated, and compute the normal
+to the triangle they form. The vertices are chosen so that the
+triangle has an area at least 1/sqrt(3) times the largest area of any
+triangle formed using the input vertices.
+
+The contours do affect the orientation of the normal; after computing
+the normal, we check that the sum of the signed contour areas is
+non-negative, and reverse the normal if necessary.
+
+
+Projecting the vertices
+-----------------------
+
+We project the vertices onto a plane perpendicular to one of the three
+coordinate axes. This helps numerical accuracy by removing a
+transformation step between the original input data and the data
+processed by the algorithm. The projection also compresses the input
+data; the 2D distance between vertices after projection may be smaller
+than the original 2D distance. However by choosing the coordinate
+axis whose dot product with the normal is greatest, the compression
+factor is at most 1/sqrt(3).
+
+Even though the *accuracy* of the normal is not that important (since
+we are projecting perpendicular to a coordinate axis anyway), the
+*robustness* of the computation is important. For example, if there
+are many vertices which lie almost along a line, and one vertex V
+which is well-separated from the line, then our normal computation
+should involve V otherwise the results will be garbage.
+
+The advantage of projecting perpendicular to the polygon normal is
+that computed intersection points will be as close as possible to
+their ideal locations. To get this behavior, define TRUE_PROJECT.
+
+
+The Line Sweep
+--------------
+
+There are three data structures: the mesh, the event queue, and the
+edge dictionary.
+
+The mesh is a "quad-edge" data structure which records the topology of
+the current decomposition; for details see the include file "mesh.h".
+
+The event queue simply holds all vertices (both original and computed
+ones), organized so that we can quickly extract the vertex with the
+minimum x-coord (and among those, the one with the minimum y-coord).
+
+The edge dictionary describes the current intersection of the sweep
+line with the regions of the polygon. This is just an ordering of the
+edges which intersect the sweep line, sorted by their current order of
+intersection. For each pair of edges, we store some information about
+the monotone region between them -- these are call "active regions"
+(since they are crossed by the current sweep line).
+
+The basic algorithm is to sweep from left to right, processing each
+vertex. The processed portion of the mesh (left of the sweep line) is
+a planar decomposition. As we cross each vertex, we update the mesh
+and the edge dictionary, then we check any newly adjacent pairs of
+edges to see if they intersect.
+
+A vertex can have any number of edges. Vertices with many edges can
+be created as vertices are merged and intersection points are
+computed. For unprocessed vertices (right of the sweep line), these
+edges are in no particular order around the vertex; for processed
+vertices, the topological ordering should match the geometric ordering.
+
+The vertex processing happens in two phases: first we process are the
+left-going edges (all these edges are currently in the edge
+dictionary). This involves:
+
+ - deleting the left-going edges from the dictionary;
+ - relinking the mesh if necessary, so that the order of these edges around
+ the event vertex matches the order in the dictionary;
+ - marking any terminated regions (regions which lie between two left-going
+ edges) as either "inside" or "outside" according to their winding number.
+
+When there are no left-going edges, and the event vertex is in an
+"interior" region, we need to add an edge (to split the region into
+monotone pieces). To do this we simply join the event vertex to the
+rightmost left endpoint of the upper or lower edge of the containing
+region.
+
+Then we process the right-going edges. This involves:
+
+ - inserting the edges in the edge dictionary;
+ - computing the winding number of any newly created active regions.
+ We can compute this incrementally using the winding of each edge
+ that we cross as we walk through the dictionary.
+ - relinking the mesh if necessary, so that the order of these edges around
+ the event vertex matches the order in the dictionary;
+ - checking any newly adjacent edges for intersection and/or merging.
+
+If there are no right-going edges, again we need to add one to split
+the containing region into monotone pieces. In our case it is most
+convenient to add an edge to the leftmost right endpoint of either
+containing edge; however we may need to change this later (see the
+code for details).
+
+
+Invariants
+----------
+
+These are the most important invariants maintained during the sweep.
+We define a function VertLeq(v1,v2) which defines the order in which
+vertices cross the sweep line, and a function EdgeLeq(e1,e2; loc)
+which says whether e1 is below e2 at the sweep event location "loc".
+This function is defined only at sweep event locations which lie
+between the rightmost left endpoint of {e1,e2}, and the leftmost right
+endpoint of {e1,e2}.
+
+Invariants for the Edge Dictionary.
+
+ - Each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)
+ at any valid location of the sweep event.
+ - If EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2
+ share a common endpoint.
+ - For each e in the dictionary, e->Dst has been processed but not e->Org.
+ - Each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org)
+ where "event" is the current sweep line event.
+ - No edge e has zero length.
+ - No two edges have identical left and right endpoints.
+
+Invariants for the Mesh (the processed portion).
+
+ - The portion of the mesh left of the sweep line is a planar graph,
+ ie. there is *some* way to embed it in the plane.
+ - No processed edge has zero length.
+ - No two processed vertices have identical coordinates.
+ - Each "inside" region is monotone, ie. can be broken into two chains
+ of monotonically increasing vertices according to VertLeq(v1,v2)
+ - a non-invariant: these chains may intersect (slightly) due to
+ numerical errors, but this does not affect the algorithm's operation.
+
+Invariants for the Sweep.
+
+ - If a vertex has any left-going edges, then these must be in the edge
+ dictionary at the time the vertex is processed.
+ - If an edge is marked "fixUpperEdge" (it is a temporary edge introduced
+ by ConnectRightVertex), then it is the only right-going edge from
+ its associated vertex. (This says that these edges exist only
+ when it is necessary.)
+
+
+Robustness
+----------
+
+The key to the robustness of the algorithm is maintaining the
+invariants above, especially the correct ordering of the edge
+dictionary. We achieve this by:
+
+ 1. Writing the numerical computations for maximum precision rather
+ than maximum speed.
+
+ 2. Making no assumptions at all about the results of the edge
+ intersection calculations -- for sufficiently degenerate inputs,
+ the computed location is not much better than a random number.
+
+ 3. When numerical errors violate the invariants, restore them
+ by making *topological* changes when necessary (ie. relinking
+ the mesh structure).
+
+
+Triangulation and Grouping
+--------------------------
+
+We finish the line sweep before doing any triangulation. This is
+because even after a monotone region is complete, there can be further
+changes to its vertex data because of further vertex merging.
+
+After triangulating all monotone regions, we want to group the
+triangles into fans and strips. We do this using a greedy approach.
+The triangulation itself is not optimized to reduce the number of
+primitives; we just try to get a reasonable decomposition of the
+computed triangulation.
diff --git a/WebCore/thirdparty/glu/libtess/dict-list.h b/WebCore/thirdparty/glu/libtess/dict-list.h
new file mode 100644
index 0000000..9c67c49
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/dict-list.h
@@ -0,0 +1,107 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/dict-list.h#5 $
+*/
+
+#ifndef __dict_list_h_
+#define __dict_list_h_
+
+/* Use #define's so that another heap implementation can use this one */
+
+#define DictKey DictListKey
+#define Dict DictList
+#define DictNode DictListNode
+
+#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq)
+#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict)
+
+#define dictSearch(dict,key) __gl_dictListSearch(dict,key)
+#define dictInsert(dict,key) __gl_dictListInsert(dict,key)
+#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key)
+#define dictDelete(dict,node) __gl_dictListDelete(dict,node)
+
+#define dictKey(n) __gl_dictListKey(n)
+#define dictSucc(n) __gl_dictListSucc(n)
+#define dictPred(n) __gl_dictListPred(n)
+#define dictMin(d) __gl_dictListMin(d)
+#define dictMax(d) __gl_dictListMax(d)
+
+
+
+typedef void *DictKey;
+typedef struct Dict Dict;
+typedef struct DictNode DictNode;
+
+Dict *dictNewDict(
+ void *frame,
+ int (*leq)(void *frame, DictKey key1, DictKey key2) );
+
+void dictDeleteDict( Dict *dict );
+
+/* Search returns the node with the smallest key greater than or equal
+ * to the given key. If there is no such key, returns a node whose
+ * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc.
+ */
+DictNode *dictSearch( Dict *dict, DictKey key );
+DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key );
+void dictDelete( Dict *dict, DictNode *node );
+
+#define __gl_dictListKey(n) ((n)->key)
+#define __gl_dictListSucc(n) ((n)->next)
+#define __gl_dictListPred(n) ((n)->prev)
+#define __gl_dictListMin(d) ((d)->head.next)
+#define __gl_dictListMax(d) ((d)->head.prev)
+#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k)))
+
+
+/*** Private data structures ***/
+
+struct DictNode {
+ DictKey key;
+ DictNode *next;
+ DictNode *prev;
+};
+
+struct Dict {
+ DictNode head;
+ void *frame;
+ int (*leq)(void *frame, DictKey key1, DictKey key2);
+};
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/dict.c b/WebCore/thirdparty/glu/libtess/dict.c
new file mode 100644
index 0000000..6c3b27a
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/dict.c
@@ -0,0 +1,117 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/dict.c#5 $
+*/
+
+#include <stddef.h>
+#include "thirdparty/glu/libtess/dict-list.h"
+#include "thirdparty/glu/libtess/memalloc.h"
+
+/* really __gl_dictListNewDict */
+Dict *dictNewDict( void *frame,
+ int (*leq)(void *frame, DictKey key1, DictKey key2) )
+{
+ Dict *dict = (Dict *) memAlloc( sizeof( Dict ));
+ DictNode *head;
+
+ if (dict == NULL) return NULL;
+
+ head = &dict->head;
+
+ head->key = NULL;
+ head->next = head;
+ head->prev = head;
+
+ dict->frame = frame;
+ dict->leq = leq;
+
+ return dict;
+}
+
+/* really __gl_dictListDeleteDict */
+void dictDeleteDict( Dict *dict )
+{
+ DictNode *node;
+
+ for( node = dict->head.next; node != &dict->head; node = node->next ) {
+ memFree( node );
+ }
+ memFree( dict );
+}
+
+/* really __gl_dictListInsertBefore */
+DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key )
+{
+ DictNode *newNode;
+
+ do {
+ node = node->prev;
+ } while( node->key != NULL && ! (*dict->leq)(dict->frame, node->key, key));
+
+ newNode = (DictNode *) memAlloc( sizeof( DictNode ));
+ if (newNode == NULL) return NULL;
+
+ newNode->key = key;
+ newNode->next = node->next;
+ node->next->prev = newNode;
+ newNode->prev = node;
+ node->next = newNode;
+
+ return newNode;
+}
+
+/* really __gl_dictListDelete */
+void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/
+{
+ node->next->prev = node->prev;
+ node->prev->next = node->next;
+ memFree( node );
+}
+
+/* really __gl_dictListSearch */
+DictNode *dictSearch( Dict *dict, DictKey key )
+{
+ DictNode *node = &dict->head;
+
+ do {
+ node = node->next;
+ } while( node->key != NULL && ! (*dict->leq)(dict->frame, key, node->key));
+
+ return node;
+}
diff --git a/WebCore/thirdparty/glu/libtess/dict.h b/WebCore/thirdparty/glu/libtess/dict.h
new file mode 100644
index 0000000..7851bac
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/dict.h
@@ -0,0 +1,107 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/dict.h#5 $
+*/
+
+#ifndef __dict_list_h_
+#define __dict_list_h_
+
+/* Use #define's so that another heap implementation can use this one */
+
+#define DictKey DictListKey
+#define Dict DictList
+#define DictNode DictListNode
+
+#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq)
+#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict)
+
+#define dictSearch(dict,key) __gl_dictListSearch(dict,key)
+#define dictInsert(dict,key) __gl_dictListInsert(dict,key)
+#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key)
+#define dictDelete(dict,node) __gl_dictListDelete(dict,node)
+
+#define dictKey(n) __gl_dictListKey(n)
+#define dictSucc(n) __gl_dictListSucc(n)
+#define dictPred(n) __gl_dictListPred(n)
+#define dictMin(d) __gl_dictListMin(d)
+#define dictMax(d) __gl_dictListMax(d)
+
+
+
+typedef void *DictKey;
+typedef struct Dict Dict;
+typedef struct DictNode DictNode;
+
+Dict *dictNewDict(
+ void *frame,
+ int (*leq)(void *frame, DictKey key1, DictKey key2) );
+
+void dictDeleteDict( Dict *dict );
+
+/* Search returns the node with the smallest key greater than or equal
+ * to the given key. If there is no such key, returns a node whose
+ * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc.
+ */
+DictNode *dictSearch( Dict *dict, DictKey key );
+DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key );
+void dictDelete( Dict *dict, DictNode *node );
+
+#define __gl_dictListKey(n) ((n)->key)
+#define __gl_dictListSucc(n) ((n)->next)
+#define __gl_dictListPred(n) ((n)->prev)
+#define __gl_dictListMin(d) ((d)->head.next)
+#define __gl_dictListMax(d) ((d)->head.prev)
+#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k)))
+
+
+/*** Private data structures ***/
+
+struct DictNode {
+ DictKey key;
+ DictNode *next;
+ DictNode *prev;
+};
+
+struct Dict {
+ DictNode head;
+ void *frame;
+ int (*leq)(void *frame, DictKey key1, DictKey key2);
+};
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/geom.c b/WebCore/thirdparty/glu/libtess/geom.c
new file mode 100644
index 0000000..2db2699
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/geom.c
@@ -0,0 +1,271 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/geom.c#5 $
+*/
+
+#include <assert.h>
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/geom.h"
+
+int __gl_vertLeq( GLUvertex *u, GLUvertex *v )
+{
+ /* Returns TRUE if u is lexicographically <= v. */
+
+ return VertLeq( u, v );
+}
+
+GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
+{
+ /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),
+ * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
+ * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.
+ * If uw is vertical (and thus passes thru v), the result is zero.
+ *
+ * The calculation is extremely accurate and stable, even when v
+ * is very close to u or w. In particular if we set v->t = 0 and
+ * let r be the negated result (this evaluates (uw)(v->s)), then
+ * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t).
+ */
+ GLdouble gapL, gapR;
+
+ assert( VertLeq( u, v ) && VertLeq( v, w ));
+
+ gapL = v->s - u->s;
+ gapR = w->s - v->s;
+
+ if( gapL + gapR > 0 ) {
+ if( gapL < gapR ) {
+ return (v->t - u->t) + (u->t - w->t) * (gapL / (gapL + gapR));
+ } else {
+ return (v->t - w->t) + (w->t - u->t) * (gapR / (gapL + gapR));
+ }
+ }
+ /* vertical line */
+ return 0;
+}
+
+GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
+{
+ /* Returns a number whose sign matches EdgeEval(u,v,w) but which
+ * is cheaper to evaluate. Returns > 0, == 0 , or < 0
+ * as v is above, on, or below the edge uw.
+ */
+ GLdouble gapL, gapR;
+
+ assert( VertLeq( u, v ) && VertLeq( v, w ));
+
+ gapL = v->s - u->s;
+ gapR = w->s - v->s;
+
+ if( gapL + gapR > 0 ) {
+ return (v->t - w->t) * gapL + (v->t - u->t) * gapR;
+ }
+ /* vertical line */
+ return 0;
+}
+
+
+/***********************************************************************
+ * Define versions of EdgeSign, EdgeEval with s and t transposed.
+ */
+
+GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
+{
+ /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w),
+ * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
+ * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v.
+ * If uw is vertical (and thus passes thru v), the result is zero.
+ *
+ * The calculation is extremely accurate and stable, even when v
+ * is very close to u or w. In particular if we set v->s = 0 and
+ * let r be the negated result (this evaluates (uw)(v->t)), then
+ * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s).
+ */
+ GLdouble gapL, gapR;
+
+ assert( TransLeq( u, v ) && TransLeq( v, w ));
+
+ gapL = v->t - u->t;
+ gapR = w->t - v->t;
+
+ if( gapL + gapR > 0 ) {
+ if( gapL < gapR ) {
+ return (v->s - u->s) + (u->s - w->s) * (gapL / (gapL + gapR));
+ } else {
+ return (v->s - w->s) + (w->s - u->s) * (gapR / (gapL + gapR));
+ }
+ }
+ /* vertical line */
+ return 0;
+}
+
+GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
+{
+ /* Returns a number whose sign matches TransEval(u,v,w) but which
+ * is cheaper to evaluate. Returns > 0, == 0 , or < 0
+ * as v is above, on, or below the edge uw.
+ */
+ GLdouble gapL, gapR;
+
+ assert( TransLeq( u, v ) && TransLeq( v, w ));
+
+ gapL = v->t - u->t;
+ gapR = w->t - v->t;
+
+ if( gapL + gapR > 0 ) {
+ return (v->s - w->s) * gapL + (v->s - u->s) * gapR;
+ }
+ /* vertical line */
+ return 0;
+}
+
+
+int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w )
+{
+ /* For almost-degenerate situations, the results are not reliable.
+ * Unless the floating-point arithmetic can be performed without
+ * rounding errors, *any* implementation will give incorrect results
+ * on some degenerate inputs, so the client must have some way to
+ * handle this situation.
+ */
+ return (u->s*(v->t - w->t) + v->s*(w->t - u->t) + w->s*(u->t - v->t)) >= 0;
+}
+
+/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),
+ * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces
+ * this in the rare case that one argument is slightly negative.
+ * The implementation is extremely stable numerically.
+ * In particular it guarantees that the result r satisfies
+ * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate
+ * even when a and b differ greatly in magnitude.
+ */
+#define RealInterpolate(a,x,b,y) \
+ (a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b, \
+ ((a <= b) ? ((b == 0) ? ((x+y) / 2) \
+ : (x + (y-x) * (a/(a+b)))) \
+ : (y + (x-y) * (b/(a+b)))))
+
+#ifndef FOR_TRITE_TEST_PROGRAM
+#define Interpolate(a,x,b,y) RealInterpolate(a,x,b,y)
+#else
+
+/* Claim: the ONLY property the sweep algorithm relies on is that
+ * MIN(x,y) <= r <= MAX(x,y). This is a nasty way to test that.
+ */
+#include <stdlib.h>
+extern int RandomInterpolate;
+
+GLdouble Interpolate( GLdouble a, GLdouble x, GLdouble b, GLdouble y)
+{
+printf("*********************%d\n",RandomInterpolate);
+ if( RandomInterpolate ) {
+ a = 1.2 * drand48() - 0.1;
+ a = (a < 0) ? 0 : ((a > 1) ? 1 : a);
+ b = 1.0 - a;
+ }
+ return RealInterpolate(a,x,b,y);
+}
+
+#endif
+
+#define Swap(a,b) if (1) { GLUvertex *t = a; a = b; b = t; } else
+
+void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
+ GLUvertex *o2, GLUvertex *d2,
+ GLUvertex *v )
+/* Given edges (o1,d1) and (o2,d2), compute their point of intersection.
+ * The computed point is guaranteed to lie in the intersection of the
+ * bounding rectangles defined by each edge.
+ */
+{
+ GLdouble z1, z2;
+
+ /* This is certainly not the most efficient way to find the intersection
+ * of two line segments, but it is very numerically stable.
+ *
+ * Strategy: find the two middle vertices in the VertLeq ordering,
+ * and interpolate the intersection s-value from these. Then repeat
+ * using the TransLeq ordering to find the intersection t-value.
+ */
+
+ if( ! VertLeq( o1, d1 )) { Swap( o1, d1 ); }
+ if( ! VertLeq( o2, d2 )) { Swap( o2, d2 ); }
+ if( ! VertLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
+
+ if( ! VertLeq( o2, d1 )) {
+ /* Technically, no intersection -- do our best */
+ v->s = (o2->s + d1->s) / 2;
+ } else if( VertLeq( d1, d2 )) {
+ /* Interpolate between o2 and d1 */
+ z1 = EdgeEval( o1, o2, d1 );
+ z2 = EdgeEval( o2, d1, d2 );
+ if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
+ v->s = Interpolate( z1, o2->s, z2, d1->s );
+ } else {
+ /* Interpolate between o2 and d2 */
+ z1 = EdgeSign( o1, o2, d1 );
+ z2 = -EdgeSign( o1, d2, d1 );
+ if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
+ v->s = Interpolate( z1, o2->s, z2, d2->s );
+ }
+
+ /* Now repeat the process for t */
+
+ if( ! TransLeq( o1, d1 )) { Swap( o1, d1 ); }
+ if( ! TransLeq( o2, d2 )) { Swap( o2, d2 ); }
+ if( ! TransLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
+
+ if( ! TransLeq( o2, d1 )) {
+ /* Technically, no intersection -- do our best */
+ v->t = (o2->t + d1->t) / 2;
+ } else if( TransLeq( d1, d2 )) {
+ /* Interpolate between o2 and d1 */
+ z1 = TransEval( o1, o2, d1 );
+ z2 = TransEval( o2, d1, d2 );
+ if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
+ v->t = Interpolate( z1, o2->t, z2, d1->t );
+ } else {
+ /* Interpolate between o2 and d2 */
+ z1 = TransSign( o1, o2, d1 );
+ z2 = -TransSign( o1, d2, d1 );
+ if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
+ v->t = Interpolate( z1, o2->t, z2, d2->t );
+ }
+}
diff --git a/WebCore/thirdparty/glu/libtess/geom.h b/WebCore/thirdparty/glu/libtess/geom.h
new file mode 100644
index 0000000..97b7b30
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/geom.h
@@ -0,0 +1,90 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/geom.h#5 $
+*/
+
+#ifndef __geom_h_
+#define __geom_h_
+
+#include "thirdparty/glu/libtess/mesh.h"
+
+#ifdef NO_BRANCH_CONDITIONS
+/* MIPS architecture has special instructions to evaluate boolean
+ * conditions -- more efficient than branching, IF you can get the
+ * compiler to generate the right instructions (SGI compiler doesn't)
+ */
+#define VertEq(u,v) (((u)->s == (v)->s) & ((u)->t == (v)->t))
+#define VertLeq(u,v) (((u)->s < (v)->s) | \
+ ((u)->s == (v)->s & (u)->t <= (v)->t))
+#else
+#define VertEq(u,v) ((u)->s == (v)->s && (u)->t == (v)->t)
+#define VertLeq(u,v) (((u)->s < (v)->s) || \
+ ((u)->s == (v)->s && (u)->t <= (v)->t))
+#endif
+
+#define EdgeEval(u,v,w) __gl_edgeEval(u,v,w)
+#define EdgeSign(u,v,w) __gl_edgeSign(u,v,w)
+
+/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */
+
+#define TransLeq(u,v) (((u)->t < (v)->t) || \
+ ((u)->t == (v)->t && (u)->s <= (v)->s))
+#define TransEval(u,v,w) __gl_transEval(u,v,w)
+#define TransSign(u,v,w) __gl_transSign(u,v,w)
+
+
+#define EdgeGoesLeft(e) VertLeq( (e)->Dst, (e)->Org )
+#define EdgeGoesRight(e) VertLeq( (e)->Org, (e)->Dst )
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#define VertL1dist(u,v) (ABS(u->s - v->s) + ABS(u->t - v->t))
+
+#define VertCCW(u,v,w) __gl_vertCCW(u,v,w)
+
+int __gl_vertLeq( GLUvertex *u, GLUvertex *v );
+GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w );
+GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w );
+GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w );
+GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w );
+int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w );
+void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
+ GLUvertex *o2, GLUvertex *d2,
+ GLUvertex *v );
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/memalloc.c b/WebCore/thirdparty/glu/libtess/memalloc.c
new file mode 100644
index 0000000..b422b66
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/memalloc.c
@@ -0,0 +1,62 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/memalloc.c#5 $
+*/
+
+#include "string.h"
+#include "thirdparty/glu/libtess/memalloc.h"
+
+int __gl_memInit( size_t maxFast )
+{
+#ifndef NO_MALLOPT
+/* mallopt( M_MXFAST, maxFast );*/
+#ifdef MEMORY_DEBUG
+ mallopt( M_DEBUG, 1 );
+#endif
+#endif
+ return 1;
+}
+
+#ifdef MEMORY_DEBUG
+void *__gl_memAlloc( size_t n )
+{
+ return memset( malloc( n ), 0xa5, n );
+}
+#endif
+
diff --git a/WebCore/thirdparty/glu/libtess/memalloc.h b/WebCore/thirdparty/glu/libtess/memalloc.h
new file mode 100644
index 0000000..1e37f7a
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/memalloc.h
@@ -0,0 +1,61 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/memalloc.h#5 $
+*/
+
+#ifndef __memalloc_simple_h_
+#define __memalloc_simple_h_
+
+#include <stdlib.h>
+
+#define memRealloc realloc
+#define memFree free
+
+#define memInit __gl_memInit
+/*extern void __gl_memInit( size_t );*/
+extern int __gl_memInit( size_t );
+
+#ifndef MEMORY_DEBUG
+#define memAlloc malloc
+#else
+#define memAlloc __gl_memAlloc
+extern void * __gl_memAlloc( size_t );
+#endif
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/mesh.c b/WebCore/thirdparty/glu/libtess/mesh.c
new file mode 100644
index 0000000..62ff469
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/mesh.c
@@ -0,0 +1,796 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/mesh.c#6 $
+*/
+
+#include <assert.h>
+#include <stddef.h>
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/memalloc.h"
+#include "thirdparty/glu/libtess/mesh.h"
+
+#define TRUE 1
+#define FALSE 0
+
+static GLUvertex *allocVertex()
+{
+ return (GLUvertex *)memAlloc( sizeof( GLUvertex ));
+}
+
+static GLUface *allocFace()
+{
+ return (GLUface *)memAlloc( sizeof( GLUface ));
+}
+
+/************************ Utility Routines ************************/
+
+/* Allocate and free half-edges in pairs for efficiency.
+ * The *only* place that should use this fact is allocation/free.
+ */
+typedef struct { GLUhalfEdge e, eSym; } EdgePair;
+
+/* MakeEdge creates a new pair of half-edges which form their own loop.
+ * No vertex or face structures are allocated, but these must be assigned
+ * before the current edge operation is completed.
+ */
+static GLUhalfEdge *MakeEdge( GLUhalfEdge *eNext )
+{
+ GLUhalfEdge *e;
+ GLUhalfEdge *eSym;
+ GLUhalfEdge *ePrev;
+ EdgePair *pair = (EdgePair *)memAlloc( sizeof( EdgePair ));
+ if (pair == NULL) return NULL;
+
+ e = &pair->e;
+ eSym = &pair->eSym;
+
+ /* Make sure eNext points to the first edge of the edge pair */
+ if( eNext->Sym < eNext ) { eNext = eNext->Sym; }
+
+ /* Insert in circular doubly-linked list before eNext.
+ * Note that the prev pointer is stored in Sym->next.
+ */
+ ePrev = eNext->Sym->next;
+ eSym->next = ePrev;
+ ePrev->Sym->next = e;
+ e->next = eNext;
+ eNext->Sym->next = eSym;
+
+ e->Sym = eSym;
+ e->Onext = e;
+ e->Lnext = eSym;
+ e->Org = NULL;
+ e->Lface = NULL;
+ e->winding = 0;
+ e->activeRegion = NULL;
+
+ eSym->Sym = e;
+ eSym->Onext = eSym;
+ eSym->Lnext = e;
+ eSym->Org = NULL;
+ eSym->Lface = NULL;
+ eSym->winding = 0;
+ eSym->activeRegion = NULL;
+
+ return e;
+}
+
+/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the
+ * CS348a notes (see mesh.h). Basically it modifies the mesh so that
+ * a->Onext and b->Onext are exchanged. This can have various effects
+ * depending on whether a and b belong to different face or vertex rings.
+ * For more explanation see __gl_meshSplice() below.
+ */
+static void Splice( GLUhalfEdge *a, GLUhalfEdge *b )
+{
+ GLUhalfEdge *aOnext = a->Onext;
+ GLUhalfEdge *bOnext = b->Onext;
+
+ aOnext->Sym->Lnext = b;
+ bOnext->Sym->Lnext = a;
+ a->Onext = bOnext;
+ b->Onext = aOnext;
+}
+
+/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the
+ * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
+ * a place to insert the new vertex in the global vertex list. We insert
+ * the new vertex *before* vNext so that algorithms which walk the vertex
+ * list will not see the newly created vertices.
+ */
+static void MakeVertex( GLUvertex *newVertex,
+ GLUhalfEdge *eOrig, GLUvertex *vNext )
+{
+ GLUhalfEdge *e;
+ GLUvertex *vPrev;
+ GLUvertex *vNew = newVertex;
+
+ assert(vNew != NULL);
+
+ /* insert in circular doubly-linked list before vNext */
+ vPrev = vNext->prev;
+ vNew->prev = vPrev;
+ vPrev->next = vNew;
+ vNew->next = vNext;
+ vNext->prev = vNew;
+
+ vNew->anEdge = eOrig;
+ vNew->data = NULL;
+ /* leave coords, s, t undefined */
+
+ /* fix other edges on this vertex loop */
+ e = eOrig;
+ do {
+ e->Org = vNew;
+ e = e->Onext;
+ } while( e != eOrig );
+}
+
+/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left
+ * face of all edges in the face loop to which eOrig belongs. "fNext" gives
+ * a place to insert the new face in the global face list. We insert
+ * the new face *before* fNext so that algorithms which walk the face
+ * list will not see the newly created faces.
+ */
+static void MakeFace( GLUface *newFace, GLUhalfEdge *eOrig, GLUface *fNext )
+{
+ GLUhalfEdge *e;
+ GLUface *fPrev;
+ GLUface *fNew = newFace;
+
+ assert(fNew != NULL);
+
+ /* insert in circular doubly-linked list before fNext */
+ fPrev = fNext->prev;
+ fNew->prev = fPrev;
+ fPrev->next = fNew;
+ fNew->next = fNext;
+ fNext->prev = fNew;
+
+ fNew->anEdge = eOrig;
+ fNew->data = NULL;
+ fNew->trail = NULL;
+ fNew->marked = FALSE;
+
+ /* The new face is marked "inside" if the old one was. This is a
+ * convenience for the common case where a face has been split in two.
+ */
+ fNew->inside = fNext->inside;
+
+ /* fix other edges on this face loop */
+ e = eOrig;
+ do {
+ e->Lface = fNew;
+ e = e->Lnext;
+ } while( e != eOrig );
+}
+
+/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),
+ * and removes from the global edge list.
+ */
+static void KillEdge( GLUhalfEdge *eDel )
+{
+ GLUhalfEdge *ePrev, *eNext;
+
+ /* Half-edges are allocated in pairs, see EdgePair above */
+ if( eDel->Sym < eDel ) { eDel = eDel->Sym; }
+
+ /* delete from circular doubly-linked list */
+ eNext = eDel->next;
+ ePrev = eDel->Sym->next;
+ eNext->Sym->next = ePrev;
+ ePrev->Sym->next = eNext;
+
+ memFree( eDel );
+}
+
+
+/* KillVertex( vDel ) destroys a vertex and removes it from the global
+ * vertex list. It updates the vertex loop to point to a given new vertex.
+ */
+static void KillVertex( GLUvertex *vDel, GLUvertex *newOrg )
+{
+ GLUhalfEdge *e, *eStart = vDel->anEdge;
+ GLUvertex *vPrev, *vNext;
+
+ /* change the origin of all affected edges */
+ e = eStart;
+ do {
+ e->Org = newOrg;
+ e = e->Onext;
+ } while( e != eStart );
+
+ /* delete from circular doubly-linked list */
+ vPrev = vDel->prev;
+ vNext = vDel->next;
+ vNext->prev = vPrev;
+ vPrev->next = vNext;
+
+ memFree( vDel );
+}
+
+/* KillFace( fDel ) destroys a face and removes it from the global face
+ * list. It updates the face loop to point to a given new face.
+ */
+static void KillFace( GLUface *fDel, GLUface *newLface )
+{
+ GLUhalfEdge *e, *eStart = fDel->anEdge;
+ GLUface *fPrev, *fNext;
+
+ /* change the left face of all affected edges */
+ e = eStart;
+ do {
+ e->Lface = newLface;
+ e = e->Lnext;
+ } while( e != eStart );
+
+ /* delete from circular doubly-linked list */
+ fPrev = fDel->prev;
+ fNext = fDel->next;
+ fNext->prev = fPrev;
+ fPrev->next = fNext;
+
+ memFree( fDel );
+}
+
+
+/****************** Basic Edge Operations **********************/
+
+/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
+ * The loop consists of the two new half-edges.
+ */
+GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh )
+{
+ GLUvertex *newVertex1= allocVertex();
+ GLUvertex *newVertex2= allocVertex();
+ GLUface *newFace= allocFace();
+ GLUhalfEdge *e;
+
+ /* if any one is null then all get freed */
+ if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) {
+ if (newVertex1 != NULL) memFree(newVertex1);
+ if (newVertex2 != NULL) memFree(newVertex2);
+ if (newFace != NULL) memFree(newFace);
+ return NULL;
+ }
+
+ e = MakeEdge( &mesh->eHead );
+ if (e == NULL) return NULL;
+
+ MakeVertex( newVertex1, e, &mesh->vHead );
+ MakeVertex( newVertex2, e->Sym, &mesh->vHead );
+ MakeFace( newFace, e, &mesh->fHead );
+ return e;
+}
+
+
+/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
+ * mesh connectivity and topology. It changes the mesh so that
+ * eOrg->Onext <- OLD( eDst->Onext )
+ * eDst->Onext <- OLD( eOrg->Onext )
+ * where OLD(...) means the value before the meshSplice operation.
+ *
+ * This can have two effects on the vertex structure:
+ * - if eOrg->Org != eDst->Org, the two vertices are merged together
+ * - if eOrg->Org == eDst->Org, the origin is split into two vertices
+ * In both cases, eDst->Org is changed and eOrg->Org is untouched.
+ *
+ * Similarly (and independently) for the face structure,
+ * - if eOrg->Lface == eDst->Lface, one loop is split into two
+ * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
+ * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
+ *
+ * Some special cases:
+ * If eDst == eOrg, the operation has no effect.
+ * If eDst == eOrg->Lnext, the new face will have a single edge.
+ * If eDst == eOrg->Lprev, the old face will have a single edge.
+ * If eDst == eOrg->Onext, the new vertex will have a single edge.
+ * If eDst == eOrg->Oprev, the old vertex will have a single edge.
+ */
+int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst )
+{
+ int joiningLoops = FALSE;
+ int joiningVertices = FALSE;
+
+ if( eOrg == eDst ) return 1;
+
+ if( eDst->Org != eOrg->Org ) {
+ /* We are merging two disjoint vertices -- destroy eDst->Org */
+ joiningVertices = TRUE;
+ KillVertex( eDst->Org, eOrg->Org );
+ }
+ if( eDst->Lface != eOrg->Lface ) {
+ /* We are connecting two disjoint loops -- destroy eDst->Lface */
+ joiningLoops = TRUE;
+ KillFace( eDst->Lface, eOrg->Lface );
+ }
+
+ /* Change the edge structure */
+ Splice( eDst, eOrg );
+
+ if( ! joiningVertices ) {
+ GLUvertex *newVertex= allocVertex();
+ if (newVertex == NULL) return 0;
+
+ /* We split one vertex into two -- the new vertex is eDst->Org.
+ * Make sure the old vertex points to a valid half-edge.
+ */
+ MakeVertex( newVertex, eDst, eOrg->Org );
+ eOrg->Org->anEdge = eOrg;
+ }
+ if( ! joiningLoops ) {
+ GLUface *newFace= allocFace();
+ if (newFace == NULL) return 0;
+
+ /* We split one loop into two -- the new loop is eDst->Lface.
+ * Make sure the old face points to a valid half-edge.
+ */
+ MakeFace( newFace, eDst, eOrg->Lface );
+ eOrg->Lface->anEdge = eOrg;
+ }
+
+ return 1;
+}
+
+
+/* __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
+ * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
+ * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
+ * the newly created loop will contain eDel->Dst. If the deletion of eDel
+ * would create isolated vertices, those are deleted as well.
+ *
+ * This function could be implemented as two calls to __gl_meshSplice
+ * plus a few calls to memFree, but this would allocate and delete
+ * unnecessary vertices and faces.
+ */
+int __gl_meshDelete( GLUhalfEdge *eDel )
+{
+ GLUhalfEdge *eDelSym = eDel->Sym;
+ int joiningLoops = FALSE;
+
+ /* First step: disconnect the origin vertex eDel->Org. We make all
+ * changes to get a consistent mesh in this "intermediate" state.
+ */
+ if( eDel->Lface != eDel->Rface ) {
+ /* We are joining two loops into one -- remove the left face */
+ joiningLoops = TRUE;
+ KillFace( eDel->Lface, eDel->Rface );
+ }
+
+ if( eDel->Onext == eDel ) {
+ KillVertex( eDel->Org, NULL );
+ } else {
+ /* Make sure that eDel->Org and eDel->Rface point to valid half-edges */
+ eDel->Rface->anEdge = eDel->Oprev;
+ eDel->Org->anEdge = eDel->Onext;
+
+ Splice( eDel, eDel->Oprev );
+ if( ! joiningLoops ) {
+ GLUface *newFace= allocFace();
+ if (newFace == NULL) return 0;
+
+ /* We are splitting one loop into two -- create a new loop for eDel. */
+ MakeFace( newFace, eDel, eDel->Lface );
+ }
+ }
+
+ /* Claim: the mesh is now in a consistent state, except that eDel->Org
+ * may have been deleted. Now we disconnect eDel->Dst.
+ */
+ if( eDelSym->Onext == eDelSym ) {
+ KillVertex( eDelSym->Org, NULL );
+ KillFace( eDelSym->Lface, NULL );
+ } else {
+ /* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */
+ eDel->Lface->anEdge = eDelSym->Oprev;
+ eDelSym->Org->anEdge = eDelSym->Onext;
+ Splice( eDelSym, eDelSym->Oprev );
+ }
+
+ /* Any isolated vertices or faces have already been freed. */
+ KillEdge( eDel );
+
+ return 1;
+}
+
+
+/******************** Other Edge Operations **********************/
+
+/* All these routines can be implemented with the basic edge
+ * operations above. They are provided for convenience and efficiency.
+ */
+
+
+/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
+ * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
+ * eOrg and eNew will have the same left face.
+ */
+GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg )
+{
+ GLUhalfEdge *eNewSym;
+ GLUhalfEdge *eNew = MakeEdge( eOrg );
+ if (eNew == NULL) return NULL;
+
+ eNewSym = eNew->Sym;
+
+ /* Connect the new edge appropriately */
+ Splice( eNew, eOrg->Lnext );
+
+ /* Set the vertex and face information */
+ eNew->Org = eOrg->Dst;
+ {
+ GLUvertex *newVertex= allocVertex();
+ if (newVertex == NULL) return NULL;
+
+ MakeVertex( newVertex, eNewSym, eNew->Org );
+ }
+ eNew->Lface = eNewSym->Lface = eOrg->Lface;
+
+ return eNew;
+}
+
+
+/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
+ * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.
+ * eOrg and eNew will have the same left face.
+ */
+GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg )
+{
+ GLUhalfEdge *eNew;
+ GLUhalfEdge *tempHalfEdge= __gl_meshAddEdgeVertex( eOrg );
+ if (tempHalfEdge == NULL) return NULL;
+
+ eNew = tempHalfEdge->Sym;
+
+ /* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */
+ Splice( eOrg->Sym, eOrg->Sym->Oprev );
+ Splice( eOrg->Sym, eNew );
+
+ /* Set the vertex and face information */
+ eOrg->Dst = eNew->Org;
+ eNew->Dst->anEdge = eNew->Sym; /* may have pointed to eOrg->Sym */
+ eNew->Rface = eOrg->Rface;
+ eNew->winding = eOrg->winding; /* copy old winding information */
+ eNew->Sym->winding = eOrg->Sym->winding;
+
+ return eNew;
+}
+
+
+/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
+ * to eDst->Org, and returns the corresponding half-edge eNew.
+ * If eOrg->Lface == eDst->Lface, this splits one loop into two,
+ * and the newly created loop is eNew->Lface. Otherwise, two disjoint
+ * loops are merged into one, and the loop eDst->Lface is destroyed.
+ *
+ * If (eOrg == eDst), the new face will have only two edges.
+ * If (eOrg->Lnext == eDst), the old face is reduced to a single edge.
+ * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.
+ */
+GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst )
+{
+ GLUhalfEdge *eNewSym;
+ int joiningLoops = FALSE;
+ GLUhalfEdge *eNew = MakeEdge( eOrg );
+ if (eNew == NULL) return NULL;
+
+ eNewSym = eNew->Sym;
+
+ if( eDst->Lface != eOrg->Lface ) {
+ /* We are connecting two disjoint loops -- destroy eDst->Lface */
+ joiningLoops = TRUE;
+ KillFace( eDst->Lface, eOrg->Lface );
+ }
+
+ /* Connect the new edge appropriately */
+ Splice( eNew, eOrg->Lnext );
+ Splice( eNewSym, eDst );
+
+ /* Set the vertex and face information */
+ eNew->Org = eOrg->Dst;
+ eNewSym->Org = eDst->Org;
+ eNew->Lface = eNewSym->Lface = eOrg->Lface;
+
+ /* Make sure the old face points to a valid half-edge */
+ eOrg->Lface->anEdge = eNewSym;
+
+ if( ! joiningLoops ) {
+ GLUface *newFace= allocFace();
+ if (newFace == NULL) return NULL;
+
+ /* We split one loop into two -- the new loop is eNew->Lface */
+ MakeFace( newFace, eNew, eOrg->Lface );
+ }
+ return eNew;
+}
+
+
+/******************** Other Operations **********************/
+
+/* __gl_meshZapFace( fZap ) destroys a face and removes it from the
+ * global face list. All edges of fZap will have a NULL pointer as their
+ * left face. Any edges which also have a NULL pointer as their right face
+ * are deleted entirely (along with any isolated vertices this produces).
+ * An entire mesh can be deleted by zapping its faces, one at a time,
+ * in any order. Zapped faces cannot be used in further mesh operations!
+ */
+void __gl_meshZapFace( GLUface *fZap )
+{
+ GLUhalfEdge *eStart = fZap->anEdge;
+ GLUhalfEdge *e, *eNext, *eSym;
+ GLUface *fPrev, *fNext;
+
+ /* walk around face, deleting edges whose right face is also NULL */
+ eNext = eStart->Lnext;
+ do {
+ e = eNext;
+ eNext = e->Lnext;
+
+ e->Lface = NULL;
+ if( e->Rface == NULL ) {
+ /* delete the edge -- see __gl_MeshDelete above */
+
+ if( e->Onext == e ) {
+ KillVertex( e->Org, NULL );
+ } else {
+ /* Make sure that e->Org points to a valid half-edge */
+ e->Org->anEdge = e->Onext;
+ Splice( e, e->Oprev );
+ }
+ eSym = e->Sym;
+ if( eSym->Onext == eSym ) {
+ KillVertex( eSym->Org, NULL );
+ } else {
+ /* Make sure that eSym->Org points to a valid half-edge */
+ eSym->Org->anEdge = eSym->Onext;
+ Splice( eSym, eSym->Oprev );
+ }
+ KillEdge( e );
+ }
+ } while( e != eStart );
+
+ /* delete from circular doubly-linked list */
+ fPrev = fZap->prev;
+ fNext = fZap->next;
+ fNext->prev = fPrev;
+ fPrev->next = fNext;
+
+ memFree( fZap );
+}
+
+
+/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
+ * and no loops (what we usually call a "face").
+ */
+GLUmesh *__gl_meshNewMesh( void )
+{
+ GLUvertex *v;
+ GLUface *f;
+ GLUhalfEdge *e;
+ GLUhalfEdge *eSym;
+ GLUmesh *mesh = (GLUmesh *)memAlloc( sizeof( GLUmesh ));
+ if (mesh == NULL) {
+ return NULL;
+ }
+
+ v = &mesh->vHead;
+ f = &mesh->fHead;
+ e = &mesh->eHead;
+ eSym = &mesh->eHeadSym;
+
+ v->next = v->prev = v;
+ v->anEdge = NULL;
+ v->data = NULL;
+
+ f->next = f->prev = f;
+ f->anEdge = NULL;
+ f->data = NULL;
+ f->trail = NULL;
+ f->marked = FALSE;
+ f->inside = FALSE;
+
+ e->next = e;
+ e->Sym = eSym;
+ e->Onext = NULL;
+ e->Lnext = NULL;
+ e->Org = NULL;
+ e->Lface = NULL;
+ e->winding = 0;
+ e->activeRegion = NULL;
+
+ eSym->next = eSym;
+ eSym->Sym = e;
+ eSym->Onext = NULL;
+ eSym->Lnext = NULL;
+ eSym->Org = NULL;
+ eSym->Lface = NULL;
+ eSym->winding = 0;
+ eSym->activeRegion = NULL;
+
+ return mesh;
+}
+
+
+/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
+ * both meshes, and returns the new mesh (the old meshes are destroyed).
+ */
+GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 )
+{
+ GLUface *f1 = &mesh1->fHead;
+ GLUvertex *v1 = &mesh1->vHead;
+ GLUhalfEdge *e1 = &mesh1->eHead;
+ GLUface *f2 = &mesh2->fHead;
+ GLUvertex *v2 = &mesh2->vHead;
+ GLUhalfEdge *e2 = &mesh2->eHead;
+
+ /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */
+ if( f2->next != f2 ) {
+ f1->prev->next = f2->next;
+ f2->next->prev = f1->prev;
+ f2->prev->next = f1;
+ f1->prev = f2->prev;
+ }
+
+ if( v2->next != v2 ) {
+ v1->prev->next = v2->next;
+ v2->next->prev = v1->prev;
+ v2->prev->next = v1;
+ v1->prev = v2->prev;
+ }
+
+ if( e2->next != e2 ) {
+ e1->Sym->next->Sym->next = e2->next;
+ e2->next->Sym->next = e1->Sym->next;
+ e2->Sym->next->Sym->next = e1;
+ e1->Sym->next = e2->Sym->next;
+ }
+
+ memFree( mesh2 );
+ return mesh1;
+}
+
+
+#ifdef DELETE_BY_ZAPPING
+
+/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
+ */
+void __gl_meshDeleteMesh( GLUmesh *mesh )
+{
+ GLUface *fHead = &mesh->fHead;
+
+ while( fHead->next != fHead ) {
+ __gl_meshZapFace( fHead->next );
+ }
+ assert( mesh->vHead.next == &mesh->vHead );
+
+ memFree( mesh );
+}
+
+#else
+
+/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
+ */
+void __gl_meshDeleteMesh( GLUmesh *mesh )
+{
+ GLUface *f, *fNext;
+ GLUvertex *v, *vNext;
+ GLUhalfEdge *e, *eNext;
+
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) {
+ fNext = f->next;
+ memFree( f );
+ }
+
+ for( v = mesh->vHead.next; v != &mesh->vHead; v = vNext ) {
+ vNext = v->next;
+ memFree( v );
+ }
+
+ for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
+ /* One call frees both e and e->Sym (see EdgePair above) */
+ eNext = e->next;
+ memFree( e );
+ }
+
+ memFree( mesh );
+}
+
+#endif
+
+#ifndef NDEBUG
+
+/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
+ */
+void __gl_meshCheckMesh( GLUmesh *mesh )
+{
+ GLUface *fHead = &mesh->fHead;
+ GLUvertex *vHead = &mesh->vHead;
+ GLUhalfEdge *eHead = &mesh->eHead;
+ GLUface *f, *fPrev;
+ GLUvertex *v, *vPrev;
+ GLUhalfEdge *e, *ePrev;
+
+ fPrev = fHead;
+ for( fPrev = fHead ; (f = fPrev->next) != fHead; fPrev = f) {
+ assert( f->prev == fPrev );
+ e = f->anEdge;
+ do {
+ assert( e->Sym != e );
+ assert( e->Sym->Sym == e );
+ assert( e->Lnext->Onext->Sym == e );
+ assert( e->Onext->Sym->Lnext == e );
+ assert( e->Lface == f );
+ e = e->Lnext;
+ } while( e != f->anEdge );
+ }
+ assert( f->prev == fPrev && f->anEdge == NULL && f->data == NULL );
+
+ vPrev = vHead;
+ for( vPrev = vHead ; (v = vPrev->next) != vHead; vPrev = v) {
+ assert( v->prev == vPrev );
+ e = v->anEdge;
+ do {
+ assert( e->Sym != e );
+ assert( e->Sym->Sym == e );
+ assert( e->Lnext->Onext->Sym == e );
+ assert( e->Onext->Sym->Lnext == e );
+ assert( e->Org == v );
+ e = e->Onext;
+ } while( e != v->anEdge );
+ }
+ assert( v->prev == vPrev && v->anEdge == NULL && v->data == NULL );
+
+ ePrev = eHead;
+ for( ePrev = eHead ; (e = ePrev->next) != eHead; ePrev = e) {
+ assert( e->Sym->next == ePrev->Sym );
+ assert( e->Sym != e );
+ assert( e->Sym->Sym == e );
+ assert( e->Org != NULL );
+ assert( e->Dst != NULL );
+ assert( e->Lnext->Onext->Sym == e );
+ assert( e->Onext->Sym->Lnext == e );
+ }
+ assert( e->Sym->next == ePrev->Sym
+ && e->Sym == &mesh->eHeadSym
+ && e->Sym->Sym == e
+ && e->Org == NULL && e->Dst == NULL
+ && e->Lface == NULL && e->Rface == NULL );
+}
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/mesh.h b/WebCore/thirdparty/glu/libtess/mesh.h
new file mode 100644
index 0000000..4d2bcd1
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/mesh.h
@@ -0,0 +1,273 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/mesh.h#5 $
+*/
+
+#ifndef __mesh_h_
+#define __mesh_h_
+
+#include "thirdparty/glu/internal_glu.h"
+
+typedef struct GLUmesh GLUmesh;
+
+typedef struct GLUvertex GLUvertex;
+typedef struct GLUface GLUface;
+typedef struct GLUhalfEdge GLUhalfEdge;
+
+typedef struct ActiveRegion ActiveRegion; /* Internal data */
+
+/* The mesh structure is similar in spirit, notation, and operations
+ * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives
+ * for the manipulation of general subdivisions and the computation of
+ * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985).
+ * For a simplified description, see the course notes for CS348a,
+ * "Mathematical Foundations of Computer Graphics", available at the
+ * Stanford bookstore (and taught during the fall quarter).
+ * The implementation also borrows a tiny subset of the graph-based approach
+ * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction
+ * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988).
+ *
+ * The fundamental data structure is the "half-edge". Two half-edges
+ * go together to make an edge, but they point in opposite directions.
+ * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym),
+ * its origin vertex (Org), the face on its left side (Lface), and the
+ * adjacent half-edges in the CCW direction around the origin vertex
+ * (Onext) and around the left face (Lnext). There is also a "next"
+ * pointer for the global edge list (see below).
+ *
+ * The notation used for mesh navigation:
+ * Sym = the mate of a half-edge (same edge, but opposite direction)
+ * Onext = edge CCW around origin vertex (keep same origin)
+ * Dnext = edge CCW around destination vertex (keep same dest)
+ * Lnext = edge CCW around left face (dest becomes new origin)
+ * Rnext = edge CCW around right face (origin becomes new dest)
+ *
+ * "prev" means to substitute CW for CCW in the definitions above.
+ *
+ * The mesh keeps global lists of all vertices, faces, and edges,
+ * stored as doubly-linked circular lists with a dummy header node.
+ * The mesh stores pointers to these dummy headers (vHead, fHead, eHead).
+ *
+ * The circular edge list is special; since half-edges always occur
+ * in pairs (e and e->Sym), each half-edge stores a pointer in only
+ * one direction. Starting at eHead and following the e->next pointers
+ * will visit each *edge* once (ie. e or e->Sym, but not both).
+ * e->Sym stores a pointer in the opposite direction, thus it is
+ * always true that e->Sym->next->Sym->next == e.
+ *
+ * Each vertex has a pointer to next and previous vertices in the
+ * circular list, and a pointer to a half-edge with this vertex as
+ * the origin (NULL if this is the dummy header). There is also a
+ * field "data" for client data.
+ *
+ * Each face has a pointer to the next and previous faces in the
+ * circular list, and a pointer to a half-edge with this face as
+ * the left face (NULL if this is the dummy header). There is also
+ * a field "data" for client data.
+ *
+ * Note that what we call a "face" is really a loop; faces may consist
+ * of more than one loop (ie. not simply connected), but there is no
+ * record of this in the data structure. The mesh may consist of
+ * several disconnected regions, so it may not be possible to visit
+ * the entire mesh by starting at a half-edge and traversing the edge
+ * structure.
+ *
+ * The mesh does NOT support isolated vertices; a vertex is deleted along
+ * with its last edge. Similarly when two faces are merged, one of the
+ * faces is deleted (see __gl_meshDelete below). For mesh operations,
+ * all face (loop) and vertex pointers must not be NULL. However, once
+ * mesh manipulation is finished, __gl_MeshZapFace can be used to delete
+ * faces of the mesh, one at a time. All external faces can be "zapped"
+ * before the mesh is returned to the client; then a NULL face indicates
+ * a region which is not part of the output polygon.
+ */
+
+struct GLUvertex {
+ GLUvertex *next; /* next vertex (never NULL) */
+ GLUvertex *prev; /* previous vertex (never NULL) */
+ GLUhalfEdge *anEdge; /* a half-edge with this origin */
+ void *data; /* client's data */
+
+ /* Internal data (keep hidden) */
+ GLdouble coords[3]; /* vertex location in 3D */
+ GLdouble s, t; /* projection onto the sweep plane */
+ long pqHandle; /* to allow deletion from priority queue */
+};
+
+struct GLUface {
+ GLUface *next; /* next face (never NULL) */
+ GLUface *prev; /* previous face (never NULL) */
+ GLUhalfEdge *anEdge; /* a half edge with this left face */
+ void *data; /* room for client's data */
+
+ /* Internal data (keep hidden) */
+ GLUface *trail; /* "stack" for conversion to strips */
+ GLboolean marked; /* flag for conversion to strips */
+ GLboolean inside; /* this face is in the polygon interior */
+};
+
+struct GLUhalfEdge {
+ GLUhalfEdge *next; /* doubly-linked list (prev==Sym->next) */
+ GLUhalfEdge *Sym; /* same edge, opposite direction */
+ GLUhalfEdge *Onext; /* next edge CCW around origin */
+ GLUhalfEdge *Lnext; /* next edge CCW around left face */
+ GLUvertex *Org; /* origin vertex (Overtex too long) */
+ GLUface *Lface; /* left face */
+
+ /* Internal data (keep hidden) */
+ ActiveRegion *activeRegion; /* a region with this upper edge (sweep.c) */
+ int winding; /* change in winding number when crossing
+ from the right face to the left face */
+};
+
+#define Rface Sym->Lface
+#define Dst Sym->Org
+
+#define Oprev Sym->Lnext
+#define Lprev Onext->Sym
+#define Dprev Lnext->Sym
+#define Rprev Sym->Onext
+#define Dnext Rprev->Sym /* 3 pointers */
+#define Rnext Oprev->Sym /* 3 pointers */
+
+
+struct GLUmesh {
+ GLUvertex vHead; /* dummy header for vertex list */
+ GLUface fHead; /* dummy header for face list */
+ GLUhalfEdge eHead; /* dummy header for edge list */
+ GLUhalfEdge eHeadSym; /* and its symmetric counterpart */
+};
+
+/* The mesh operations below have three motivations: completeness,
+ * convenience, and efficiency. The basic mesh operations are MakeEdge,
+ * Splice, and Delete. All the other edge operations can be implemented
+ * in terms of these. The other operations are provided for convenience
+ * and/or efficiency.
+ *
+ * When a face is split or a vertex is added, they are inserted into the
+ * global list *before* the existing vertex or face (ie. e->Org or e->Lface).
+ * This makes it easier to process all vertices or faces in the global lists
+ * without worrying about processing the same data twice. As a convenience,
+ * when a face is split, the "inside" flag is copied from the old face.
+ * Other internal data (v->data, v->activeRegion, f->data, f->marked,
+ * f->trail, e->winding) is set to zero.
+ *
+ * ********************** Basic Edge Operations **************************
+ *
+ * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop.
+ * The loop (face) consists of the two new half-edges.
+ *
+ * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
+ * mesh connectivity and topology. It changes the mesh so that
+ * eOrg->Onext <- OLD( eDst->Onext )
+ * eDst->Onext <- OLD( eOrg->Onext )
+ * where OLD(...) means the value before the meshSplice operation.
+ *
+ * This can have two effects on the vertex structure:
+ * - if eOrg->Org != eDst->Org, the two vertices are merged together
+ * - if eOrg->Org == eDst->Org, the origin is split into two vertices
+ * In both cases, eDst->Org is changed and eOrg->Org is untouched.
+ *
+ * Similarly (and independently) for the face structure,
+ * - if eOrg->Lface == eDst->Lface, one loop is split into two
+ * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
+ * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
+ *
+ * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
+ * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
+ * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
+ * the newly created loop will contain eDel->Dst. If the deletion of eDel
+ * would create isolated vertices, those are deleted as well.
+ *
+ * ********************** Other Edge Operations **************************
+ *
+ * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
+ * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
+ * eOrg and eNew will have the same left face.
+ *
+ * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
+ * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.
+ * eOrg and eNew will have the same left face.
+ *
+ * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
+ * to eDst->Org, and returns the corresponding half-edge eNew.
+ * If eOrg->Lface == eDst->Lface, this splits one loop into two,
+ * and the newly created loop is eNew->Lface. Otherwise, two disjoint
+ * loops are merged into one, and the loop eDst->Lface is destroyed.
+ *
+ * ************************ Other Operations *****************************
+ *
+ * __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
+ * and no loops (what we usually call a "face").
+ *
+ * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
+ * both meshes, and returns the new mesh (the old meshes are destroyed).
+ *
+ * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
+ *
+ * __gl_meshZapFace( fZap ) destroys a face and removes it from the
+ * global face list. All edges of fZap will have a NULL pointer as their
+ * left face. Any edges which also have a NULL pointer as their right face
+ * are deleted entirely (along with any isolated vertices this produces).
+ * An entire mesh can be deleted by zapping its faces, one at a time,
+ * in any order. Zapped faces cannot be used in further mesh operations!
+ *
+ * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
+ */
+
+GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh );
+int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
+int __gl_meshDelete( GLUhalfEdge *eDel );
+
+GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg );
+GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg );
+GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
+
+GLUmesh *__gl_meshNewMesh( void );
+GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 );
+void __gl_meshDeleteMesh( GLUmesh *mesh );
+void __gl_meshZapFace( GLUface *fZap );
+
+#ifdef NDEBUG
+#define __gl_meshCheckMesh( mesh )
+#else
+void __gl_meshCheckMesh( GLUmesh *mesh );
+#endif
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/normal.c b/WebCore/thirdparty/glu/libtess/normal.c
new file mode 100644
index 0000000..18fd6ac
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/normal.c
@@ -0,0 +1,259 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/normal.c#5 $
+*/
+
+#include <assert.h>
+#include <math.h>
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/normal.h"
+#include "thirdparty/glu/libtess/tess.h"
+
+#define TRUE 1
+#define FALSE 0
+
+#define Dot(u,v) (u[0]*v[0] + u[1]*v[1] + u[2]*v[2])
+
+#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT)
+static void Normalize( GLdouble v[3] )
+{
+ GLdouble len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+
+ assert( len > 0 );
+ len = sqrt( len );
+ v[0] /= len;
+ v[1] /= len;
+ v[2] /= len;
+}
+#endif
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+static int LongAxis( GLdouble v[3] )
+{
+ int i = 0;
+
+ if( ABS(v[1]) > ABS(v[0]) ) { i = 1; }
+ if( ABS(v[2]) > ABS(v[i]) ) { i = 2; }
+ return i;
+}
+
+static void ComputeNormal( GLUtesselator *tess, GLdouble norm[3] )
+{
+ GLUvertex *v, *v1, *v2;
+ GLdouble c, tLen2, maxLen2;
+ GLdouble maxVal[3], minVal[3], d1[3], d2[3], tNorm[3];
+ GLUvertex *maxVert[3], *minVert[3];
+ GLUvertex *vHead = &tess->mesh->vHead;
+ int i;
+
+ maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU_TESS_MAX_COORD;
+ minVal[0] = minVal[1] = minVal[2] = 2 * GLU_TESS_MAX_COORD;
+
+ for( v = vHead->next; v != vHead; v = v->next ) {
+ for( i = 0; i < 3; ++i ) {
+ c = v->coords[i];
+ if( c < minVal[i] ) { minVal[i] = c; minVert[i] = v; }
+ if( c > maxVal[i] ) { maxVal[i] = c; maxVert[i] = v; }
+ }
+ }
+
+ /* Find two vertices separated by at least 1/sqrt(3) of the maximum
+ * distance between any two vertices
+ */
+ i = 0;
+ if( maxVal[1] - minVal[1] > maxVal[0] - minVal[0] ) { i = 1; }
+ if( maxVal[2] - minVal[2] > maxVal[i] - minVal[i] ) { i = 2; }
+ if( minVal[i] >= maxVal[i] ) {
+ /* All vertices are the same -- normal doesn't matter */
+ norm[0] = 0; norm[1] = 0; norm[2] = 1;
+ return;
+ }
+
+ /* Look for a third vertex which forms the triangle with maximum area
+ * (Length of normal == twice the triangle area)
+ */
+ maxLen2 = 0;
+ v1 = minVert[i];
+ v2 = maxVert[i];
+ d1[0] = v1->coords[0] - v2->coords[0];
+ d1[1] = v1->coords[1] - v2->coords[1];
+ d1[2] = v1->coords[2] - v2->coords[2];
+ for( v = vHead->next; v != vHead; v = v->next ) {
+ d2[0] = v->coords[0] - v2->coords[0];
+ d2[1] = v->coords[1] - v2->coords[1];
+ d2[2] = v->coords[2] - v2->coords[2];
+ tNorm[0] = d1[1]*d2[2] - d1[2]*d2[1];
+ tNorm[1] = d1[2]*d2[0] - d1[0]*d2[2];
+ tNorm[2] = d1[0]*d2[1] - d1[1]*d2[0];
+ tLen2 = tNorm[0]*tNorm[0] + tNorm[1]*tNorm[1] + tNorm[2]*tNorm[2];
+ if( tLen2 > maxLen2 ) {
+ maxLen2 = tLen2;
+ norm[0] = tNorm[0];
+ norm[1] = tNorm[1];
+ norm[2] = tNorm[2];
+ }
+ }
+
+ if( maxLen2 <= 0 ) {
+ /* All points lie on a single line -- any decent normal will do */
+ norm[0] = norm[1] = norm[2] = 0;
+ norm[LongAxis(d1)] = 1;
+ }
+}
+
+
+static void CheckOrientation( GLUtesselator *tess )
+{
+ GLdouble area;
+ GLUface *f, *fHead = &tess->mesh->fHead;
+ GLUvertex *v, *vHead = &tess->mesh->vHead;
+ GLUhalfEdge *e;
+
+ /* When we compute the normal automatically, we choose the orientation
+ * so that the the sum of the signed areas of all contours is non-negative.
+ */
+ area = 0;
+ for( f = fHead->next; f != fHead; f = f->next ) {
+ e = f->anEdge;
+ if( e->winding <= 0 ) continue;
+ do {
+ area += (e->Org->s - e->Dst->s) * (e->Org->t + e->Dst->t);
+ e = e->Lnext;
+ } while( e != f->anEdge );
+ }
+ if( area < 0 ) {
+ /* Reverse the orientation by flipping all the t-coordinates */
+ for( v = vHead->next; v != vHead; v = v->next ) {
+ v->t = - v->t;
+ }
+ tess->tUnit[0] = - tess->tUnit[0];
+ tess->tUnit[1] = - tess->tUnit[1];
+ tess->tUnit[2] = - tess->tUnit[2];
+ }
+}
+
+#ifdef FOR_TRITE_TEST_PROGRAM
+#include <stdlib.h>
+extern int RandomSweep;
+#define S_UNIT_X (RandomSweep ? (2*drand48()-1) : 1.0)
+#define S_UNIT_Y (RandomSweep ? (2*drand48()-1) : 0.0)
+#else
+#if defined(SLANTED_SWEEP)
+/* The "feature merging" is not intended to be complete. There are
+ * special cases where edges are nearly parallel to the sweep line
+ * which are not implemented. The algorithm should still behave
+ * robustly (ie. produce a reasonable tesselation) in the presence
+ * of such edges, however it may miss features which could have been
+ * merged. We could minimize this effect by choosing the sweep line
+ * direction to be something unusual (ie. not parallel to one of the
+ * coordinate axes).
+ */
+#define S_UNIT_X 0.50941539564955385 /* Pre-normalized */
+#define S_UNIT_Y 0.86052074622010633
+#else
+#define S_UNIT_X 1.0
+#define S_UNIT_Y 0.0
+#endif
+#endif
+
+/* Determine the polygon normal and project vertices onto the plane
+ * of the polygon.
+ */
+void __gl_projectPolygon( GLUtesselator *tess )
+{
+ GLUvertex *v, *vHead = &tess->mesh->vHead;
+ GLdouble norm[3];
+ GLdouble *sUnit, *tUnit;
+ int i, computedNormal = FALSE;
+
+ norm[0] = tess->normal[0];
+ norm[1] = tess->normal[1];
+ norm[2] = tess->normal[2];
+ if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
+ ComputeNormal( tess, norm );
+ computedNormal = TRUE;
+ }
+ sUnit = tess->sUnit;
+ tUnit = tess->tUnit;
+ i = LongAxis( norm );
+
+#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT)
+ /* Choose the initial sUnit vector to be approximately perpendicular
+ * to the normal.
+ */
+ Normalize( norm );
+
+ sUnit[i] = 0;
+ sUnit[(i+1)%3] = S_UNIT_X;
+ sUnit[(i+2)%3] = S_UNIT_Y;
+
+ /* Now make it exactly perpendicular */
+ w = Dot( sUnit, norm );
+ sUnit[0] -= w * norm[0];
+ sUnit[1] -= w * norm[1];
+ sUnit[2] -= w * norm[2];
+ Normalize( sUnit );
+
+ /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */
+ tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1];
+ tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2];
+ tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0];
+ Normalize( tUnit );
+#else
+ /* Project perpendicular to a coordinate axis -- better numerically */
+ sUnit[i] = 0;
+ sUnit[(i+1)%3] = S_UNIT_X;
+ sUnit[(i+2)%3] = S_UNIT_Y;
+
+ tUnit[i] = 0;
+ tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y;
+ tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X;
+#endif
+
+ /* Project the vertices onto the sweep plane */
+ for( v = vHead->next; v != vHead; v = v->next ) {
+ v->s = Dot( v->coords, sUnit );
+ v->t = Dot( v->coords, tUnit );
+ }
+ if( computedNormal ) {
+ CheckOrientation( tess );
+ }
+}
diff --git a/WebCore/thirdparty/glu/libtess/normal.h b/WebCore/thirdparty/glu/libtess/normal.h
new file mode 100644
index 0000000..5e74db2
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/normal.h
@@ -0,0 +1,52 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/normal.h#5 $
+*/
+
+#ifndef __normal_h_
+#define __normal_h_
+
+#include "thirdparty/glu/libtess/tess.h"
+
+/* __gl_projectPolygon( tess ) determines the polygon normal
+ * and project vertices onto the plane of the polygon.
+ */
+void __gl_projectPolygon( GLUtesselator *tess );
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/priorityq-heap.c b/WebCore/thirdparty/glu/libtess/priorityq-heap.c
new file mode 100644
index 0000000..5d60ae7
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/priorityq-heap.c
@@ -0,0 +1,260 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/priorityq-heap.c#5 $
+*/
+
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include "thirdparty/glu/libtess/memalloc.h"
+#include "thirdparty/glu/libtess/priorityq-heap.h"
+
+#define INIT_SIZE 32
+
+#define TRUE 1
+#define FALSE 0
+
+#ifdef FOR_TRITE_TEST_PROGRAM
+#define LEQ(x,y) (*pq->leq)(x,y)
+#else
+/* Violates modularity, but a little faster */
+#include "geom.h"
+#define LEQ(x,y) VertLeq((GLUvertex *)x, (GLUvertex *)y)
+#endif
+
+/* really __gl_pqHeapNewPriorityQ */
+PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) )
+{
+ PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ ));
+ if (pq == NULL) return NULL;
+
+ pq->size = 0;
+ pq->max = INIT_SIZE;
+ pq->nodes = (PQnode *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->nodes[0]) );
+ if (pq->nodes == NULL) {
+ memFree(pq);
+ return NULL;
+ }
+
+ pq->handles = (PQhandleElem *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->handles[0]) );
+ if (pq->handles == NULL) {
+ memFree(pq->nodes);
+ memFree(pq);
+ return NULL;
+ }
+
+ pq->initialized = FALSE;
+ pq->freeList = 0;
+ pq->leq = leq;
+
+ pq->nodes[1].handle = 1; /* so that Minimum() returns NULL */
+ pq->handles[1].key = NULL;
+ return pq;
+}
+
+/* really __gl_pqHeapDeletePriorityQ */
+void pqDeletePriorityQ( PriorityQ *pq )
+{
+ memFree( pq->handles );
+ memFree( pq->nodes );
+ memFree( pq );
+}
+
+
+static void FloatDown( PriorityQ *pq, long curr )
+{
+ PQnode *n = pq->nodes;
+ PQhandleElem *h = pq->handles;
+ PQhandle hCurr, hChild;
+ long child;
+
+ hCurr = n[curr].handle;
+ for( ;; ) {
+ child = curr << 1;
+ if( child < pq->size && LEQ( h[n[child+1].handle].key,
+ h[n[child].handle].key )) {
+ ++child;
+ }
+
+ assert(child <= pq->max);
+
+ hChild = n[child].handle;
+ if( child > pq->size || LEQ( h[hCurr].key, h[hChild].key )) {
+ n[curr].handle = hCurr;
+ h[hCurr].node = curr;
+ break;
+ }
+ n[curr].handle = hChild;
+ h[hChild].node = curr;
+ curr = child;
+ }
+}
+
+
+static void FloatUp( PriorityQ *pq, long curr )
+{
+ PQnode *n = pq->nodes;
+ PQhandleElem *h = pq->handles;
+ PQhandle hCurr, hParent;
+ long parent;
+
+ hCurr = n[curr].handle;
+ for( ;; ) {
+ parent = curr >> 1;
+ hParent = n[parent].handle;
+ if( parent == 0 || LEQ( h[hParent].key, h[hCurr].key )) {
+ n[curr].handle = hCurr;
+ h[hCurr].node = curr;
+ break;
+ }
+ n[curr].handle = hParent;
+ h[hParent].node = curr;
+ curr = parent;
+ }
+}
+
+/* really __gl_pqHeapInit */
+void pqInit( PriorityQ *pq )
+{
+ long i;
+
+ /* This method of building a heap is O(n), rather than O(n lg n). */
+
+ for( i = pq->size; i >= 1; --i ) {
+ FloatDown( pq, i );
+ }
+ pq->initialized = TRUE;
+}
+
+/* really __gl_pqHeapInsert */
+/* returns LONG_MAX iff out of memory */
+PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
+{
+ long curr;
+ PQhandle free;
+
+ curr = ++ pq->size;
+ if( (curr*2) > pq->max ) {
+ PQnode *saveNodes= pq->nodes;
+ PQhandleElem *saveHandles= pq->handles;
+
+ /* If the heap overflows, double its size. */
+ pq->max <<= 1;
+ pq->nodes = (PQnode *)memRealloc( pq->nodes,
+ (size_t)
+ ((pq->max + 1) * sizeof( pq->nodes[0] )));
+ if (pq->nodes == NULL) {
+ pq->nodes = saveNodes; /* restore ptr to free upon return */
+ return LONG_MAX;
+ }
+ pq->handles = (PQhandleElem *)memRealloc( pq->handles,
+ (size_t)
+ ((pq->max + 1) *
+ sizeof( pq->handles[0] )));
+ if (pq->handles == NULL) {
+ pq->handles = saveHandles; /* restore ptr to free upon return */
+ return LONG_MAX;
+ }
+ }
+
+ if( pq->freeList == 0 ) {
+ free = curr;
+ } else {
+ free = pq->freeList;
+ pq->freeList = pq->handles[free].node;
+ }
+
+ pq->nodes[curr].handle = free;
+ pq->handles[free].node = curr;
+ pq->handles[free].key = keyNew;
+
+ if( pq->initialized ) {
+ FloatUp( pq, curr );
+ }
+ assert(free != LONG_MAX);
+ return free;
+}
+
+/* really __gl_pqHeapExtractMin */
+PQkey pqExtractMin( PriorityQ *pq )
+{
+ PQnode *n = pq->nodes;
+ PQhandleElem *h = pq->handles;
+ PQhandle hMin = n[1].handle;
+ PQkey min = h[hMin].key;
+
+ if( pq->size > 0 ) {
+ n[1].handle = n[pq->size].handle;
+ h[n[1].handle].node = 1;
+
+ h[hMin].key = NULL;
+ h[hMin].node = pq->freeList;
+ pq->freeList = hMin;
+
+ if( -- pq->size > 0 ) {
+ FloatDown( pq, 1 );
+ }
+ }
+ return min;
+}
+
+/* really __gl_pqHeapDelete */
+void pqDelete( PriorityQ *pq, PQhandle hCurr )
+{
+ PQnode *n = pq->nodes;
+ PQhandleElem *h = pq->handles;
+ long curr;
+
+ assert( hCurr >= 1 && hCurr <= pq->max && h[hCurr].key != NULL );
+
+ curr = h[hCurr].node;
+ n[curr].handle = n[pq->size].handle;
+ h[n[curr].handle].node = curr;
+
+ if( curr <= -- pq->size ) {
+ if( curr <= 1 || LEQ( h[n[curr>>1].handle].key, h[n[curr].handle].key )) {
+ FloatDown( pq, curr );
+ } else {
+ FloatUp( pq, curr );
+ }
+ }
+ h[hCurr].key = NULL;
+ h[hCurr].node = pq->freeList;
+ pq->freeList = hCurr;
+}
diff --git a/WebCore/thirdparty/glu/libtess/priorityq-heap.h b/WebCore/thirdparty/glu/libtess/priorityq-heap.h
new file mode 100644
index 0000000..02e4434
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/priorityq-heap.h
@@ -0,0 +1,114 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/priorityq-heap.h#5 $
+*/
+
+#ifndef __priorityq_heap_h_
+#define __priorityq_heap_h_
+
+/* Use #define's so that another heap implementation can use this one */
+
+#define PQkey PQHeapKey
+#define PQhandle PQHeapHandle
+#define PriorityQ PriorityQHeap
+
+#define pqNewPriorityQ(leq) __gl_pqHeapNewPriorityQ(leq)
+#define pqDeletePriorityQ(pq) __gl_pqHeapDeletePriorityQ(pq)
+
+/* The basic operations are insertion of a new key (pqInsert),
+ * and examination/extraction of a key whose value is minimum
+ * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete);
+ * for this purpose pqInsert returns a "handle" which is supplied
+ * as the argument.
+ *
+ * An initial heap may be created efficiently by calling pqInsert
+ * repeatedly, then calling pqInit. In any case pqInit must be called
+ * before any operations other than pqInsert are used.
+ *
+ * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
+ * This may also be tested with pqIsEmpty.
+ */
+#define pqInit(pq) __gl_pqHeapInit(pq)
+#define pqInsert(pq,key) __gl_pqHeapInsert(pq,key)
+#define pqMinimum(pq) __gl_pqHeapMinimum(pq)
+#define pqExtractMin(pq) __gl_pqHeapExtractMin(pq)
+#define pqDelete(pq,handle) __gl_pqHeapDelete(pq,handle)
+#define pqIsEmpty(pq) __gl_pqHeapIsEmpty(pq)
+
+
+/* Since we support deletion the data structure is a little more
+ * complicated than an ordinary heap. "nodes" is the heap itself;
+ * active nodes are stored in the range 1..pq->size. When the
+ * heap exceeds its allocated size (pq->max), its size doubles.
+ * The children of node i are nodes 2i and 2i+1.
+ *
+ * Each node stores an index into an array "handles". Each handle
+ * stores a key, plus a pointer back to the node which currently
+ * represents that key (ie. nodes[handles[i].node].handle == i).
+ */
+
+typedef void *PQkey;
+typedef long PQhandle;
+typedef struct PriorityQ PriorityQ;
+
+typedef struct { PQhandle handle; } PQnode;
+typedef struct { PQkey key; PQhandle node; } PQhandleElem;
+
+struct PriorityQ {
+ PQnode *nodes;
+ PQhandleElem *handles;
+ long size, max;
+ PQhandle freeList;
+ int initialized;
+ int (*leq)(PQkey key1, PQkey key2);
+};
+
+PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
+void pqDeletePriorityQ( PriorityQ *pq );
+
+void pqInit( PriorityQ *pq );
+PQhandle pqInsert( PriorityQ *pq, PQkey key );
+PQkey pqExtractMin( PriorityQ *pq );
+void pqDelete( PriorityQ *pq, PQhandle handle );
+
+
+#define __gl_pqHeapMinimum(pq) ((pq)->handles[(pq)->nodes[1].handle].key)
+#define __gl_pqHeapIsEmpty(pq) ((pq)->size == 0)
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/priorityq-sort.h b/WebCore/thirdparty/glu/libtess/priorityq-sort.h
new file mode 100644
index 0000000..fc289d6
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/priorityq-sort.h
@@ -0,0 +1,124 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/priorityq-sort.h#5 $
+*/
+
+#ifndef __priorityq_sort_h_
+#define __priorityq_sort_h_
+
+#include "thirdparty/glu/libtess/priorityq-heap.h"
+
+#undef PQkey
+#undef PQhandle
+#undef PriorityQ
+#undef pqNewPriorityQ
+#undef pqDeletePriorityQ
+#undef pqInit
+#undef pqInsert
+#undef pqMinimum
+#undef pqExtractMin
+#undef pqDelete
+#undef pqIsEmpty
+
+/* Use #define's so that another heap implementation can use this one */
+
+#define PQkey PQSortKey
+#define PQhandle PQSortHandle
+#define PriorityQ PriorityQSort
+
+#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq)
+#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq)
+
+/* The basic operations are insertion of a new key (pqInsert),
+ * and examination/extraction of a key whose value is minimum
+ * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete);
+ * for this purpose pqInsert returns a "handle" which is supplied
+ * as the argument.
+ *
+ * An initial heap may be created efficiently by calling pqInsert
+ * repeatedly, then calling pqInit. In any case pqInit must be called
+ * before any operations other than pqInsert are used.
+ *
+ * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
+ * This may also be tested with pqIsEmpty.
+ */
+#define pqInit(pq) __gl_pqSortInit(pq)
+#define pqInsert(pq,key) __gl_pqSortInsert(pq,key)
+#define pqMinimum(pq) __gl_pqSortMinimum(pq)
+#define pqExtractMin(pq) __gl_pqSortExtractMin(pq)
+#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle)
+#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq)
+
+
+/* Since we support deletion the data structure is a little more
+ * complicated than an ordinary heap. "nodes" is the heap itself;
+ * active nodes are stored in the range 1..pq->size. When the
+ * heap exceeds its allocated size (pq->max), its size doubles.
+ * The children of node i are nodes 2i and 2i+1.
+ *
+ * Each node stores an index into an array "handles". Each handle
+ * stores a key, plus a pointer back to the node which currently
+ * represents that key (ie. nodes[handles[i].node].handle == i).
+ */
+
+typedef PQHeapKey PQkey;
+typedef PQHeapHandle PQhandle;
+typedef struct PriorityQ PriorityQ;
+
+struct PriorityQ {
+ PriorityQHeap *heap;
+ PQkey *keys;
+ PQkey **order;
+ PQhandle size, max;
+ int initialized;
+ int (*leq)(PQkey key1, PQkey key2);
+};
+
+PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
+void pqDeletePriorityQ( PriorityQ *pq );
+
+int pqInit( PriorityQ *pq );
+PQhandle pqInsert( PriorityQ *pq, PQkey key );
+PQkey pqExtractMin( PriorityQ *pq );
+void pqDelete( PriorityQ *pq, PQhandle handle );
+
+PQkey pqMinimum( PriorityQ *pq );
+int pqIsEmpty( PriorityQ *pq );
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/priorityq.c b/WebCore/thirdparty/glu/libtess/priorityq.c
new file mode 100644
index 0000000..4b0bea1
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/priorityq.c
@@ -0,0 +1,267 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/priorityq.c#5 $
+*/
+
+#include <assert.h>
+#include <limits.h> /* LONG_MAX */
+#include <stddef.h>
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/memalloc.h"
+
+/* Include all the code for the regular heap-based queue here. */
+
+#include "thirdparty/glu/libtess/priorityq-heap.c"
+
+/* Now redefine all the function names to map to their "Sort" versions. */
+
+#include "thirdparty/glu/libtess/priorityq-sort.h"
+
+/* really __gl_pqSortNewPriorityQ */
+PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) )
+{
+ PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ ));
+ if (pq == NULL) return NULL;
+
+ pq->heap = __gl_pqHeapNewPriorityQ( leq );
+ if (pq->heap == NULL) {
+ memFree(pq);
+ return NULL;
+ }
+
+ pq->keys = (PQHeapKey *)memAlloc( INIT_SIZE * sizeof(pq->keys[0]) );
+ if (pq->keys == NULL) {
+ __gl_pqHeapDeletePriorityQ(pq->heap);
+ memFree(pq);
+ return NULL;
+ }
+
+ pq->size = 0;
+ pq->max = INIT_SIZE;
+ pq->initialized = FALSE;
+ pq->leq = leq;
+ return pq;
+}
+
+/* really __gl_pqSortDeletePriorityQ */
+void pqDeletePriorityQ( PriorityQ *pq )
+{
+ assert(pq != NULL);
+ if (pq->heap != NULL) __gl_pqHeapDeletePriorityQ( pq->heap );
+ if (pq->order != NULL) memFree( pq->order );
+ if (pq->keys != NULL) memFree( pq->keys );
+ memFree( pq );
+}
+
+
+#define LT(x,y) (! LEQ(y,x))
+#define GT(x,y) (! LEQ(x,y))
+#define Swap(a,b) if(1){PQkey *tmp = *a; *a = *b; *b = tmp;}else
+
+/* really __gl_pqSortInit */
+int pqInit( PriorityQ *pq )
+{
+ PQkey **p, **r, **i, **j, *piv;
+ struct { PQkey **p, **r; } Stack[50], *top = Stack;
+ unsigned long seed = 2016473283;
+
+ /* Create an array of indirect pointers to the keys, so that we
+ * the handles we have returned are still valid.
+ */
+/*
+ pq->order = (PQHeapKey **)memAlloc( (size_t)
+ (pq->size * sizeof(pq->order[0])) );
+*/
+ pq->order = (PQHeapKey **)memAlloc( (size_t)
+ ((pq->size+1) * sizeof(pq->order[0])) );
+/* the previous line is a patch to compensate for the fact that IBM */
+/* machines return a null on a malloc of zero bytes (unlike SGI), */
+/* so we have to put in this defense to guard against a memory */
+/* fault four lines down. from fossum@austin.ibm.com. */
+ if (pq->order == NULL) return 0;
+
+ p = pq->order;
+ r = p + pq->size - 1;
+ for( piv = pq->keys, i = p; i <= r; ++piv, ++i ) {
+ *i = piv;
+ }
+
+ /* Sort the indirect pointers in descending order,
+ * using randomized Quicksort
+ */
+ top->p = p; top->r = r; ++top;
+ while( --top >= Stack ) {
+ p = top->p;
+ r = top->r;
+ while( r > p + 10 ) {
+ seed = seed * 1539415821 + 1;
+ i = p + seed % (r - p + 1);
+ piv = *i;
+ *i = *p;
+ *p = piv;
+ i = p - 1;
+ j = r + 1;
+ do {
+ do { ++i; } while( GT( **i, *piv ));
+ do { --j; } while( LT( **j, *piv ));
+ Swap( i, j );
+ } while( i < j );
+ Swap( i, j ); /* Undo last swap */
+ if( i - p < r - j ) {
+ top->p = j+1; top->r = r; ++top;
+ r = i-1;
+ } else {
+ top->p = p; top->r = i-1; ++top;
+ p = j+1;
+ }
+ }
+ /* Insertion sort small lists */
+ for( i = p+1; i <= r; ++i ) {
+ piv = *i;
+ for( j = i; j > p && LT( **(j-1), *piv ); --j ) {
+ *j = *(j-1);
+ }
+ *j = piv;
+ }
+ }
+ pq->max = pq->size;
+ pq->initialized = TRUE;
+ __gl_pqHeapInit( pq->heap ); /* always succeeds */
+
+#ifndef NDEBUG
+ p = pq->order;
+ r = p + pq->size - 1;
+ for( i = p; i < r; ++i ) {
+ assert( LEQ( **(i+1), **i ));
+ }
+#endif
+
+ return 1;
+}
+
+/* really __gl_pqSortInsert */
+/* returns LONG_MAX iff out of memory */
+PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
+{
+ long curr;
+
+ if( pq->initialized ) {
+ return __gl_pqHeapInsert( pq->heap, keyNew );
+ }
+ curr = pq->size;
+ if( ++ pq->size >= pq->max ) {
+ PQkey *saveKey= pq->keys;
+
+ /* If the heap overflows, double its size. */
+ pq->max <<= 1;
+ pq->keys = (PQHeapKey *)memRealloc( pq->keys,
+ (size_t)
+ (pq->max * sizeof( pq->keys[0] )));
+ if (pq->keys == NULL) {
+ pq->keys = saveKey; /* restore ptr to free upon return */
+ return LONG_MAX;
+ }
+ }
+ assert(curr != LONG_MAX);
+ pq->keys[curr] = keyNew;
+
+ /* Negative handles index the sorted array. */
+ return -(curr+1);
+}
+
+/* really __gl_pqSortExtractMin */
+PQkey pqExtractMin( PriorityQ *pq )
+{
+ PQkey sortMin, heapMin;
+
+ if( pq->size == 0 ) {
+ return __gl_pqHeapExtractMin( pq->heap );
+ }
+ sortMin = *(pq->order[pq->size-1]);
+ if( ! __gl_pqHeapIsEmpty( pq->heap )) {
+ heapMin = __gl_pqHeapMinimum( pq->heap );
+ if( LEQ( heapMin, sortMin )) {
+ return __gl_pqHeapExtractMin( pq->heap );
+ }
+ }
+ do {
+ -- pq->size;
+ } while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL );
+ return sortMin;
+}
+
+/* really __gl_pqSortMinimum */
+PQkey pqMinimum( PriorityQ *pq )
+{
+ PQkey sortMin, heapMin;
+
+ if( pq->size == 0 ) {
+ return __gl_pqHeapMinimum( pq->heap );
+ }
+ sortMin = *(pq->order[pq->size-1]);
+ if( ! __gl_pqHeapIsEmpty( pq->heap )) {
+ heapMin = __gl_pqHeapMinimum( pq->heap );
+ if( LEQ( heapMin, sortMin )) {
+ return heapMin;
+ }
+ }
+ return sortMin;
+}
+
+/* really __gl_pqSortIsEmpty */
+int pqIsEmpty( PriorityQ *pq )
+{
+ return (pq->size == 0) && __gl_pqHeapIsEmpty( pq->heap );
+}
+
+/* really __gl_pqSortDelete */
+void pqDelete( PriorityQ *pq, PQhandle curr )
+{
+ if( curr >= 0 ) {
+ __gl_pqHeapDelete( pq->heap, curr );
+ return;
+ }
+ curr = -(curr+1);
+ assert( curr < pq->max && pq->keys[curr] != NULL );
+
+ pq->keys[curr] = NULL;
+ while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL ) {
+ -- pq->size;
+ }
+}
diff --git a/WebCore/thirdparty/glu/libtess/priorityq.h b/WebCore/thirdparty/glu/libtess/priorityq.h
new file mode 100644
index 0000000..77aa70b
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/priorityq.h
@@ -0,0 +1,124 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/priorityq.h#5 $
+*/
+
+#ifndef __priorityq_sort_h_
+#define __priorityq_sort_h_
+
+#include "thirdparty/glu/libtess/priorityq-heap.h"
+
+#undef PQkey
+#undef PQhandle
+#undef PriorityQ
+#undef pqNewPriorityQ
+#undef pqDeletePriorityQ
+#undef pqInit
+#undef pqInsert
+#undef pqMinimum
+#undef pqExtractMin
+#undef pqDelete
+#undef pqIsEmpty
+
+/* Use #define's so that another heap implementation can use this one */
+
+#define PQkey PQSortKey
+#define PQhandle PQSortHandle
+#define PriorityQ PriorityQSort
+
+#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq)
+#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq)
+
+/* The basic operations are insertion of a new key (pqInsert),
+ * and examination/extraction of a key whose value is minimum
+ * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete);
+ * for this purpose pqInsert returns a "handle" which is supplied
+ * as the argument.
+ *
+ * An initial heap may be created efficiently by calling pqInsert
+ * repeatedly, then calling pqInit. In any case pqInit must be called
+ * before any operations other than pqInsert are used.
+ *
+ * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
+ * This may also be tested with pqIsEmpty.
+ */
+#define pqInit(pq) __gl_pqSortInit(pq)
+#define pqInsert(pq,key) __gl_pqSortInsert(pq,key)
+#define pqMinimum(pq) __gl_pqSortMinimum(pq)
+#define pqExtractMin(pq) __gl_pqSortExtractMin(pq)
+#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle)
+#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq)
+
+
+/* Since we support deletion the data structure is a little more
+ * complicated than an ordinary heap. "nodes" is the heap itself;
+ * active nodes are stored in the range 1..pq->size. When the
+ * heap exceeds its allocated size (pq->max), its size doubles.
+ * The children of node i are nodes 2i and 2i+1.
+ *
+ * Each node stores an index into an array "handles". Each handle
+ * stores a key, plus a pointer back to the node which currently
+ * represents that key (ie. nodes[handles[i].node].handle == i).
+ */
+
+typedef PQHeapKey PQkey;
+typedef PQHeapHandle PQhandle;
+typedef struct PriorityQ PriorityQ;
+
+struct PriorityQ {
+ PriorityQHeap *heap;
+ PQkey *keys;
+ PQkey **order;
+ PQhandle size, max;
+ int initialized;
+ int (*leq)(PQkey key1, PQkey key2);
+};
+
+PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
+void pqDeletePriorityQ( PriorityQ *pq );
+
+int pqInit( PriorityQ *pq );
+PQhandle pqInsert( PriorityQ *pq, PQkey key );
+PQkey pqExtractMin( PriorityQ *pq );
+void pqDelete( PriorityQ *pq, PQhandle handle );
+
+PQkey pqMinimum( PriorityQ *pq );
+int pqIsEmpty( PriorityQ *pq );
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/render.c b/WebCore/thirdparty/glu/libtess/render.c
new file mode 100644
index 0000000..0e944a2
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/render.c
@@ -0,0 +1,505 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/render.c#5 $
+*/
+
+#include <assert.h>
+#include <stddef.h>
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/render.h"
+#include "thirdparty/glu/libtess/tess.h"
+
+#define TRUE 1
+#define FALSE 0
+
+/* This structure remembers the information we need about a primitive
+ * to be able to render it later, once we have determined which
+ * primitive is able to use the most triangles.
+ */
+struct FaceCount {
+ long size; /* number of triangles used */
+ GLUhalfEdge *eStart; /* edge where this primitive starts */
+ void (*render)(GLUtesselator *, GLUhalfEdge *, long);
+ /* routine to render this primitive */
+};
+
+static struct FaceCount MaximumFan( GLUhalfEdge *eOrig );
+static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig );
+
+static void RenderFan( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
+static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
+static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *eStart,
+ long size );
+
+static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig );
+static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *head );
+
+
+
+/************************ Strips and Fans decomposition ******************/
+
+/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
+ * fans, strips, and separate triangles. A substantial effort is made
+ * to use as few rendering primitives as possible (ie. to make the fans
+ * and strips as large as possible).
+ *
+ * The rendering output is provided as callbacks (see the api).
+ */
+void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh )
+{
+ GLUface *f;
+
+ /* Make a list of separate triangles so we can render them all at once */
+ tess->lonelyTriList = NULL;
+
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
+ f->marked = FALSE;
+ }
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
+
+ /* We examine all faces in an arbitrary order. Whenever we find
+ * an unprocessed face F, we output a group of faces including F
+ * whose size is maximum.
+ */
+ if( f->inside && ! f->marked ) {
+ RenderMaximumFaceGroup( tess, f );
+ assert( f->marked );
+ }
+ }
+ if( tess->lonelyTriList != NULL ) {
+ RenderLonelyTriangles( tess, tess->lonelyTriList );
+ tess->lonelyTriList = NULL;
+ }
+}
+
+
+static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig )
+{
+ /* We want to find the largest triangle fan or strip of unmarked faces
+ * which includes the given face fOrig. There are 3 possible fans
+ * passing through fOrig (one centered at each vertex), and 3 possible
+ * strips (one for each CCW permutation of the vertices). Our strategy
+ * is to try all of these, and take the primitive which uses the most
+ * triangles (a greedy approach).
+ */
+ GLUhalfEdge *e = fOrig->anEdge;
+ struct FaceCount max, newFace;
+
+ max.size = 1;
+ max.eStart = e;
+ max.render = &RenderTriangle;
+
+ if( ! tess->flagBoundary ) {
+ newFace = MaximumFan( e ); if( newFace.size > max.size ) { max = newFace; }
+ newFace = MaximumFan( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
+ newFace = MaximumFan( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
+
+ newFace = MaximumStrip( e ); if( newFace.size > max.size ) { max = newFace; }
+ newFace = MaximumStrip( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
+ newFace = MaximumStrip( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
+ }
+ (*(max.render))( tess, max.eStart, max.size );
+}
+
+
+/* Macros which keep track of faces we have marked temporarily, and allow
+ * us to backtrack when necessary. With triangle fans, this is not
+ * really necessary, since the only awkward case is a loop of triangles
+ * around a single origin vertex. However with strips the situation is
+ * more complicated, and we need a general tracking method like the
+ * one here.
+ */
+#define Marked(f) (! (f)->inside || (f)->marked)
+
+#define AddToTrail(f,t) ((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
+
+#define FreeTrail(t) if( 1 ) { \
+ while( (t) != NULL ) { \
+ (t)->marked = FALSE; t = (t)->trail; \
+ } \
+ } else /* absorb trailing semicolon */
+
+
+
+static struct FaceCount MaximumFan( GLUhalfEdge *eOrig )
+{
+ /* eOrig->Lface is the face we want to render. We want to find the size
+ * of a maximal fan around eOrig->Org. To do this we just walk around
+ * the origin vertex as far as possible in both directions.
+ */
+ struct FaceCount newFace = { 0, NULL, &RenderFan };
+ GLUface *trail = NULL;
+ GLUhalfEdge *e;
+
+ for( e = eOrig; ! Marked( e->Lface ); e = e->Onext ) {
+ AddToTrail( e->Lface, trail );
+ ++newFace.size;
+ }
+ for( e = eOrig; ! Marked( e->Rface ); e = e->Oprev ) {
+ AddToTrail( e->Rface, trail );
+ ++newFace.size;
+ }
+ newFace.eStart = e;
+ /*LINTED*/
+ FreeTrail( trail );
+ return newFace;
+}
+
+
+#define IsEven(n) (((n) & 1) == 0)
+
+static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig )
+{
+ /* Here we are looking for a maximal strip that contains the vertices
+ * eOrig->Org, eOrig->Dst, eOrig->Lnext->Dst (in that order or the
+ * reverse, such that all triangles are oriented CCW).
+ *
+ * Again we walk forward and backward as far as possible. However for
+ * strips there is a twist: to get CCW orientations, there must be
+ * an *even* number of triangles in the strip on one side of eOrig.
+ * We walk the strip starting on a side with an even number of triangles;
+ * if both side have an odd number, we are forced to shorten one side.
+ */
+ struct FaceCount newFace = { 0, NULL, &RenderStrip };
+ long headSize = 0, tailSize = 0;
+ GLUface *trail = NULL;
+ GLUhalfEdge *e, *eTail, *eHead;
+
+ for( e = eOrig; ! Marked( e->Lface ); ++tailSize, e = e->Onext ) {
+ AddToTrail( e->Lface, trail );
+ ++tailSize;
+ e = e->Dprev;
+ if( Marked( e->Lface )) break;
+ AddToTrail( e->Lface, trail );
+ }
+ eTail = e;
+
+ for( e = eOrig; ! Marked( e->Rface ); ++headSize, e = e->Dnext ) {
+ AddToTrail( e->Rface, trail );
+ ++headSize;
+ e = e->Oprev;
+ if( Marked( e->Rface )) break;
+ AddToTrail( e->Rface, trail );
+ }
+ eHead = e;
+
+ newFace.size = tailSize + headSize;
+ if( IsEven( tailSize )) {
+ newFace.eStart = eTail->Sym;
+ } else if( IsEven( headSize )) {
+ newFace.eStart = eHead;
+ } else {
+ /* Both sides have odd length, we must shorten one of them. In fact,
+ * we must start from eHead to guarantee inclusion of eOrig->Lface.
+ */
+ --newFace.size;
+ newFace.eStart = eHead->Onext;
+ }
+ /*LINTED*/
+ FreeTrail( trail );
+ return newFace;
+}
+
+
+static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *e, long size )
+{
+ /* Just add the triangle to a triangle list, so we can render all
+ * the separate triangles at once.
+ */
+ assert( size == 1 );
+ AddToTrail( e->Lface, tess->lonelyTriList );
+}
+
+
+static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *f )
+{
+ /* Now we render all the separate triangles which could not be
+ * grouped into a triangle fan or strip.
+ */
+ GLUhalfEdge *e;
+ int newState;
+ int edgeState = -1; /* force edge state output for first vertex */
+
+ CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLES );
+
+ for( ; f != NULL; f = f->trail ) {
+ /* Loop once for each edge (there will always be 3 edges) */
+
+ e = f->anEdge;
+ do {
+ if( tess->flagBoundary ) {
+ /* Set the "edge state" to TRUE just before we output the
+ * first vertex of each edge on the polygon boundary.
+ */
+ newState = ! e->Rface->inside;
+ if( edgeState != newState ) {
+ edgeState = newState;
+ CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA( edgeState );
+ }
+ }
+ CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
+
+ e = e->Lnext;
+ } while( e != f->anEdge );
+ }
+ CALL_END_OR_END_DATA();
+}
+
+
+static void RenderFan( GLUtesselator *tess, GLUhalfEdge *e, long size )
+{
+ /* Render as many CCW triangles as possible in a fan starting from
+ * edge "e". The fan *should* contain exactly "size" triangles
+ * (otherwise we've goofed up somewhere).
+ */
+ CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_FAN );
+ CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
+ CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
+
+ while( ! Marked( e->Lface )) {
+ e->Lface->marked = TRUE;
+ --size;
+ e = e->Onext;
+ CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
+ }
+
+ assert( size == 0 );
+ CALL_END_OR_END_DATA();
+}
+
+
+static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *e, long size )
+{
+ /* Render as many CCW triangles as possible in a strip starting from
+ * edge "e". The strip *should* contain exactly "size" triangles
+ * (otherwise we've goofed up somewhere).
+ */
+ CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_STRIP );
+ CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
+ CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
+
+ while( ! Marked( e->Lface )) {
+ e->Lface->marked = TRUE;
+ --size;
+ e = e->Dprev;
+ CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
+ if( Marked( e->Lface )) break;
+
+ e->Lface->marked = TRUE;
+ --size;
+ e = e->Onext;
+ CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
+ }
+
+ assert( size == 0 );
+ CALL_END_OR_END_DATA();
+}
+
+
+/************************ Boundary contour decomposition ******************/
+
+/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
+ * contour for each face marked "inside". The rendering output is
+ * provided as callbacks (see the api).
+ */
+void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh )
+{
+ GLUface *f;
+ GLUhalfEdge *e;
+
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
+ if( f->inside ) {
+ CALL_BEGIN_OR_BEGIN_DATA( GL_LINE_LOOP );
+ e = f->anEdge;
+ do {
+ CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
+ e = e->Lnext;
+ } while( e != f->anEdge );
+ CALL_END_OR_END_DATA();
+ }
+ }
+}
+
+
+/************************ Quick-and-dirty decomposition ******************/
+
+#define SIGN_INCONSISTENT 2
+
+static int ComputeNormal( GLUtesselator *tess, GLdouble norm[3], int check )
+/*
+ * If check==FALSE, we compute the polygon normal and place it in norm[].
+ * If check==TRUE, we check that each triangle in the fan from v0 has a
+ * consistent orientation with respect to norm[]. If triangles are
+ * consistently oriented CCW, return 1; if CW, return -1; if all triangles
+ * are degenerate return 0; otherwise (no consistent orientation) return
+ * SIGN_INCONSISTENT.
+ */
+{
+ CachedVertex *v0 = tess->cache;
+ CachedVertex *vn = v0 + tess->cacheCount;
+ CachedVertex *vc;
+ GLdouble dot, xc, yc, zc, xp, yp, zp, n[3];
+ int sign = 0;
+
+ /* Find the polygon normal. It is important to get a reasonable
+ * normal even when the polygon is self-intersecting (eg. a bowtie).
+ * Otherwise, the computed normal could be very tiny, but perpendicular
+ * to the true plane of the polygon due to numerical noise. Then all
+ * the triangles would appear to be degenerate and we would incorrectly
+ * decompose the polygon as a fan (or simply not render it at all).
+ *
+ * We use a sum-of-triangles normal algorithm rather than the more
+ * efficient sum-of-trapezoids method (used in CheckOrientation()
+ * in normal.c). This lets us explicitly reverse the signed area
+ * of some triangles to get a reasonable normal in the self-intersecting
+ * case.
+ */
+ if( ! check ) {
+ norm[0] = norm[1] = norm[2] = 0.0;
+ }
+
+ vc = v0 + 1;
+ xc = vc->coords[0] - v0->coords[0];
+ yc = vc->coords[1] - v0->coords[1];
+ zc = vc->coords[2] - v0->coords[2];
+ while( ++vc < vn ) {
+ xp = xc; yp = yc; zp = zc;
+ xc = vc->coords[0] - v0->coords[0];
+ yc = vc->coords[1] - v0->coords[1];
+ zc = vc->coords[2] - v0->coords[2];
+
+ /* Compute (vp - v0) cross (vc - v0) */
+ n[0] = yp*zc - zp*yc;
+ n[1] = zp*xc - xp*zc;
+ n[2] = xp*yc - yp*xc;
+
+ dot = n[0]*norm[0] + n[1]*norm[1] + n[2]*norm[2];
+ if( ! check ) {
+ /* Reverse the contribution of back-facing triangles to get
+ * a reasonable normal for self-intersecting polygons (see above)
+ */
+ if( dot >= 0 ) {
+ norm[0] += n[0]; norm[1] += n[1]; norm[2] += n[2];
+ } else {
+ norm[0] -= n[0]; norm[1] -= n[1]; norm[2] -= n[2];
+ }
+ } else if( dot != 0 ) {
+ /* Check the new orientation for consistency with previous triangles */
+ if( dot > 0 ) {
+ if( sign < 0 ) return SIGN_INCONSISTENT;
+ sign = 1;
+ } else {
+ if( sign > 0 ) return SIGN_INCONSISTENT;
+ sign = -1;
+ }
+ }
+ }
+ return sign;
+}
+
+/* __gl_renderCache( tess ) takes a single contour and tries to render it
+ * as a triangle fan. This handles convex polygons, as well as some
+ * non-convex polygons if we get lucky.
+ *
+ * Returns TRUE if the polygon was successfully rendered. The rendering
+ * output is provided as callbacks (see the api).
+ */
+GLboolean __gl_renderCache( GLUtesselator *tess )
+{
+ CachedVertex *v0 = tess->cache;
+ CachedVertex *vn = v0 + tess->cacheCount;
+ CachedVertex *vc;
+ GLdouble norm[3];
+ int sign;
+
+ if( tess->cacheCount < 3 ) {
+ /* Degenerate contour -- no output */
+ return TRUE;
+ }
+
+ norm[0] = tess->normal[0];
+ norm[1] = tess->normal[1];
+ norm[2] = tess->normal[2];
+ if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
+ ComputeNormal( tess, norm, FALSE );
+ }
+
+ sign = ComputeNormal( tess, norm, TRUE );
+ if( sign == SIGN_INCONSISTENT ) {
+ /* Fan triangles did not have a consistent orientation */
+ return FALSE;
+ }
+ if( sign == 0 ) {
+ /* All triangles were degenerate */
+ return TRUE;
+ }
+
+ /* Make sure we do the right thing for each winding rule */
+ switch( tess->windingRule ) {
+ case GLU_TESS_WINDING_ODD:
+ case GLU_TESS_WINDING_NONZERO:
+ break;
+ case GLU_TESS_WINDING_POSITIVE:
+ if( sign < 0 ) return TRUE;
+ break;
+ case GLU_TESS_WINDING_NEGATIVE:
+ if( sign > 0 ) return TRUE;
+ break;
+ case GLU_TESS_WINDING_ABS_GEQ_TWO:
+ return TRUE;
+ }
+
+ CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP
+ : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN
+ : GL_TRIANGLES );
+
+ CALL_VERTEX_OR_VERTEX_DATA( v0->data );
+ if( sign > 0 ) {
+ for( vc = v0+1; vc < vn; ++vc ) {
+ CALL_VERTEX_OR_VERTEX_DATA( vc->data );
+ }
+ } else {
+ for( vc = vn-1; vc > v0; --vc ) {
+ CALL_VERTEX_OR_VERTEX_DATA( vc->data );
+ }
+ }
+ CALL_END_OR_END_DATA();
+ return TRUE;
+}
diff --git a/WebCore/thirdparty/glu/libtess/render.h b/WebCore/thirdparty/glu/libtess/render.h
new file mode 100644
index 0000000..d8ef914
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/render.h
@@ -0,0 +1,59 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/render.h#5 $
+*/
+
+#ifndef __render_h_
+#define __render_h_
+
+#include "thirdparty/glu/libtess/mesh.h"
+
+/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
+ * fans, strips, and separate triangles. A substantial effort is made
+ * to use as few rendering primitives as possible (ie. to make the fans
+ * and strips as large as possible).
+ *
+ * The rendering output is provided as callbacks (see the api).
+ */
+void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh );
+void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh );
+
+GLboolean __gl_renderCache( GLUtesselator *tess );
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/sweep.c b/WebCore/thirdparty/glu/libtess/sweep.c
new file mode 100644
index 0000000..e85757c
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/sweep.c
@@ -0,0 +1,1359 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/sweep.c#5 $
+*/
+
+#include <assert.h>
+#include <setjmp.h> /* longjmp */
+#include <limits.h> /* LONG_MAX */
+#include <stddef.h>
+
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/dict.h"
+#include "thirdparty/glu/libtess/geom.h"
+#include "thirdparty/glu/libtess/memalloc.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/priorityq.h"
+#include "thirdparty/glu/libtess/sweep.h"
+#include "thirdparty/glu/libtess/tess.h"
+
+#define TRUE 1
+#define FALSE 0
+
+#ifdef FOR_TRITE_TEST_PROGRAM
+extern void DebugEvent( GLUtesselator *tess );
+#else
+#define DebugEvent( tess )
+#endif
+
+/*
+ * Invariants for the Edge Dictionary.
+ * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)
+ * at any valid location of the sweep event
+ * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2
+ * share a common endpoint
+ * - for each e, e->Dst has been processed, but not e->Org
+ * - each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org)
+ * where "event" is the current sweep line event.
+ * - no edge e has zero length
+ *
+ * Invariants for the Mesh (the processed portion).
+ * - the portion of the mesh left of the sweep line is a planar graph,
+ * ie. there is *some* way to embed it in the plane
+ * - no processed edge has zero length
+ * - no two processed vertices have identical coordinates
+ * - each "inside" region is monotone, ie. can be broken into two chains
+ * of monotonically increasing vertices according to VertLeq(v1,v2)
+ * - a non-invariant: these chains may intersect (very slightly)
+ *
+ * Invariants for the Sweep.
+ * - if none of the edges incident to the event vertex have an activeRegion
+ * (ie. none of these edges are in the edge dictionary), then the vertex
+ * has only right-going edges.
+ * - if an edge is marked "fixUpperEdge" (it is a temporary edge introduced
+ * by ConnectRightVertex), then it is the only right-going edge from
+ * its associated vertex. (This says that these edges exist only
+ * when it is necessary.)
+ */
+
+#define MAX(x,y) ((x) >= (y) ? (x) : (y))
+#define MIN(x,y) ((x) <= (y) ? (x) : (y))
+
+/* When we merge two edges into one, we need to compute the combined
+ * winding of the new edge.
+ */
+#define AddWinding(eDst,eSrc) (eDst->winding += eSrc->winding, \
+ eDst->Sym->winding += eSrc->Sym->winding)
+
+static void SweepEvent( GLUtesselator *tess, GLUvertex *vEvent );
+static void WalkDirtyRegions( GLUtesselator *tess, ActiveRegion *regUp );
+static int CheckForRightSplice( GLUtesselator *tess, ActiveRegion *regUp );
+
+static int EdgeLeq( GLUtesselator *tess, ActiveRegion *reg1,
+ ActiveRegion *reg2 )
+/*
+ * Both edges must be directed from right to left (this is the canonical
+ * direction for the upper edge of each region).
+ *
+ * The strategy is to evaluate a "t" value for each edge at the
+ * current sweep line position, given by tess->event. The calculations
+ * are designed to be very stable, but of course they are not perfect.
+ *
+ * Special case: if both edge destinations are at the sweep event,
+ * we sort the edges by slope (they would otherwise compare equally).
+ */
+{
+ GLUvertex *event = tess->event;
+ GLUhalfEdge *e1, *e2;
+ GLdouble t1, t2;
+
+ e1 = reg1->eUp;
+ e2 = reg2->eUp;
+
+ if( e1->Dst == event ) {
+ if( e2->Dst == event ) {
+ /* Two edges right of the sweep line which meet at the sweep event.
+ * Sort them by slope.
+ */
+ if( VertLeq( e1->Org, e2->Org )) {
+ return EdgeSign( e2->Dst, e1->Org, e2->Org ) <= 0;
+ }
+ return EdgeSign( e1->Dst, e2->Org, e1->Org ) >= 0;
+ }
+ return EdgeSign( e2->Dst, event, e2->Org ) <= 0;
+ }
+ if( e2->Dst == event ) {
+ return EdgeSign( e1->Dst, event, e1->Org ) >= 0;
+ }
+
+ /* General case - compute signed distance *from* e1, e2 to event */
+ t1 = EdgeEval( e1->Dst, event, e1->Org );
+ t2 = EdgeEval( e2->Dst, event, e2->Org );
+ return (t1 >= t2);
+}
+
+
+static void DeleteRegion( GLUtesselator *tess, ActiveRegion *reg )
+{
+ if( reg->fixUpperEdge ) {
+ /* It was created with zero winding number, so it better be
+ * deleted with zero winding number (ie. it better not get merged
+ * with a real edge).
+ */
+ assert( reg->eUp->winding == 0 );
+ }
+ reg->eUp->activeRegion = NULL;
+ dictDelete( tess->dict, reg->nodeUp ); /* __gl_dictListDelete */
+ memFree( reg );
+}
+
+
+static int FixUpperEdge( ActiveRegion *reg, GLUhalfEdge *newEdge )
+/*
+ * Replace an upper edge which needs fixing (see ConnectRightVertex).
+ */
+{
+ assert( reg->fixUpperEdge );
+ if ( !__gl_meshDelete( reg->eUp ) ) return 0;
+ reg->fixUpperEdge = FALSE;
+ reg->eUp = newEdge;
+ newEdge->activeRegion = reg;
+
+ return 1;
+}
+
+static ActiveRegion *TopLeftRegion( ActiveRegion *reg )
+{
+ GLUvertex *org = reg->eUp->Org;
+ GLUhalfEdge *e;
+
+ /* Find the region above the uppermost edge with the same origin */
+ do {
+ reg = RegionAbove( reg );
+ } while( reg->eUp->Org == org );
+
+ /* If the edge above was a temporary edge introduced by ConnectRightVertex,
+ * now is the time to fix it.
+ */
+ if( reg->fixUpperEdge ) {
+ e = __gl_meshConnect( RegionBelow(reg)->eUp->Sym, reg->eUp->Lnext );
+ if (e == NULL) return NULL;
+ if ( !FixUpperEdge( reg, e ) ) return NULL;
+ reg = RegionAbove( reg );
+ }
+ return reg;
+}
+
+static ActiveRegion *TopRightRegion( ActiveRegion *reg )
+{
+ GLUvertex *dst = reg->eUp->Dst;
+
+ /* Find the region above the uppermost edge with the same destination */
+ do {
+ reg = RegionAbove( reg );
+ } while( reg->eUp->Dst == dst );
+ return reg;
+}
+
+static ActiveRegion *AddRegionBelow( GLUtesselator *tess,
+ ActiveRegion *regAbove,
+ GLUhalfEdge *eNewUp )
+/*
+ * Add a new active region to the sweep line, *somewhere* below "regAbove"
+ * (according to where the new edge belongs in the sweep-line dictionary).
+ * The upper edge of the new region will be "eNewUp".
+ * Winding number and "inside" flag are not updated.
+ */
+{
+ ActiveRegion *regNew = (ActiveRegion *)memAlloc( sizeof( ActiveRegion ));
+ if (regNew == NULL) longjmp(tess->env,1);
+
+ regNew->eUp = eNewUp;
+ /* __gl_dictListInsertBefore */
+ regNew->nodeUp = dictInsertBefore( tess->dict, regAbove->nodeUp, regNew );
+ if (regNew->nodeUp == NULL) longjmp(tess->env,1);
+ regNew->fixUpperEdge = FALSE;
+ regNew->sentinel = FALSE;
+ regNew->dirty = FALSE;
+
+ eNewUp->activeRegion = regNew;
+ return regNew;
+}
+
+static GLboolean IsWindingInside( GLUtesselator *tess, int n )
+{
+ switch( tess->windingRule ) {
+ case GLU_TESS_WINDING_ODD:
+ return (n & 1);
+ case GLU_TESS_WINDING_NONZERO:
+ return (n != 0);
+ case GLU_TESS_WINDING_POSITIVE:
+ return (n > 0);
+ case GLU_TESS_WINDING_NEGATIVE:
+ return (n < 0);
+ case GLU_TESS_WINDING_ABS_GEQ_TWO:
+ return (n >= 2) || (n <= -2);
+ }
+ /*LINTED*/
+ assert( FALSE );
+ /*NOTREACHED*/
+}
+
+
+static void ComputeWinding( GLUtesselator *tess, ActiveRegion *reg )
+{
+ reg->windingNumber = RegionAbove(reg)->windingNumber + reg->eUp->winding;
+ reg->inside = IsWindingInside( tess, reg->windingNumber );
+}
+
+
+static void FinishRegion( GLUtesselator *tess, ActiveRegion *reg )
+/*
+ * Delete a region from the sweep line. This happens when the upper
+ * and lower chains of a region meet (at a vertex on the sweep line).
+ * The "inside" flag is copied to the appropriate mesh face (we could
+ * not do this before -- since the structure of the mesh is always
+ * changing, this face may not have even existed until now).
+ */
+{
+ GLUhalfEdge *e = reg->eUp;
+ GLUface *f = e->Lface;
+
+ f->inside = reg->inside;
+ f->anEdge = e; /* optimization for __gl_meshTessellateMonoRegion() */
+ DeleteRegion( tess, reg );
+}
+
+
+static GLUhalfEdge *FinishLeftRegions( GLUtesselator *tess,
+ ActiveRegion *regFirst, ActiveRegion *regLast )
+/*
+ * We are given a vertex with one or more left-going edges. All affected
+ * edges should be in the edge dictionary. Starting at regFirst->eUp,
+ * we walk down deleting all regions where both edges have the same
+ * origin vOrg. At the same time we copy the "inside" flag from the
+ * active region to the face, since at this point each face will belong
+ * to at most one region (this was not necessarily true until this point
+ * in the sweep). The walk stops at the region above regLast; if regLast
+ * is NULL we walk as far as possible. At the same time we relink the
+ * mesh if necessary, so that the ordering of edges around vOrg is the
+ * same as in the dictionary.
+ */
+{
+ ActiveRegion *reg, *regPrev;
+ GLUhalfEdge *e, *ePrev;
+
+ regPrev = regFirst;
+ ePrev = regFirst->eUp;
+ while( regPrev != regLast ) {
+ regPrev->fixUpperEdge = FALSE; /* placement was OK */
+ reg = RegionBelow( regPrev );
+ e = reg->eUp;
+ if( e->Org != ePrev->Org ) {
+ if( ! reg->fixUpperEdge ) {
+ /* Remove the last left-going edge. Even though there are no further
+ * edges in the dictionary with this origin, there may be further
+ * such edges in the mesh (if we are adding left edges to a vertex
+ * that has already been processed). Thus it is important to call
+ * FinishRegion rather than just DeleteRegion.
+ */
+ FinishRegion( tess, regPrev );
+ break;
+ }
+ /* If the edge below was a temporary edge introduced by
+ * ConnectRightVertex, now is the time to fix it.
+ */
+ e = __gl_meshConnect( ePrev->Lprev, e->Sym );
+ if (e == NULL) longjmp(tess->env,1);
+ if ( !FixUpperEdge( reg, e ) ) longjmp(tess->env,1);
+ }
+
+ /* Relink edges so that ePrev->Onext == e */
+ if( ePrev->Onext != e ) {
+ if ( !__gl_meshSplice( e->Oprev, e ) ) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( ePrev, e ) ) longjmp(tess->env,1);
+ }
+ FinishRegion( tess, regPrev ); /* may change reg->eUp */
+ ePrev = reg->eUp;
+ regPrev = reg;
+ }
+ return ePrev;
+}
+
+
+static void AddRightEdges( GLUtesselator *tess, ActiveRegion *regUp,
+ GLUhalfEdge *eFirst, GLUhalfEdge *eLast, GLUhalfEdge *eTopLeft,
+ GLboolean cleanUp )
+/*
+ * Purpose: insert right-going edges into the edge dictionary, and update
+ * winding numbers and mesh connectivity appropriately. All right-going
+ * edges share a common origin vOrg. Edges are inserted CCW starting at
+ * eFirst; the last edge inserted is eLast->Oprev. If vOrg has any
+ * left-going edges already processed, then eTopLeft must be the edge
+ * such that an imaginary upward vertical segment from vOrg would be
+ * contained between eTopLeft->Oprev and eTopLeft; otherwise eTopLeft
+ * should be NULL.
+ */
+{
+ ActiveRegion *reg, *regPrev;
+ GLUhalfEdge *e, *ePrev;
+ int firstTime = TRUE;
+
+ /* Insert the new right-going edges in the dictionary */
+ e = eFirst;
+ do {
+ assert( VertLeq( e->Org, e->Dst ));
+ AddRegionBelow( tess, regUp, e->Sym );
+ e = e->Onext;
+ } while ( e != eLast );
+
+ /* Walk *all* right-going edges from e->Org, in the dictionary order,
+ * updating the winding numbers of each region, and re-linking the mesh
+ * edges to match the dictionary ordering (if necessary).
+ */
+ if( eTopLeft == NULL ) {
+ eTopLeft = RegionBelow( regUp )->eUp->Rprev;
+ }
+ regPrev = regUp;
+ ePrev = eTopLeft;
+ for( ;; ) {
+ reg = RegionBelow( regPrev );
+ e = reg->eUp->Sym;
+ if( e->Org != ePrev->Org ) break;
+
+ if( e->Onext != ePrev ) {
+ /* Unlink e from its current position, and relink below ePrev */
+ if ( !__gl_meshSplice( e->Oprev, e ) ) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( ePrev->Oprev, e ) ) longjmp(tess->env,1);
+ }
+ /* Compute the winding number and "inside" flag for the new regions */
+ reg->windingNumber = regPrev->windingNumber - e->winding;
+ reg->inside = IsWindingInside( tess, reg->windingNumber );
+
+ /* Check for two outgoing edges with same slope -- process these
+ * before any intersection tests (see example in __gl_computeInterior).
+ */
+ regPrev->dirty = TRUE;
+ if( ! firstTime && CheckForRightSplice( tess, regPrev )) {
+ AddWinding( e, ePrev );
+ DeleteRegion( tess, regPrev );
+ if ( !__gl_meshDelete( ePrev ) ) longjmp(tess->env,1);
+ }
+ firstTime = FALSE;
+ regPrev = reg;
+ ePrev = e;
+ }
+ regPrev->dirty = TRUE;
+ assert( regPrev->windingNumber - e->winding == reg->windingNumber );
+
+ if( cleanUp ) {
+ /* Check for intersections between newly adjacent edges. */
+ WalkDirtyRegions( tess, regPrev );
+ }
+}
+
+
+static void CallCombine( GLUtesselator *tess, GLUvertex *isect,
+ void *data[4], GLfloat weights[4], int needed )
+{
+ GLdouble coords[3];
+
+ /* Copy coord data in case the callback changes it. */
+ coords[0] = isect->coords[0];
+ coords[1] = isect->coords[1];
+ coords[2] = isect->coords[2];
+
+ isect->data = NULL;
+ CALL_COMBINE_OR_COMBINE_DATA( coords, data, weights, &isect->data );
+ if( isect->data == NULL ) {
+ if( ! needed ) {
+ isect->data = data[0];
+ } else if( ! tess->fatalError ) {
+ /* The only way fatal error is when two edges are found to intersect,
+ * but the user has not provided the callback necessary to handle
+ * generated intersection points.
+ */
+ CALL_ERROR_OR_ERROR_DATA( GLU_TESS_NEED_COMBINE_CALLBACK );
+ tess->fatalError = TRUE;
+ }
+ }
+}
+
+static void SpliceMergeVertices( GLUtesselator *tess, GLUhalfEdge *e1,
+ GLUhalfEdge *e2 )
+/*
+ * Two vertices with idential coordinates are combined into one.
+ * e1->Org is kept, while e2->Org is discarded.
+ */
+{
+ void *data[4] = { NULL, NULL, NULL, NULL };
+ GLfloat weights[4] = { 0.5, 0.5, 0.0, 0.0 };
+
+ data[0] = e1->Org->data;
+ data[1] = e2->Org->data;
+ CallCombine( tess, e1->Org, data, weights, FALSE );
+ if ( !__gl_meshSplice( e1, e2 ) ) longjmp(tess->env,1);
+}
+
+static void VertexWeights( GLUvertex *isect, GLUvertex *org, GLUvertex *dst,
+ GLfloat *weights )
+/*
+ * Find some weights which describe how the intersection vertex is
+ * a linear combination of "org" and "dest". Each of the two edges
+ * which generated "isect" is allocated 50% of the weight; each edge
+ * splits the weight between its org and dst according to the
+ * relative distance to "isect".
+ */
+{
+ GLdouble t1 = VertL1dist( org, isect );
+ GLdouble t2 = VertL1dist( dst, isect );
+
+ weights[0] = 0.5 * t2 / (t1 + t2);
+ weights[1] = 0.5 * t1 / (t1 + t2);
+ isect->coords[0] += weights[0]*org->coords[0] + weights[1]*dst->coords[0];
+ isect->coords[1] += weights[0]*org->coords[1] + weights[1]*dst->coords[1];
+ isect->coords[2] += weights[0]*org->coords[2] + weights[1]*dst->coords[2];
+}
+
+
+static void GetIntersectData( GLUtesselator *tess, GLUvertex *isect,
+ GLUvertex *orgUp, GLUvertex *dstUp,
+ GLUvertex *orgLo, GLUvertex *dstLo )
+/*
+ * We've computed a new intersection point, now we need a "data" pointer
+ * from the user so that we can refer to this new vertex in the
+ * rendering callbacks.
+ */
+{
+ void *data[4];
+ GLfloat weights[4];
+
+ data[0] = orgUp->data;
+ data[1] = dstUp->data;
+ data[2] = orgLo->data;
+ data[3] = dstLo->data;
+
+ isect->coords[0] = isect->coords[1] = isect->coords[2] = 0;
+ VertexWeights( isect, orgUp, dstUp, &weights[0] );
+ VertexWeights( isect, orgLo, dstLo, &weights[2] );
+
+ CallCombine( tess, isect, data, weights, TRUE );
+}
+
+static int CheckForRightSplice( GLUtesselator *tess, ActiveRegion *regUp )
+/*
+ * Check the upper and lower edge of "regUp", to make sure that the
+ * eUp->Org is above eLo, or eLo->Org is below eUp (depending on which
+ * origin is leftmost).
+ *
+ * The main purpose is to splice right-going edges with the same
+ * dest vertex and nearly identical slopes (ie. we can't distinguish
+ * the slopes numerically). However the splicing can also help us
+ * to recover from numerical errors. For example, suppose at one
+ * point we checked eUp and eLo, and decided that eUp->Org is barely
+ * above eLo. Then later, we split eLo into two edges (eg. from
+ * a splice operation like this one). This can change the result of
+ * our test so that now eUp->Org is incident to eLo, or barely below it.
+ * We must correct this condition to maintain the dictionary invariants.
+ *
+ * One possibility is to check these edges for intersection again
+ * (ie. CheckForIntersect). This is what we do if possible. However
+ * CheckForIntersect requires that tess->event lies between eUp and eLo,
+ * so that it has something to fall back on when the intersection
+ * calculation gives us an unusable answer. So, for those cases where
+ * we can't check for intersection, this routine fixes the problem
+ * by just splicing the offending vertex into the other edge.
+ * This is a guaranteed solution, no matter how degenerate things get.
+ * Basically this is a combinatorial solution to a numerical problem.
+ */
+{
+ ActiveRegion *regLo = RegionBelow(regUp);
+ GLUhalfEdge *eUp = regUp->eUp;
+ GLUhalfEdge *eLo = regLo->eUp;
+
+ if( VertLeq( eUp->Org, eLo->Org )) {
+ if( EdgeSign( eLo->Dst, eUp->Org, eLo->Org ) > 0 ) return FALSE;
+
+ /* eUp->Org appears to be below eLo */
+ if( ! VertEq( eUp->Org, eLo->Org )) {
+ /* Splice eUp->Org into eLo */
+ if ( __gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eUp, eLo->Oprev ) ) longjmp(tess->env,1);
+ regUp->dirty = regLo->dirty = TRUE;
+
+ } else if( eUp->Org != eLo->Org ) {
+ /* merge the two vertices, discarding eUp->Org */
+ pqDelete( tess->pq, eUp->Org->pqHandle ); /* __gl_pqSortDelete */
+ SpliceMergeVertices( tess, eLo->Oprev, eUp );
+ }
+ } else {
+ if( EdgeSign( eUp->Dst, eLo->Org, eUp->Org ) < 0 ) return FALSE;
+
+ /* eLo->Org appears to be above eUp, so splice eLo->Org into eUp */
+ RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
+ if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eLo->Oprev, eUp ) ) longjmp(tess->env,1);
+ }
+ return TRUE;
+}
+
+static int CheckForLeftSplice( GLUtesselator *tess, ActiveRegion *regUp )
+/*
+ * Check the upper and lower edge of "regUp", to make sure that the
+ * eUp->Dst is above eLo, or eLo->Dst is below eUp (depending on which
+ * destination is rightmost).
+ *
+ * Theoretically, this should always be true. However, splitting an edge
+ * into two pieces can change the results of previous tests. For example,
+ * suppose at one point we checked eUp and eLo, and decided that eUp->Dst
+ * is barely above eLo. Then later, we split eLo into two edges (eg. from
+ * a splice operation like this one). This can change the result of
+ * the test so that now eUp->Dst is incident to eLo, or barely below it.
+ * We must correct this condition to maintain the dictionary invariants
+ * (otherwise new edges might get inserted in the wrong place in the
+ * dictionary, and bad stuff will happen).
+ *
+ * We fix the problem by just splicing the offending vertex into the
+ * other edge.
+ */
+{
+ ActiveRegion *regLo = RegionBelow(regUp);
+ GLUhalfEdge *eUp = regUp->eUp;
+ GLUhalfEdge *eLo = regLo->eUp;
+ GLUhalfEdge *e;
+
+ assert( ! VertEq( eUp->Dst, eLo->Dst ));
+
+ if( VertLeq( eUp->Dst, eLo->Dst )) {
+ if( EdgeSign( eUp->Dst, eLo->Dst, eUp->Org ) < 0 ) return FALSE;
+
+ /* eLo->Dst is above eUp, so splice eLo->Dst into eUp */
+ RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
+ e = __gl_meshSplitEdge( eUp );
+ if (e == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eLo->Sym, e ) ) longjmp(tess->env,1);
+ e->Lface->inside = regUp->inside;
+ } else {
+ if( EdgeSign( eLo->Dst, eUp->Dst, eLo->Org ) > 0 ) return FALSE;
+
+ /* eUp->Dst is below eLo, so splice eUp->Dst into eLo */
+ regUp->dirty = regLo->dirty = TRUE;
+ e = __gl_meshSplitEdge( eLo );
+ if (e == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eUp->Lnext, eLo->Sym ) ) longjmp(tess->env,1);
+ e->Rface->inside = regUp->inside;
+ }
+ return TRUE;
+}
+
+
+static int CheckForIntersect( GLUtesselator *tess, ActiveRegion *regUp )
+/*
+ * Check the upper and lower edges of the given region to see if
+ * they intersect. If so, create the intersection and add it
+ * to the data structures.
+ *
+ * Returns TRUE if adding the new intersection resulted in a recursive
+ * call to AddRightEdges(); in this case all "dirty" regions have been
+ * checked for intersections, and possibly regUp has been deleted.
+ */
+{
+ ActiveRegion *regLo = RegionBelow(regUp);
+ GLUhalfEdge *eUp = regUp->eUp;
+ GLUhalfEdge *eLo = regLo->eUp;
+ GLUvertex *orgUp = eUp->Org;
+ GLUvertex *orgLo = eLo->Org;
+ GLUvertex *dstUp = eUp->Dst;
+ GLUvertex *dstLo = eLo->Dst;
+ GLdouble tMinUp, tMaxLo;
+ GLUvertex isect, *orgMin;
+ GLUhalfEdge *e;
+
+ assert( ! VertEq( dstLo, dstUp ));
+ assert( EdgeSign( dstUp, tess->event, orgUp ) <= 0 );
+ assert( EdgeSign( dstLo, tess->event, orgLo ) >= 0 );
+ assert( orgUp != tess->event && orgLo != tess->event );
+ assert( ! regUp->fixUpperEdge && ! regLo->fixUpperEdge );
+
+ if( orgUp == orgLo ) return FALSE; /* right endpoints are the same */
+
+ tMinUp = MIN( orgUp->t, dstUp->t );
+ tMaxLo = MAX( orgLo->t, dstLo->t );
+ if( tMinUp > tMaxLo ) return FALSE; /* t ranges do not overlap */
+
+ if( VertLeq( orgUp, orgLo )) {
+ if( EdgeSign( dstLo, orgUp, orgLo ) > 0 ) return FALSE;
+ } else {
+ if( EdgeSign( dstUp, orgLo, orgUp ) < 0 ) return FALSE;
+ }
+
+ /* At this point the edges intersect, at least marginally */
+ DebugEvent( tess );
+
+ __gl_edgeIntersect( dstUp, orgUp, dstLo, orgLo, &isect );
+ /* The following properties are guaranteed: */
+ assert( MIN( orgUp->t, dstUp->t ) <= isect.t );
+ assert( isect.t <= MAX( orgLo->t, dstLo->t ));
+ assert( MIN( dstLo->s, dstUp->s ) <= isect.s );
+ assert( isect.s <= MAX( orgLo->s, orgUp->s ));
+
+ if( VertLeq( &isect, tess->event )) {
+ /* The intersection point lies slightly to the left of the sweep line,
+ * so move it until it''s slightly to the right of the sweep line.
+ * (If we had perfect numerical precision, this would never happen
+ * in the first place). The easiest and safest thing to do is
+ * replace the intersection by tess->event.
+ */
+ isect.s = tess->event->s;
+ isect.t = tess->event->t;
+ }
+ /* Similarly, if the computed intersection lies to the right of the
+ * rightmost origin (which should rarely happen), it can cause
+ * unbelievable inefficiency on sufficiently degenerate inputs.
+ * (If you have the test program, try running test54.d with the
+ * "X zoom" option turned on).
+ */
+ orgMin = VertLeq( orgUp, orgLo ) ? orgUp : orgLo;
+ if( VertLeq( orgMin, &isect )) {
+ isect.s = orgMin->s;
+ isect.t = orgMin->t;
+ }
+
+ if( VertEq( &isect, orgUp ) || VertEq( &isect, orgLo )) {
+ /* Easy case -- intersection at one of the right endpoints */
+ (void) CheckForRightSplice( tess, regUp );
+ return FALSE;
+ }
+
+ if( (! VertEq( dstUp, tess->event )
+ && EdgeSign( dstUp, tess->event, &isect ) >= 0)
+ || (! VertEq( dstLo, tess->event )
+ && EdgeSign( dstLo, tess->event, &isect ) <= 0 ))
+ {
+ /* Very unusual -- the new upper or lower edge would pass on the
+ * wrong side of the sweep event, or through it. This can happen
+ * due to very small numerical errors in the intersection calculation.
+ */
+ if( dstLo == tess->event ) {
+ /* Splice dstLo into eUp, and process the new region(s) */
+ if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eLo->Sym, eUp ) ) longjmp(tess->env,1);
+ regUp = TopLeftRegion( regUp );
+ if (regUp == NULL) longjmp(tess->env,1);
+ eUp = RegionBelow(regUp)->eUp;
+ FinishLeftRegions( tess, RegionBelow(regUp), regLo );
+ AddRightEdges( tess, regUp, eUp->Oprev, eUp, eUp, TRUE );
+ return TRUE;
+ }
+ if( dstUp == tess->event ) {
+ /* Splice dstUp into eLo, and process the new region(s) */
+ if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eUp->Lnext, eLo->Oprev ) ) longjmp(tess->env,1);
+ regLo = regUp;
+ regUp = TopRightRegion( regUp );
+ e = RegionBelow(regUp)->eUp->Rprev;
+ regLo->eUp = eLo->Oprev;
+ eLo = FinishLeftRegions( tess, regLo, NULL );
+ AddRightEdges( tess, regUp, eLo->Onext, eUp->Rprev, e, TRUE );
+ return TRUE;
+ }
+ /* Special case: called from ConnectRightVertex. If either
+ * edge passes on the wrong side of tess->event, split it
+ * (and wait for ConnectRightVertex to splice it appropriately).
+ */
+ if( EdgeSign( dstUp, tess->event, &isect ) >= 0 ) {
+ RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
+ if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
+ eUp->Org->s = tess->event->s;
+ eUp->Org->t = tess->event->t;
+ }
+ if( EdgeSign( dstLo, tess->event, &isect ) <= 0 ) {
+ regUp->dirty = regLo->dirty = TRUE;
+ if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
+ eLo->Org->s = tess->event->s;
+ eLo->Org->t = tess->event->t;
+ }
+ /* leave the rest for ConnectRightVertex */
+ return FALSE;
+ }
+
+ /* General case -- split both edges, splice into new vertex.
+ * When we do the splice operation, the order of the arguments is
+ * arbitrary as far as correctness goes. However, when the operation
+ * creates a new face, the work done is proportional to the size of
+ * the new face. We expect the faces in the processed part of
+ * the mesh (ie. eUp->Lface) to be smaller than the faces in the
+ * unprocessed original contours (which will be eLo->Oprev->Lface).
+ */
+ if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
+ if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
+ if ( !__gl_meshSplice( eLo->Oprev, eUp ) ) longjmp(tess->env,1);
+ eUp->Org->s = isect.s;
+ eUp->Org->t = isect.t;
+ eUp->Org->pqHandle = pqInsert( tess->pq, eUp->Org ); /* __gl_pqSortInsert */
+ if (eUp->Org->pqHandle == LONG_MAX) {
+ pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */
+ tess->pq = NULL;
+ longjmp(tess->env,1);
+ }
+ GetIntersectData( tess, eUp->Org, orgUp, dstUp, orgLo, dstLo );
+ RegionAbove(regUp)->dirty = regUp->dirty = regLo->dirty = TRUE;
+ return FALSE;
+}
+
+static void WalkDirtyRegions( GLUtesselator *tess, ActiveRegion *regUp )
+/*
+ * When the upper or lower edge of any region changes, the region is
+ * marked "dirty". This routine walks through all the dirty regions
+ * and makes sure that the dictionary invariants are satisfied
+ * (see the comments at the beginning of this file). Of course
+ * new dirty regions can be created as we make changes to restore
+ * the invariants.
+ */
+{
+ ActiveRegion *regLo = RegionBelow(regUp);
+ GLUhalfEdge *eUp, *eLo;
+
+ for( ;; ) {
+ /* Find the lowest dirty region (we walk from the bottom up). */
+ while( regLo->dirty ) {
+ regUp = regLo;
+ regLo = RegionBelow(regLo);
+ }
+ if( ! regUp->dirty ) {
+ regLo = regUp;
+ regUp = RegionAbove( regUp );
+ if( regUp == NULL || ! regUp->dirty ) {
+ /* We've walked all the dirty regions */
+ return;
+ }
+ }
+ regUp->dirty = FALSE;
+ eUp = regUp->eUp;
+ eLo = regLo->eUp;
+
+ if( eUp->Dst != eLo->Dst ) {
+ /* Check that the edge ordering is obeyed at the Dst vertices. */
+ if( CheckForLeftSplice( tess, regUp )) {
+
+ /* If the upper or lower edge was marked fixUpperEdge, then
+ * we no longer need it (since these edges are needed only for
+ * vertices which otherwise have no right-going edges).
+ */
+ if( regLo->fixUpperEdge ) {
+ DeleteRegion( tess, regLo );
+ if ( !__gl_meshDelete( eLo ) ) longjmp(tess->env,1);
+ regLo = RegionBelow( regUp );
+ eLo = regLo->eUp;
+ } else if( regUp->fixUpperEdge ) {
+ DeleteRegion( tess, regUp );
+ if ( !__gl_meshDelete( eUp ) ) longjmp(tess->env,1);
+ regUp = RegionAbove( regLo );
+ eUp = regUp->eUp;
+ }
+ }
+ }
+ if( eUp->Org != eLo->Org ) {
+ if( eUp->Dst != eLo->Dst
+ && ! regUp->fixUpperEdge && ! regLo->fixUpperEdge
+ && (eUp->Dst == tess->event || eLo->Dst == tess->event) )
+ {
+ /* When all else fails in CheckForIntersect(), it uses tess->event
+ * as the intersection location. To make this possible, it requires
+ * that tess->event lie between the upper and lower edges, and also
+ * that neither of these is marked fixUpperEdge (since in the worst
+ * case it might splice one of these edges into tess->event, and
+ * violate the invariant that fixable edges are the only right-going
+ * edge from their associated vertex).
+ */
+ if( CheckForIntersect( tess, regUp )) {
+ /* WalkDirtyRegions() was called recursively; we're done */
+ return;
+ }
+ } else {
+ /* Even though we can't use CheckForIntersect(), the Org vertices
+ * may violate the dictionary edge ordering. Check and correct this.
+ */
+ (void) CheckForRightSplice( tess, regUp );
+ }
+ }
+ if( eUp->Org == eLo->Org && eUp->Dst == eLo->Dst ) {
+ /* A degenerate loop consisting of only two edges -- delete it. */
+ AddWinding( eLo, eUp );
+ DeleteRegion( tess, regUp );
+ if ( !__gl_meshDelete( eUp ) ) longjmp(tess->env,1);
+ regUp = RegionAbove( regLo );
+ }
+ }
+}
+
+
+static void ConnectRightVertex( GLUtesselator *tess, ActiveRegion *regUp,
+ GLUhalfEdge *eBottomLeft )
+/*
+ * Purpose: connect a "right" vertex vEvent (one where all edges go left)
+ * to the unprocessed portion of the mesh. Since there are no right-going
+ * edges, two regions (one above vEvent and one below) are being merged
+ * into one. "regUp" is the upper of these two regions.
+ *
+ * There are two reasons for doing this (adding a right-going edge):
+ * - if the two regions being merged are "inside", we must add an edge
+ * to keep them separated (the combined region would not be monotone).
+ * - in any case, we must leave some record of vEvent in the dictionary,
+ * so that we can merge vEvent with features that we have not seen yet.
+ * For example, maybe there is a vertical edge which passes just to
+ * the right of vEvent; we would like to splice vEvent into this edge.
+ *
+ * However, we don't want to connect vEvent to just any vertex. We don''t
+ * want the new edge to cross any other edges; otherwise we will create
+ * intersection vertices even when the input data had no self-intersections.
+ * (This is a bad thing; if the user's input data has no intersections,
+ * we don't want to generate any false intersections ourselves.)
+ *
+ * Our eventual goal is to connect vEvent to the leftmost unprocessed
+ * vertex of the combined region (the union of regUp and regLo).
+ * But because of unseen vertices with all right-going edges, and also
+ * new vertices which may be created by edge intersections, we don''t
+ * know where that leftmost unprocessed vertex is. In the meantime, we
+ * connect vEvent to the closest vertex of either chain, and mark the region
+ * as "fixUpperEdge". This flag says to delete and reconnect this edge
+ * to the next processed vertex on the boundary of the combined region.
+ * Quite possibly the vertex we connected to will turn out to be the
+ * closest one, in which case we won''t need to make any changes.
+ */
+{
+ GLUhalfEdge *eNew;
+ GLUhalfEdge *eTopLeft = eBottomLeft->Onext;
+ ActiveRegion *regLo = RegionBelow(regUp);
+ GLUhalfEdge *eUp = regUp->eUp;
+ GLUhalfEdge *eLo = regLo->eUp;
+ int degenerate = FALSE;
+
+ if( eUp->Dst != eLo->Dst ) {
+ (void) CheckForIntersect( tess, regUp );
+ }
+
+ /* Possible new degeneracies: upper or lower edge of regUp may pass
+ * through vEvent, or may coincide with new intersection vertex
+ */
+ if( VertEq( eUp->Org, tess->event )) {
+ if ( !__gl_meshSplice( eTopLeft->Oprev, eUp ) ) longjmp(tess->env,1);
+ regUp = TopLeftRegion( regUp );
+ if (regUp == NULL) longjmp(tess->env,1);
+ eTopLeft = RegionBelow( regUp )->eUp;
+ FinishLeftRegions( tess, RegionBelow(regUp), regLo );
+ degenerate = TRUE;
+ }
+ if( VertEq( eLo->Org, tess->event )) {
+ if ( !__gl_meshSplice( eBottomLeft, eLo->Oprev ) ) longjmp(tess->env,1);
+ eBottomLeft = FinishLeftRegions( tess, regLo, NULL );
+ degenerate = TRUE;
+ }
+ if( degenerate ) {
+ AddRightEdges( tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE );
+ return;
+ }
+
+ /* Non-degenerate situation -- need to add a temporary, fixable edge.
+ * Connect to the closer of eLo->Org, eUp->Org.
+ */
+ if( VertLeq( eLo->Org, eUp->Org )) {
+ eNew = eLo->Oprev;
+ } else {
+ eNew = eUp;
+ }
+ eNew = __gl_meshConnect( eBottomLeft->Lprev, eNew );
+ if (eNew == NULL) longjmp(tess->env,1);
+
+ /* Prevent cleanup, otherwise eNew might disappear before we've even
+ * had a chance to mark it as a temporary edge.
+ */
+ AddRightEdges( tess, regUp, eNew, eNew->Onext, eNew->Onext, FALSE );
+ eNew->Sym->activeRegion->fixUpperEdge = TRUE;
+ WalkDirtyRegions( tess, regUp );
+}
+
+/* Because vertices at exactly the same location are merged together
+ * before we process the sweep event, some degenerate cases can't occur.
+ * However if someone eventually makes the modifications required to
+ * merge features which are close together, the cases below marked
+ * TOLERANCE_NONZERO will be useful. They were debugged before the
+ * code to merge identical vertices in the main loop was added.
+ */
+#define TOLERANCE_NONZERO FALSE
+
+static void ConnectLeftDegenerate( GLUtesselator *tess,
+ ActiveRegion *regUp, GLUvertex *vEvent )
+/*
+ * The event vertex lies exacty on an already-processed edge or vertex.
+ * Adding the new vertex involves splicing it into the already-processed
+ * part of the mesh.
+ */
+{
+ GLUhalfEdge *e, *eTopLeft, *eTopRight, *eLast;
+ ActiveRegion *reg;
+
+ e = regUp->eUp;
+ if( VertEq( e->Org, vEvent )) {
+ /* e->Org is an unprocessed vertex - just combine them, and wait
+ * for e->Org to be pulled from the queue
+ */
+ assert( TOLERANCE_NONZERO );
+ SpliceMergeVertices( tess, e, vEvent->anEdge );
+ return;
+ }
+
+ if( ! VertEq( e->Dst, vEvent )) {
+ /* General case -- splice vEvent into edge e which passes through it */
+ if (__gl_meshSplitEdge( e->Sym ) == NULL) longjmp(tess->env,1);
+ if( regUp->fixUpperEdge ) {
+ /* This edge was fixable -- delete unused portion of original edge */
+ if ( !__gl_meshDelete( e->Onext ) ) longjmp(tess->env,1);
+ regUp->fixUpperEdge = FALSE;
+ }
+ if ( !__gl_meshSplice( vEvent->anEdge, e ) ) longjmp(tess->env,1);
+ SweepEvent( tess, vEvent ); /* recurse */
+ return;
+ }
+
+ /* vEvent coincides with e->Dst, which has already been processed.
+ * Splice in the additional right-going edges.
+ */
+ assert( TOLERANCE_NONZERO );
+ regUp = TopRightRegion( regUp );
+ reg = RegionBelow( regUp );
+ eTopRight = reg->eUp->Sym;
+ eTopLeft = eLast = eTopRight->Onext;
+ if( reg->fixUpperEdge ) {
+ /* Here e->Dst has only a single fixable edge going right.
+ * We can delete it since now we have some real right-going edges.
+ */
+ assert( eTopLeft != eTopRight ); /* there are some left edges too */
+ DeleteRegion( tess, reg );
+ if ( !__gl_meshDelete( eTopRight ) ) longjmp(tess->env,1);
+ eTopRight = eTopLeft->Oprev;
+ }
+ if ( !__gl_meshSplice( vEvent->anEdge, eTopRight ) ) longjmp(tess->env,1);
+ if( ! EdgeGoesLeft( eTopLeft )) {
+ /* e->Dst had no left-going edges -- indicate this to AddRightEdges() */
+ eTopLeft = NULL;
+ }
+ AddRightEdges( tess, regUp, eTopRight->Onext, eLast, eTopLeft, TRUE );
+}
+
+
+static void ConnectLeftVertex( GLUtesselator *tess, GLUvertex *vEvent )
+/*
+ * Purpose: connect a "left" vertex (one where both edges go right)
+ * to the processed portion of the mesh. Let R be the active region
+ * containing vEvent, and let U and L be the upper and lower edge
+ * chains of R. There are two possibilities:
+ *
+ * - the normal case: split R into two regions, by connecting vEvent to
+ * the rightmost vertex of U or L lying to the left of the sweep line
+ *
+ * - the degenerate case: if vEvent is close enough to U or L, we
+ * merge vEvent into that edge chain. The subcases are:
+ * - merging with the rightmost vertex of U or L
+ * - merging with the active edge of U or L
+ * - merging with an already-processed portion of U or L
+ */
+{
+ ActiveRegion *regUp, *regLo, *reg;
+ GLUhalfEdge *eUp, *eLo, *eNew;
+ ActiveRegion tmp;
+
+ /* assert( vEvent->anEdge->Onext->Onext == vEvent->anEdge ); */
+
+ /* Get a pointer to the active region containing vEvent */
+ tmp.eUp = vEvent->anEdge->Sym;
+ /* __GL_DICTLISTKEY */ /* __gl_dictListSearch */
+ regUp = (ActiveRegion *)dictKey( dictSearch( tess->dict, &tmp ));
+ regLo = RegionBelow( regUp );
+ eUp = regUp->eUp;
+ eLo = regLo->eUp;
+
+ /* Try merging with U or L first */
+ if( EdgeSign( eUp->Dst, vEvent, eUp->Org ) == 0 ) {
+ ConnectLeftDegenerate( tess, regUp, vEvent );
+ return;
+ }
+
+ /* Connect vEvent to rightmost processed vertex of either chain.
+ * e->Dst is the vertex that we will connect to vEvent.
+ */
+ reg = VertLeq( eLo->Dst, eUp->Dst ) ? regUp : regLo;
+
+ if( regUp->inside || reg->fixUpperEdge) {
+ if( reg == regUp ) {
+ eNew = __gl_meshConnect( vEvent->anEdge->Sym, eUp->Lnext );
+ if (eNew == NULL) longjmp(tess->env,1);
+ } else {
+ GLUhalfEdge *tempHalfEdge= __gl_meshConnect( eLo->Dnext, vEvent->anEdge);
+ if (tempHalfEdge == NULL) longjmp(tess->env,1);
+
+ eNew = tempHalfEdge->Sym;
+ }
+ if( reg->fixUpperEdge ) {
+ if ( !FixUpperEdge( reg, eNew ) ) longjmp(tess->env,1);
+ } else {
+ ComputeWinding( tess, AddRegionBelow( tess, regUp, eNew ));
+ }
+ SweepEvent( tess, vEvent );
+ } else {
+ /* The new vertex is in a region which does not belong to the polygon.
+ * We don''t need to connect this vertex to the rest of the mesh.
+ */
+ AddRightEdges( tess, regUp, vEvent->anEdge, vEvent->anEdge, NULL, TRUE );
+ }
+}
+
+
+static void SweepEvent( GLUtesselator *tess, GLUvertex *vEvent )
+/*
+ * Does everything necessary when the sweep line crosses a vertex.
+ * Updates the mesh and the edge dictionary.
+ */
+{
+ ActiveRegion *regUp, *reg;
+ GLUhalfEdge *e, *eTopLeft, *eBottomLeft;
+
+ tess->event = vEvent; /* for access in EdgeLeq() */
+ DebugEvent( tess );
+
+ /* Check if this vertex is the right endpoint of an edge that is
+ * already in the dictionary. In this case we don't need to waste
+ * time searching for the location to insert new edges.
+ */
+ e = vEvent->anEdge;
+ while( e->activeRegion == NULL ) {
+ e = e->Onext;
+ if( e == vEvent->anEdge ) {
+ /* All edges go right -- not incident to any processed edges */
+ ConnectLeftVertex( tess, vEvent );
+ return;
+ }
+ }
+
+ /* Processing consists of two phases: first we "finish" all the
+ * active regions where both the upper and lower edges terminate
+ * at vEvent (ie. vEvent is closing off these regions).
+ * We mark these faces "inside" or "outside" the polygon according
+ * to their winding number, and delete the edges from the dictionary.
+ * This takes care of all the left-going edges from vEvent.
+ */
+ regUp = TopLeftRegion( e->activeRegion );
+ if (regUp == NULL) longjmp(tess->env,1);
+ reg = RegionBelow( regUp );
+ eTopLeft = reg->eUp;
+ eBottomLeft = FinishLeftRegions( tess, reg, NULL );
+
+ /* Next we process all the right-going edges from vEvent. This
+ * involves adding the edges to the dictionary, and creating the
+ * associated "active regions" which record information about the
+ * regions between adjacent dictionary edges.
+ */
+ if( eBottomLeft->Onext == eTopLeft ) {
+ /* No right-going edges -- add a temporary "fixable" edge */
+ ConnectRightVertex( tess, regUp, eBottomLeft );
+ } else {
+ AddRightEdges( tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE );
+ }
+}
+
+
+/* Make the sentinel coordinates big enough that they will never be
+ * merged with real input features. (Even with the largest possible
+ * input contour and the maximum tolerance of 1.0, no merging will be
+ * done with coordinates larger than 3 * GLU_TESS_MAX_COORD).
+ */
+#define SENTINEL_COORD (4 * GLU_TESS_MAX_COORD)
+
+static void AddSentinel( GLUtesselator *tess, GLdouble t )
+/*
+ * We add two sentinel edges above and below all other edges,
+ * to avoid special cases at the top and bottom.
+ */
+{
+ GLUhalfEdge *e;
+ ActiveRegion *reg = (ActiveRegion *)memAlloc( sizeof( ActiveRegion ));
+ if (reg == NULL) longjmp(tess->env,1);
+
+ e = __gl_meshMakeEdge( tess->mesh );
+ if (e == NULL) longjmp(tess->env,1);
+
+ e->Org->s = SENTINEL_COORD;
+ e->Org->t = t;
+ e->Dst->s = -SENTINEL_COORD;
+ e->Dst->t = t;
+ tess->event = e->Dst; /* initialize it */
+
+ reg->eUp = e;
+ reg->windingNumber = 0;
+ reg->inside = FALSE;
+ reg->fixUpperEdge = FALSE;
+ reg->sentinel = TRUE;
+ reg->dirty = FALSE;
+ reg->nodeUp = dictInsert( tess->dict, reg ); /* __gl_dictListInsertBefore */
+ if (reg->nodeUp == NULL) longjmp(tess->env,1);
+}
+
+
+static void InitEdgeDict( GLUtesselator *tess )
+/*
+ * We maintain an ordering of edge intersections with the sweep line.
+ * This order is maintained in a dynamic dictionary.
+ */
+{
+ /* __gl_dictListNewDict */
+ tess->dict = dictNewDict( tess, (int (*)(void *, DictKey, DictKey)) EdgeLeq );
+ if (tess->dict == NULL) longjmp(tess->env,1);
+
+ AddSentinel( tess, -SENTINEL_COORD );
+ AddSentinel( tess, SENTINEL_COORD );
+}
+
+
+static void DoneEdgeDict( GLUtesselator *tess )
+{
+ ActiveRegion *reg;
+ int fixedEdges = 0;
+
+ /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
+ while( (reg = (ActiveRegion *)dictKey( dictMin( tess->dict ))) != NULL ) {
+ /*
+ * At the end of all processing, the dictionary should contain
+ * only the two sentinel edges, plus at most one "fixable" edge
+ * created by ConnectRightVertex().
+ */
+ if( ! reg->sentinel ) {
+ assert( reg->fixUpperEdge );
+ assert( ++fixedEdges == 1 );
+ }
+ assert( reg->windingNumber == 0 );
+ DeleteRegion( tess, reg );
+/* __gl_meshDelete( reg->eUp );*/
+ }
+ dictDeleteDict( tess->dict ); /* __gl_dictListDeleteDict */
+}
+
+
+static void RemoveDegenerateEdges( GLUtesselator *tess )
+/*
+ * Remove zero-length edges, and contours with fewer than 3 vertices.
+ */
+{
+ GLUhalfEdge *e, *eNext, *eLnext;
+ GLUhalfEdge *eHead = &tess->mesh->eHead;
+
+ /*LINTED*/
+ for( e = eHead->next; e != eHead; e = eNext ) {
+ eNext = e->next;
+ eLnext = e->Lnext;
+
+ if( VertEq( e->Org, e->Dst ) && e->Lnext->Lnext != e ) {
+ /* Zero-length edge, contour has at least 3 edges */
+
+ SpliceMergeVertices( tess, eLnext, e ); /* deletes e->Org */
+ if ( !__gl_meshDelete( e ) ) longjmp(tess->env,1); /* e is a self-loop */
+ e = eLnext;
+ eLnext = e->Lnext;
+ }
+ if( eLnext->Lnext == e ) {
+ /* Degenerate contour (one or two edges) */
+
+ if( eLnext != e ) {
+ if( eLnext == eNext || eLnext == eNext->Sym ) { eNext = eNext->next; }
+ if ( !__gl_meshDelete( eLnext ) ) longjmp(tess->env,1);
+ }
+ if( e == eNext || e == eNext->Sym ) { eNext = eNext->next; }
+ if ( !__gl_meshDelete( e ) ) longjmp(tess->env,1);
+ }
+ }
+}
+
+static int InitPriorityQ( GLUtesselator *tess )
+/*
+ * Insert all vertices into the priority queue which determines the
+ * order in which vertices cross the sweep line.
+ */
+{
+ PriorityQ *pq;
+ GLUvertex *v, *vHead;
+
+ /* __gl_pqSortNewPriorityQ */
+ pq = tess->pq = pqNewPriorityQ( (int (*)(PQkey, PQkey)) __gl_vertLeq );
+ if (pq == NULL) return 0;
+
+ vHead = &tess->mesh->vHead;
+ for( v = vHead->next; v != vHead; v = v->next ) {
+ v->pqHandle = pqInsert( pq, v ); /* __gl_pqSortInsert */
+ if (v->pqHandle == LONG_MAX) break;
+ }
+ if (v != vHead || !pqInit( pq ) ) { /* __gl_pqSortInit */
+ pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */
+ tess->pq = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static void DonePriorityQ( GLUtesselator *tess )
+{
+ pqDeletePriorityQ( tess->pq ); /* __gl_pqSortDeletePriorityQ */
+}
+
+
+static int RemoveDegenerateFaces( GLUmesh *mesh )
+/*
+ * Delete any degenerate faces with only two edges. WalkDirtyRegions()
+ * will catch almost all of these, but it won't catch degenerate faces
+ * produced by splice operations on already-processed edges.
+ * The two places this can happen are in FinishLeftRegions(), when
+ * we splice in a "temporary" edge produced by ConnectRightVertex(),
+ * and in CheckForLeftSplice(), where we splice already-processed
+ * edges to ensure that our dictionary invariants are not violated
+ * by numerical errors.
+ *
+ * In both these cases it is *very* dangerous to delete the offending
+ * edge at the time, since one of the routines further up the stack
+ * will sometimes be keeping a pointer to that edge.
+ */
+{
+ GLUface *f, *fNext;
+ GLUhalfEdge *e;
+
+ /*LINTED*/
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) {
+ fNext = f->next;
+ e = f->anEdge;
+ assert( e->Lnext != e );
+
+ if( e->Lnext->Lnext == e ) {
+ /* A face with only two edges */
+ AddWinding( e->Onext, e );
+ if ( !__gl_meshDelete( e ) ) return 0;
+ }
+ }
+ return 1;
+}
+
+int __gl_computeInterior( GLUtesselator *tess )
+/*
+ * __gl_computeInterior( tess ) computes the planar arrangement specified
+ * by the given contours, and further subdivides this arrangement
+ * into regions. Each region is marked "inside" if it belongs
+ * to the polygon, according to the rule given by tess->windingRule.
+ * Each interior region is guaranteed be monotone.
+ */
+{
+ GLUvertex *v, *vNext;
+
+ tess->fatalError = FALSE;
+
+ /* Each vertex defines an event for our sweep line. Start by inserting
+ * all the vertices in a priority queue. Events are processed in
+ * lexicographic order, ie.
+ *
+ * e1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y)
+ */
+ RemoveDegenerateEdges( tess );
+ if ( !InitPriorityQ( tess ) ) return 0; /* if error */
+ InitEdgeDict( tess );
+
+ /* __gl_pqSortExtractMin */
+ while( (v = (GLUvertex *)pqExtractMin( tess->pq )) != NULL ) {
+ for( ;; ) {
+ vNext = (GLUvertex *)pqMinimum( tess->pq ); /* __gl_pqSortMinimum */
+ if( vNext == NULL || ! VertEq( vNext, v )) break;
+
+ /* Merge together all vertices at exactly the same location.
+ * This is more efficient than processing them one at a time,
+ * simplifies the code (see ConnectLeftDegenerate), and is also
+ * important for correct handling of certain degenerate cases.
+ * For example, suppose there are two identical edges A and B
+ * that belong to different contours (so without this code they would
+ * be processed by separate sweep events). Suppose another edge C
+ * crosses A and B from above. When A is processed, we split it
+ * at its intersection point with C. However this also splits C,
+ * so when we insert B we may compute a slightly different
+ * intersection point. This might leave two edges with a small
+ * gap between them. This kind of error is especially obvious
+ * when using boundary extraction (GLU_TESS_BOUNDARY_ONLY).
+ */
+ vNext = (GLUvertex *)pqExtractMin( tess->pq ); /* __gl_pqSortExtractMin*/
+ SpliceMergeVertices( tess, v->anEdge, vNext->anEdge );
+ }
+ SweepEvent( tess, v );
+ }
+
+ /* Set tess->event for debugging purposes */
+ /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
+ tess->event = ((ActiveRegion *) dictKey( dictMin( tess->dict )))->eUp->Org;
+ DebugEvent( tess );
+ DoneEdgeDict( tess );
+ DonePriorityQ( tess );
+
+ if ( !RemoveDegenerateFaces( tess->mesh ) ) return 0;
+ __gl_meshCheckMesh( tess->mesh );
+
+ return 1;
+}
diff --git a/WebCore/thirdparty/glu/libtess/sweep.h b/WebCore/thirdparty/glu/libtess/sweep.h
new file mode 100644
index 0000000..c099450
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/sweep.h
@@ -0,0 +1,84 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/sweep.h#5 $
+*/
+
+#ifndef __sweep_h_
+#define __sweep_h_
+
+#include "thirdparty/glu/libtess/mesh.h"
+
+/* __gl_computeInterior( tess ) computes the planar arrangement specified
+ * by the given contours, and further subdivides this arrangement
+ * into regions. Each region is marked "inside" if it belongs
+ * to the polygon, according to the rule given by tess->windingRule.
+ * Each interior region is guaranteed be monotone.
+ */
+int __gl_computeInterior( GLUtesselator *tess );
+
+
+/* The following is here *only* for access by debugging routines */
+
+#include "dict.h"
+
+/* For each pair of adjacent edges crossing the sweep line, there is
+ * an ActiveRegion to represent the region between them. The active
+ * regions are kept in sorted order in a dynamic dictionary. As the
+ * sweep line crosses each vertex, we update the affected regions.
+ */
+
+struct ActiveRegion {
+ GLUhalfEdge *eUp; /* upper edge, directed right to left */
+ DictNode *nodeUp; /* dictionary node corresponding to eUp */
+ int windingNumber; /* used to determine which regions are
+ * inside the polygon */
+ GLboolean inside; /* is this region inside the polygon? */
+ GLboolean sentinel; /* marks fake edges at t = +/-infinity */
+ GLboolean dirty; /* marks regions where the upper or lower
+ * edge has changed, but we haven't checked
+ * whether they intersect yet */
+ GLboolean fixUpperEdge; /* marks temporary edges introduced when
+ * we process a "right vertex" (one without
+ * any edges leaving to the right) */
+};
+
+#define RegionBelow(r) ((ActiveRegion *) dictKey(dictPred((r)->nodeUp)))
+#define RegionAbove(r) ((ActiveRegion *) dictKey(dictSucc((r)->nodeUp)))
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/tess.c b/WebCore/thirdparty/glu/libtess/tess.c
new file mode 100644
index 0000000..5cba586
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/tess.c
@@ -0,0 +1,639 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/tess.c#7 $
+*/
+
+#include <assert.h>
+#include <setjmp.h>
+#include <stddef.h>
+
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/memalloc.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/normal.h"
+#include "thirdparty/glu/libtess/render.h"
+#include "thirdparty/glu/libtess/sweep.h"
+#include "thirdparty/glu/libtess/tess.h"
+#include "thirdparty/glu/libtess/tessmono.h"
+
+#define GLU_TESS_DEFAULT_TOLERANCE 0.0
+#define GLU_TESS_MESH 100112 /* void (*)(GLUmesh *mesh) */
+
+#define TRUE 1
+#define FALSE 0
+
+/*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {}
+/*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {}
+/*ARGSUSED*/ static void GLAPIENTRY noVertex( void *data ) {}
+/*ARGSUSED*/ static void GLAPIENTRY noEnd( void ) {}
+/*ARGSUSED*/ static void GLAPIENTRY noError( GLenum errnum ) {}
+/*ARGSUSED*/ static void GLAPIENTRY noCombine( GLdouble coords[3], void *data[4],
+ GLfloat weight[4], void **dataOut ) {}
+/*ARGSUSED*/ static void GLAPIENTRY noMesh( GLUmesh *mesh ) {}
+
+
+/*ARGSUSED*/ void GLAPIENTRY __gl_noBeginData( GLenum type,
+ void *polygonData ) {}
+/*ARGSUSED*/ void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge,
+ void *polygonData ) {}
+/*ARGSUSED*/ void GLAPIENTRY __gl_noVertexData( void *data,
+ void *polygonData ) {}
+/*ARGSUSED*/ void GLAPIENTRY __gl_noEndData( void *polygonData ) {}
+/*ARGSUSED*/ void GLAPIENTRY __gl_noErrorData( GLenum errnum,
+ void *polygonData ) {}
+/*ARGSUSED*/ void GLAPIENTRY __gl_noCombineData( GLdouble coords[3],
+ void *data[4],
+ GLfloat weight[4],
+ void **outData,
+ void *polygonData ) {}
+
+/* Half-edges are allocated in pairs (see mesh.c) */
+typedef struct { GLUhalfEdge e, eSym; } EdgePair;
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \
+ MAX(sizeof(GLUvertex),sizeof(GLUface))))
+
+
+GLUtesselator * GLAPIENTRY
+internal_gluNewTess( void )
+{
+ GLUtesselator *tess;
+
+ /* Only initialize fields which can be changed by the api. Other fields
+ * are initialized where they are used.
+ */
+
+ if (memInit( MAX_FAST_ALLOC ) == 0) {
+ return 0; /* out of memory */
+ }
+ tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator ));
+ if (tess == NULL) {
+ return 0; /* out of memory */
+ }
+
+ tess->state = T_DORMANT;
+
+ tess->normal[0] = 0;
+ tess->normal[1] = 0;
+ tess->normal[2] = 0;
+
+ tess->relTolerance = GLU_TESS_DEFAULT_TOLERANCE;
+ tess->windingRule = GLU_TESS_WINDING_ODD;
+ tess->flagBoundary = FALSE;
+ tess->boundaryOnly = FALSE;
+
+ tess->callBegin = &noBegin;
+ tess->callEdgeFlag = &noEdgeFlag;
+ tess->callVertex = &noVertex;
+ tess->callEnd = &noEnd;
+
+ tess->callError = &noError;
+ tess->callCombine = &noCombine;
+ tess->callMesh = &noMesh;
+
+ tess->callBeginData= &__gl_noBeginData;
+ tess->callEdgeFlagData= &__gl_noEdgeFlagData;
+ tess->callVertexData= &__gl_noVertexData;
+ tess->callEndData= &__gl_noEndData;
+ tess->callErrorData= &__gl_noErrorData;
+ tess->callCombineData= &__gl_noCombineData;
+
+ tess->polygonData= NULL;
+
+ return tess;
+}
+
+static void MakeDormant( GLUtesselator *tess )
+{
+ /* Return the tessellator to its original dormant state. */
+
+ if( tess->mesh != NULL ) {
+ __gl_meshDeleteMesh( tess->mesh );
+ }
+ tess->state = T_DORMANT;
+ tess->lastEdge = NULL;
+ tess->mesh = NULL;
+}
+
+#define RequireState( tess, s ) if( tess->state != s ) GotoState(tess,s)
+
+static void GotoState( GLUtesselator *tess, enum TessState newState )
+{
+ while( tess->state != newState ) {
+ /* We change the current state one level at a time, to get to
+ * the desired state.
+ */
+ if( tess->state < newState ) {
+ switch( tess->state ) {
+ case T_DORMANT:
+ CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON );
+ internal_gluTessBeginPolygon( tess, NULL );
+ break;
+ case T_IN_POLYGON:
+ CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR );
+ internal_gluTessBeginContour( tess );
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ } else {
+ switch( tess->state ) {
+ case T_IN_CONTOUR:
+ CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR );
+ internal_gluTessEndContour( tess );
+ break;
+ case T_IN_POLYGON:
+ CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON );
+ /* gluTessEndPolygon( tess ) is too much work! */
+ MakeDormant( tess );
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ }
+}
+
+
+void GLAPIENTRY
+internal_gluDeleteTess( GLUtesselator *tess )
+{
+ RequireState( tess, T_DORMANT );
+ memFree( tess );
+}
+
+
+void GLAPIENTRY
+internal_gluTessProperty( GLUtesselator *tess, GLenum which, GLdouble value )
+{
+ GLenum windingRule;
+
+ switch( which ) {
+ case GLU_TESS_TOLERANCE:
+ if( value < 0.0 || value > 1.0 ) break;
+ tess->relTolerance = value;
+ return;
+
+ case GLU_TESS_WINDING_RULE:
+ windingRule = (GLenum) value;
+ if( windingRule != value ) break; /* not an integer */
+
+ switch( windingRule ) {
+ case GLU_TESS_WINDING_ODD:
+ case GLU_TESS_WINDING_NONZERO:
+ case GLU_TESS_WINDING_POSITIVE:
+ case GLU_TESS_WINDING_NEGATIVE:
+ case GLU_TESS_WINDING_ABS_GEQ_TWO:
+ tess->windingRule = windingRule;
+ return;
+ default:
+ break;
+ }
+
+ case GLU_TESS_BOUNDARY_ONLY:
+ tess->boundaryOnly = (value != 0);
+ return;
+
+ default:
+ CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
+ return;
+ }
+ CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_VALUE );
+}
+
+/* Returns tessellator property */
+void GLAPIENTRY
+internal_gluGetTessProperty( GLUtesselator *tess, GLenum which, GLdouble *value )
+{
+ switch (which) {
+ case GLU_TESS_TOLERANCE:
+ /* tolerance should be in range [0..1] */
+ assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0);
+ *value= tess->relTolerance;
+ break;
+ case GLU_TESS_WINDING_RULE:
+ assert(tess->windingRule == GLU_TESS_WINDING_ODD ||
+ tess->windingRule == GLU_TESS_WINDING_NONZERO ||
+ tess->windingRule == GLU_TESS_WINDING_POSITIVE ||
+ tess->windingRule == GLU_TESS_WINDING_NEGATIVE ||
+ tess->windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO);
+ *value= tess->windingRule;
+ break;
+ case GLU_TESS_BOUNDARY_ONLY:
+ assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE);
+ *value= tess->boundaryOnly;
+ break;
+ default:
+ *value= 0.0;
+ CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
+ break;
+ }
+} /* gluGetTessProperty() */
+
+void GLAPIENTRY
+internal_gluTessNormal( GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z )
+{
+ tess->normal[0] = x;
+ tess->normal[1] = y;
+ tess->normal[2] = z;
+}
+
+void GLAPIENTRY
+internal_gluTessCallback( GLUtesselator *tess, GLenum which, void (GLAPIENTRY *fn)())
+{
+ switch( which ) {
+ case GLU_TESS_BEGIN:
+ tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn;
+ return;
+ case GLU_TESS_BEGIN_DATA:
+ tess->callBeginData = (fn == NULL) ?
+ &__gl_noBeginData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
+ return;
+ case GLU_TESS_EDGE_FLAG:
+ tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag :
+ (void (GLAPIENTRY *)(GLboolean)) fn;
+ /* If the client wants boundary edges to be flagged,
+ * we render everything as separate triangles (no strips or fans).
+ */
+ tess->flagBoundary = (fn != NULL);
+ return;
+ case GLU_TESS_EDGE_FLAG_DATA:
+ tess->callEdgeFlagData= (fn == NULL) ?
+ &__gl_noEdgeFlagData : (void (GLAPIENTRY *)(GLboolean, void *)) fn;
+ /* If the client wants boundary edges to be flagged,
+ * we render everything as separate triangles (no strips or fans).
+ */
+ tess->flagBoundary = (fn != NULL);
+ return;
+ case GLU_TESS_VERTEX:
+ tess->callVertex = (fn == NULL) ? &noVertex :
+ (void (GLAPIENTRY *)(void *)) fn;
+ return;
+ case GLU_TESS_VERTEX_DATA:
+ tess->callVertexData = (fn == NULL) ?
+ &__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn;
+ return;
+ case GLU_TESS_END:
+ tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn;
+ return;
+ case GLU_TESS_END_DATA:
+ tess->callEndData = (fn == NULL) ? &__gl_noEndData :
+ (void (GLAPIENTRY *)(void *)) fn;
+ return;
+ case GLU_TESS_ERROR:
+ tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn;
+ return;
+ case GLU_TESS_ERROR_DATA:
+ tess->callErrorData = (fn == NULL) ?
+ &__gl_noErrorData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
+ return;
+ case GLU_TESS_COMBINE:
+ tess->callCombine = (fn == NULL) ? &noCombine :
+ (void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn;
+ return;
+ case GLU_TESS_COMBINE_DATA:
+ tess->callCombineData = (fn == NULL) ? &__gl_noCombineData :
+ (void (GLAPIENTRY *)(GLdouble [3],
+ void *[4],
+ GLfloat [4],
+ void **,
+ void *)) fn;
+ return;
+ case GLU_TESS_MESH:
+ tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn;
+ return;
+ default:
+ CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
+ return;
+ }
+}
+
+static int AddVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
+{
+ GLUhalfEdge *e;
+
+ e = tess->lastEdge;
+ if( e == NULL ) {
+ /* Make a self-loop (one vertex, one edge). */
+
+ e = __gl_meshMakeEdge( tess->mesh );
+ if (e == NULL) return 0;
+ if ( !__gl_meshSplice( e, e->Sym ) ) return 0;
+ } else {
+ /* Create a new vertex and edge which immediately follow e
+ * in the ordering around the left face.
+ */
+ if (__gl_meshSplitEdge( e ) == NULL) return 0;
+ e = e->Lnext;
+ }
+
+ /* The new vertex is now e->Org. */
+ e->Org->data = data;
+ e->Org->coords[0] = coords[0];
+ e->Org->coords[1] = coords[1];
+ e->Org->coords[2] = coords[2];
+
+ /* The winding of an edge says how the winding number changes as we
+ * cross from the edge''s right face to its left face. We add the
+ * vertices in such an order that a CCW contour will add +1 to
+ * the winding number of the region inside the contour.
+ */
+ e->winding = 1;
+ e->Sym->winding = -1;
+
+ tess->lastEdge = e;
+
+ return 1;
+}
+
+
+static void CacheVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
+{
+ CachedVertex *v = &tess->cache[tess->cacheCount];
+
+ v->data = data;
+ v->coords[0] = coords[0];
+ v->coords[1] = coords[1];
+ v->coords[2] = coords[2];
+ ++tess->cacheCount;
+}
+
+
+static int EmptyCache( GLUtesselator *tess )
+{
+ CachedVertex *v = tess->cache;
+ CachedVertex *vLast;
+
+ tess->mesh = __gl_meshNewMesh();
+ if (tess->mesh == NULL) return 0;
+
+ for( vLast = v + tess->cacheCount; v < vLast; ++v ) {
+ if ( !AddVertex( tess, v->coords, v->data ) ) return 0;
+ }
+ tess->cacheCount = 0;
+ tess->emptyCache = FALSE;
+
+ return 1;
+}
+
+
+void GLAPIENTRY
+internal_gluTessVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
+{
+ int i, tooLarge = FALSE;
+ GLdouble x, clamped[3];
+
+ RequireState( tess, T_IN_CONTOUR );
+
+ if( tess->emptyCache ) {
+ if ( !EmptyCache( tess ) ) {
+ CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
+ return;
+ }
+ tess->lastEdge = NULL;
+ }
+ for( i = 0; i < 3; ++i ) {
+ x = coords[i];
+ if( x < - GLU_TESS_MAX_COORD ) {
+ x = - GLU_TESS_MAX_COORD;
+ tooLarge = TRUE;
+ }
+ if( x > GLU_TESS_MAX_COORD ) {
+ x = GLU_TESS_MAX_COORD;
+ tooLarge = TRUE;
+ }
+ clamped[i] = x;
+ }
+ if( tooLarge ) {
+ CALL_ERROR_OR_ERROR_DATA( GLU_TESS_COORD_TOO_LARGE );
+ }
+
+ if( tess->mesh == NULL ) {
+ if( tess->cacheCount < TESS_MAX_CACHE ) {
+ CacheVertex( tess, clamped, data );
+ return;
+ }
+ if ( !EmptyCache( tess ) ) {
+ CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
+ return;
+ }
+ }
+ if ( !AddVertex( tess, clamped, data ) ) {
+ CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
+ }
+}
+
+
+void GLAPIENTRY
+internal_gluTessBeginPolygon( GLUtesselator *tess, void *data )
+{
+ RequireState( tess, T_DORMANT );
+
+ tess->state = T_IN_POLYGON;
+ tess->cacheCount = 0;
+ tess->emptyCache = FALSE;
+ tess->mesh = NULL;
+
+ tess->polygonData= data;
+}
+
+
+void GLAPIENTRY
+internal_gluTessBeginContour( GLUtesselator *tess )
+{
+ RequireState( tess, T_IN_POLYGON );
+
+ tess->state = T_IN_CONTOUR;
+ tess->lastEdge = NULL;
+ if( tess->cacheCount > 0 ) {
+ /* Just set a flag so we don't get confused by empty contours
+ * -- these can be generated accidentally with the obsolete
+ * NextContour() interface.
+ */
+ tess->emptyCache = TRUE;
+ }
+}
+
+
+void GLAPIENTRY
+internal_gluTessEndContour( GLUtesselator *tess )
+{
+ RequireState( tess, T_IN_CONTOUR );
+ tess->state = T_IN_POLYGON;
+}
+
+void GLAPIENTRY
+internal_gluTessEndPolygon( GLUtesselator *tess )
+{
+ GLUmesh *mesh;
+
+ if (setjmp(tess->env) != 0) {
+ /* come back here if out of memory */
+ CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
+ return;
+ }
+
+ RequireState( tess, T_IN_POLYGON );
+ tess->state = T_DORMANT;
+
+ if( tess->mesh == NULL ) {
+ if( ! tess->flagBoundary && tess->callMesh == &noMesh ) {
+
+ /* Try some special code to make the easy cases go quickly
+ * (eg. convex polygons). This code does NOT handle multiple contours,
+ * intersections, edge flags, and of course it does not generate
+ * an explicit mesh either.
+ */
+ if( __gl_renderCache( tess )) {
+ tess->polygonData= NULL;
+ return;
+ }
+ }
+ if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/
+ }
+
+ /* Determine the polygon normal and project vertices onto the plane
+ * of the polygon.
+ */
+ __gl_projectPolygon( tess );
+
+ /* __gl_computeInterior( tess ) computes the planar arrangement specified
+ * by the given contours, and further subdivides this arrangement
+ * into regions. Each region is marked "inside" if it belongs
+ * to the polygon, according to the rule given by tess->windingRule.
+ * Each interior region is guaranteed be monotone.
+ */
+ if ( !__gl_computeInterior( tess ) ) {
+ longjmp(tess->env,1); /* could've used a label */
+ }
+
+ mesh = tess->mesh;
+ if( ! tess->fatalError ) {
+ int rc = 1;
+
+ /* If the user wants only the boundary contours, we throw away all edges
+ * except those which separate the interior from the exterior.
+ * Otherwise we tessellate all the regions marked "inside".
+ */
+ if( tess->boundaryOnly ) {
+ rc = __gl_meshSetWindingNumber( mesh, 1, TRUE );
+ } else {
+ rc = __gl_meshTessellateInterior( mesh );
+ }
+ if (rc == 0) longjmp(tess->env,1); /* could've used a label */
+
+ __gl_meshCheckMesh( mesh );
+
+ if( tess->callBegin != &noBegin || tess->callEnd != &noEnd
+ || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag
+ || tess->callBeginData != &__gl_noBeginData
+ || tess->callEndData != &__gl_noEndData
+ || tess->callVertexData != &__gl_noVertexData
+ || tess->callEdgeFlagData != &__gl_noEdgeFlagData )
+ {
+ if( tess->boundaryOnly ) {
+ __gl_renderBoundary( tess, mesh ); /* output boundary contours */
+ } else {
+ __gl_renderMesh( tess, mesh ); /* output strips and fans */
+ }
+ }
+ if( tess->callMesh != &noMesh ) {
+
+ /* Throw away the exterior faces, so that all faces are interior.
+ * This way the user doesn't have to check the "inside" flag,
+ * and we don't need to even reveal its existence. It also leaves
+ * the freedom for an implementation to not generate the exterior
+ * faces in the first place.
+ */
+ __gl_meshDiscardExterior( mesh );
+ (*tess->callMesh)( mesh ); /* user wants the mesh itself */
+ tess->mesh = NULL;
+ tess->polygonData= NULL;
+ return;
+ }
+ }
+ __gl_meshDeleteMesh( mesh );
+ tess->polygonData= NULL;
+ tess->mesh = NULL;
+}
+
+
+/*XXXblythe unused function*/
+#if 0
+void GLAPIENTRY
+gluDeleteMesh( GLUmesh *mesh )
+{
+ __gl_meshDeleteMesh( mesh );
+}
+#endif
+
+
+
+/*******************************************************/
+
+/* Obsolete calls -- for backward compatibility */
+
+#if 0
+void GLAPIENTRY
+gluBeginPolygon( GLUtesselator *tess )
+{
+ gluTessBeginPolygon( tess, NULL );
+ gluTessBeginContour( tess );
+}
+
+
+/*ARGSUSED*/
+void GLAPIENTRY
+gluNextContour( GLUtesselator *tess, GLenum type )
+{
+ gluTessEndContour( tess );
+ gluTessBeginContour( tess );
+}
+
+
+void GLAPIENTRY
+gluEndPolygon( GLUtesselator *tess )
+{
+ gluTessEndContour( tess );
+ gluTessEndPolygon( tess );
+}
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/tess.h b/WebCore/thirdparty/glu/libtess/tess.h
new file mode 100644
index 0000000..8215223
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/tess.h
@@ -0,0 +1,173 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/tess.h#6 $
+*/
+
+#ifndef __tess_h_
+#define __tess_h_
+
+#include <setjmp.h>
+
+#include "thirdparty/glu/internal_glu.h"
+#include "thirdparty/glu/libtess/dict.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/priorityq.h"
+
+/* The begin/end calls must be properly nested. We keep track of
+ * the current state to enforce the ordering.
+ */
+enum TessState { T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR };
+
+/* We cache vertex data for single-contour polygons so that we can
+ * try a quick-and-dirty decomposition first.
+ */
+#define TESS_MAX_CACHE 100
+
+typedef struct CachedVertex {
+ GLdouble coords[3];
+ void *data;
+} CachedVertex;
+
+struct GLUtesselator {
+
+ /*** state needed for collecting the input data ***/
+
+ enum TessState state; /* what begin/end calls have we seen? */
+
+ GLUhalfEdge *lastEdge; /* lastEdge->Org is the most recent vertex */
+ GLUmesh *mesh; /* stores the input contours, and eventually
+ the tessellation itself */
+
+ void (GLAPIENTRY *callError)( GLenum errnum );
+
+ /*** state needed for projecting onto the sweep plane ***/
+
+ GLdouble normal[3]; /* user-specified normal (if provided) */
+ GLdouble sUnit[3]; /* unit vector in s-direction (debugging) */
+ GLdouble tUnit[3]; /* unit vector in t-direction (debugging) */
+
+ /*** state needed for the line sweep ***/
+
+ GLdouble relTolerance; /* tolerance for merging features */
+ GLenum windingRule; /* rule for determining polygon interior */
+ GLboolean fatalError; /* fatal error: needed combine callback */
+
+ Dict *dict; /* edge dictionary for sweep line */
+ PriorityQ *pq; /* priority queue of vertex events */
+ GLUvertex *event; /* current sweep event being processed */
+
+ void (GLAPIENTRY *callCombine)( GLdouble coords[3], void *data[4],
+ GLfloat weight[4], void **outData );
+
+ /*** state needed for rendering callbacks (see render.c) ***/
+
+ GLboolean flagBoundary; /* mark boundary edges (use EdgeFlag) */
+ GLboolean boundaryOnly; /* Extract contours, not triangles */
+ GLUface *lonelyTriList;
+ /* list of triangles which could not be rendered as strips or fans */
+
+ void (GLAPIENTRY *callBegin)( GLenum type );
+ void (GLAPIENTRY *callEdgeFlag)( GLboolean boundaryEdge );
+ void (GLAPIENTRY *callVertex)( void *data );
+ void (GLAPIENTRY *callEnd)( void );
+ void (GLAPIENTRY *callMesh)( GLUmesh *mesh );
+
+
+ /*** state needed to cache single-contour polygons for renderCache() */
+
+ GLboolean emptyCache; /* empty cache on next vertex() call */
+ int cacheCount; /* number of cached vertices */
+ CachedVertex cache[TESS_MAX_CACHE]; /* the vertex data */
+
+ /*** rendering callbacks that also pass polygon data ***/
+ void (GLAPIENTRY *callBeginData)( GLenum type, void *polygonData );
+ void (GLAPIENTRY *callEdgeFlagData)( GLboolean boundaryEdge,
+ void *polygonData );
+ void (GLAPIENTRY *callVertexData)( void *data, void *polygonData );
+ void (GLAPIENTRY *callEndData)( void *polygonData );
+ void (GLAPIENTRY *callErrorData)( GLenum errnum, void *polygonData );
+ void (GLAPIENTRY *callCombineData)( GLdouble coords[3], void *data[4],
+ GLfloat weight[4], void **outData,
+ void *polygonData );
+
+ jmp_buf env; /* place to jump to when memAllocs fail */
+
+ void *polygonData; /* client data for current polygon */
+};
+
+void GLAPIENTRY __gl_noBeginData( GLenum type, void *polygonData );
+void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, void *polygonData );
+void GLAPIENTRY __gl_noVertexData( void *data, void *polygonData );
+void GLAPIENTRY __gl_noEndData( void *polygonData );
+void GLAPIENTRY __gl_noErrorData( GLenum errnum, void *polygonData );
+void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], void *data[4],
+ GLfloat weight[4], void **outData,
+ void *polygonData );
+
+#define CALL_BEGIN_OR_BEGIN_DATA(a) \
+ if (tess->callBeginData != &__gl_noBeginData) \
+ (*tess->callBeginData)((a),tess->polygonData); \
+ else (*tess->callBegin)((a));
+
+#define CALL_VERTEX_OR_VERTEX_DATA(a) \
+ if (tess->callVertexData != &__gl_noVertexData) \
+ (*tess->callVertexData)((a),tess->polygonData); \
+ else (*tess->callVertex)((a));
+
+#define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \
+ if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \
+ (*tess->callEdgeFlagData)((a),tess->polygonData); \
+ else (*tess->callEdgeFlag)((a));
+
+#define CALL_END_OR_END_DATA() \
+ if (tess->callEndData != &__gl_noEndData) \
+ (*tess->callEndData)(tess->polygonData); \
+ else (*tess->callEnd)();
+
+#define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \
+ if (tess->callCombineData != &__gl_noCombineData) \
+ (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \
+ else (*tess->callCombine)((a),(b),(c),(d));
+
+#define CALL_ERROR_OR_ERROR_DATA(a) \
+ if (tess->callErrorData != &__gl_noErrorData) \
+ (*tess->callErrorData)((a),tess->polygonData); \
+ else (*tess->callError)((a));
+
+#endif
diff --git a/WebCore/thirdparty/glu/libtess/tessmono.c b/WebCore/thirdparty/glu/libtess/tessmono.c
new file mode 100644
index 0000000..3aaaaa1
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/tessmono.c
@@ -0,0 +1,209 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/tessmono.c#5 $
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "thirdparty/glu/gluos.h"
+#include "thirdparty/glu/libtess/geom.h"
+#include "thirdparty/glu/libtess/mesh.h"
+#include "thirdparty/glu/libtess/tessmono.h"
+
+#define AddWinding(eDst,eSrc) (eDst->winding += eSrc->winding, \
+ eDst->Sym->winding += eSrc->Sym->winding)
+
+/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
+ * (what else would it do??) The region must consist of a single
+ * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this
+ * case means that any vertical line intersects the interior of the
+ * region in a single interval.
+ *
+ * Tessellation consists of adding interior edges (actually pairs of
+ * half-edges), to split the region into non-overlapping triangles.
+ *
+ * The basic idea is explained in Preparata and Shamos (which I don''t
+ * have handy right now), although their implementation is more
+ * complicated than this one. The are two edge chains, an upper chain
+ * and a lower chain. We process all vertices from both chains in order,
+ * from right to left.
+ *
+ * The algorithm ensures that the following invariant holds after each
+ * vertex is processed: the untessellated region consists of two
+ * chains, where one chain (say the upper) is a single edge, and
+ * the other chain is concave. The left vertex of the single edge
+ * is always to the left of all vertices in the concave chain.
+ *
+ * Each step consists of adding the rightmost unprocessed vertex to one
+ * of the two chains, and forming a fan of triangles from the rightmost
+ * of two chain endpoints. Determining whether we can add each triangle
+ * to the fan is a simple orientation test. By making the fan as large
+ * as possible, we restore the invariant (check it yourself).
+ */
+int __gl_meshTessellateMonoRegion( GLUface *face )
+{
+ GLUhalfEdge *up, *lo;
+
+ /* All edges are oriented CCW around the boundary of the region.
+ * First, find the half-edge whose origin vertex is rightmost.
+ * Since the sweep goes from left to right, face->anEdge should
+ * be close to the edge we want.
+ */
+ up = face->anEdge;
+ assert( up->Lnext != up && up->Lnext->Lnext != up );
+
+ for( ; VertLeq( up->Dst, up->Org ); up = up->Lprev )
+ ;
+ for( ; VertLeq( up->Org, up->Dst ); up = up->Lnext )
+ ;
+ lo = up->Lprev;
+
+ while( up->Lnext != lo ) {
+ if( VertLeq( up->Dst, lo->Org )) {
+ /* up->Dst is on the left. It is safe to form triangles from lo->Org.
+ * The EdgeGoesLeft test guarantees progress even when some triangles
+ * are CW, given that the upper and lower chains are truly monotone.
+ */
+ while( lo->Lnext != up && (EdgeGoesLeft( lo->Lnext )
+ || EdgeSign( lo->Org, lo->Dst, lo->Lnext->Dst ) <= 0 )) {
+ GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
+ if (tempHalfEdge == NULL) return 0;
+ lo = tempHalfEdge->Sym;
+ }
+ lo = lo->Lprev;
+ } else {
+ /* lo->Org is on the left. We can make CCW triangles from up->Dst. */
+ while( lo->Lnext != up && (EdgeGoesRight( up->Lprev )
+ || EdgeSign( up->Dst, up->Org, up->Lprev->Org ) >= 0 )) {
+ GLUhalfEdge *tempHalfEdge= __gl_meshConnect( up, up->Lprev );
+ if (tempHalfEdge == NULL) return 0;
+ up = tempHalfEdge->Sym;
+ }
+ up = up->Lnext;
+ }
+ }
+
+ /* Now lo->Org == up->Dst == the leftmost vertex. The remaining region
+ * can be tessellated in a fan from this leftmost vertex.
+ */
+ assert( lo->Lnext != up );
+ while( lo->Lnext->Lnext != up ) {
+ GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
+ if (tempHalfEdge == NULL) return 0;
+ lo = tempHalfEdge->Sym;
+ }
+
+ return 1;
+}
+
+
+/* __gl_meshTessellateInterior( mesh ) tessellates each region of
+ * the mesh which is marked "inside" the polygon. Each such region
+ * must be monotone.
+ */
+int __gl_meshTessellateInterior( GLUmesh *mesh )
+{
+ GLUface *f, *next;
+
+ /*LINTED*/
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
+ /* Make sure we don''t try to tessellate the new triangles. */
+ next = f->next;
+ if( f->inside ) {
+ if ( !__gl_meshTessellateMonoRegion( f ) ) return 0;
+ }
+ }
+
+ return 1;
+}
+
+
+/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
+ * which are not marked "inside" the polygon. Since further mesh operations
+ * on NULL faces are not allowed, the main purpose is to clean up the
+ * mesh so that exterior loops are not represented in the data structure.
+ */
+void __gl_meshDiscardExterior( GLUmesh *mesh )
+{
+ GLUface *f, *next;
+
+ /*LINTED*/
+ for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
+ /* Since f will be destroyed, save its next pointer. */
+ next = f->next;
+ if( ! f->inside ) {
+ __gl_meshZapFace( f );
+ }
+ }
+}
+
+#define MARKED_FOR_DELETION 0x7fffffff
+
+/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
+ * winding numbers on all edges so that regions marked "inside" the
+ * polygon have a winding number of "value", and regions outside
+ * have a winding number of 0.
+ *
+ * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
+ * separate an interior region from an exterior one.
+ */
+int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
+ GLboolean keepOnlyBoundary )
+{
+ GLUhalfEdge *e, *eNext;
+
+ for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
+ eNext = e->next;
+ if( e->Rface->inside != e->Lface->inside ) {
+
+ /* This is a boundary edge (one side is interior, one is exterior). */
+ e->winding = (e->Lface->inside) ? value : -value;
+ } else {
+
+ /* Both regions are interior, or both are exterior. */
+ if( ! keepOnlyBoundary ) {
+ e->winding = 0;
+ } else {
+ if ( !__gl_meshDelete( e ) ) return 0;
+ }
+ }
+ }
+ return 1;
+}
diff --git a/WebCore/thirdparty/glu/libtess/tessmono.h b/WebCore/thirdparty/glu/libtess/tessmono.h
new file mode 100644
index 0000000..6a71ee8
--- /dev/null
+++ b/WebCore/thirdparty/glu/libtess/tessmono.h
@@ -0,0 +1,78 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+/*
+** Author: Eric Veach, July 1994.
+**
+** $Date$ $Revision$
+** $Header: //depot/main/gfx/lib/glu/libtess/tessmono.h#5 $
+*/
+
+#ifndef __tessmono_h_
+#define __tessmono_h_
+
+/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
+ * (what else would it do??) The region must consist of a single
+ * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this
+ * case means that any vertical line intersects the interior of the
+ * region in a single interval.
+ *
+ * Tessellation consists of adding interior edges (actually pairs of
+ * half-edges), to split the region into non-overlapping triangles.
+ *
+ * __gl_meshTessellateInterior( mesh ) tessellates each region of
+ * the mesh which is marked "inside" the polygon. Each such region
+ * must be monotone.
+ *
+ * __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
+ * which are not marked "inside" the polygon. Since further mesh operations
+ * on NULL faces are not allowed, the main purpose is to clean up the
+ * mesh so that exterior loops are not represented in the data structure.
+ *
+ * __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
+ * winding numbers on all edges so that regions marked "inside" the
+ * polygon have a winding number of "value", and regions outside
+ * have a winding number of 0.
+ *
+ * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
+ * separate an interior region from an exterior one.
+ */
+
+int __gl_meshTessellateMonoRegion( GLUface *face );
+int __gl_meshTessellateInterior( GLUmesh *mesh );
+void __gl_meshDiscardExterior( GLUmesh *mesh );
+int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
+ GLboolean keepOnlyBoundary );
+
+#endif
diff --git a/WebCore/webaudio/AudioBuffer.cpp b/WebCore/webaudio/AudioBuffer.cpp
new file mode 100644
index 0000000..f46d153
--- /dev/null
+++ b/WebCore/webaudio/AudioBuffer.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO) & ENABLE(3D_CANVAS)
+
+#include "AudioBuffer.h"
+
+#include "AudioBus.h"
+#include "AudioFileReader.h"
+#include "ExceptionCode.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate)
+{
+ return adoptRef(new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate));
+}
+
+PassRefPtr<AudioBuffer> AudioBuffer::createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, double sampleRate)
+{
+ OwnPtr<AudioBus> bus = createBusFromInMemoryAudioFile(data, dataSize, mixToMono, sampleRate);
+ if (bus.get())
+ return adoptRef(new AudioBuffer(bus.get()));
+
+ return 0;
+}
+
+AudioBuffer::AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate)
+ : m_gain(1.0)
+ , m_sampleRate(sampleRate)
+ , m_length(numberOfFrames)
+{
+ m_channels.reserveCapacity(numberOfChannels);
+
+ for (unsigned i = 0; i < numberOfChannels; ++i) {
+ RefPtr<Float32Array> channelDataArray = Float32Array::create(m_length);
+ m_channels.append(channelDataArray);
+ }
+}
+
+AudioBuffer::AudioBuffer(AudioBus* bus)
+ : m_gain(1.0)
+ , m_sampleRate(bus->sampleRate())
+ , m_length(bus->length())
+{
+ // Copy audio data from the bus to the Float32Arrays we manage.
+ unsigned numberOfChannels = bus->numberOfChannels();
+ m_channels.reserveCapacity(numberOfChannels);
+ for (unsigned i = 0; i < numberOfChannels; ++i) {
+ RefPtr<Float32Array> channelDataArray = Float32Array::create(m_length);
+ ExceptionCode ec;
+ channelDataArray->setRange(bus->channel(i)->data(), m_length, 0, ec);
+ m_channels.append(channelDataArray);
+ }
+}
+
+void AudioBuffer::releaseMemory()
+{
+ m_channels.clear();
+}
+
+Float32Array* AudioBuffer::getChannelData(unsigned channelIndex)
+{
+ if (channelIndex >= m_channels.size())
+ return 0;
+
+ return m_channels[channelIndex].get();
+}
+
+void AudioBuffer::zero()
+{
+ for (unsigned i = 0; i < m_channels.size(); ++i) {
+ if (getChannelData(i)) {
+ ExceptionCode ec;
+ getChannelData(i)->zeroRange(0, length(), ec);
+ }
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO) & ENABLE(3D_CANVAS)
diff --git a/WebCore/webaudio/AudioBuffer.h b/WebCore/webaudio/AudioBuffer.h
new file mode 100644
index 0000000..b11a20e
--- /dev/null
+++ b/WebCore/webaudio/AudioBuffer.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioBuffer_h
+#define AudioBuffer_h
+
+#include "Float32Array.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioBus;
+
+class AudioBuffer : public RefCounted<AudioBuffer> {
+public:
+ static PassRefPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate);
+
+ // Returns 0 if data is not a valid audio file.
+ static PassRefPtr<AudioBuffer> createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, double sampleRate);
+
+ // Format
+ size_t length() const { return m_length; }
+ double duration() const { return length() / sampleRate(); }
+ double sampleRate() const { return m_sampleRate; }
+
+ // Channel data access
+ unsigned numberOfChannels() const { return m_channels.size(); }
+ Float32Array* getChannelData(unsigned channelIndex);
+ void zero();
+
+ // Scalar gain
+ double gain() const { return m_gain; }
+ void setGain(double gain) { m_gain = gain; }
+
+ // Because an AudioBuffer has a JavaScript wrapper, which will be garbage collected, it may take awhile for this object to be deleted.
+ // releaseMemory() can be called when the AudioContext goes away, so we can release the memory earlier than when the garbage collection happens.
+ // Careful! Only call this when the page unloads, after the AudioContext is no longer processing.
+ void releaseMemory();
+
+protected:
+ AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate);
+ AudioBuffer(AudioBus* bus);
+
+ double m_gain; // scalar gain
+ double m_sampleRate;
+ size_t m_length;
+
+ Vector<RefPtr<Float32Array> > m_channels;
+};
+
+} // namespace WebCore
+
+#endif // AudioBuffer_h
diff --git a/WebCore/webaudio/AudioBuffer.idl b/WebCore/webaudio/AudioBuffer.idl
new file mode 100644
index 0000000..e7353bf
--- /dev/null
+++ b/WebCore/webaudio/AudioBuffer.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module audio {
+ interface [
+ Conditional=WEB_AUDIO & 3D_CANVAS
+ ] AudioBuffer {
+ readonly attribute long length; // in sample-frames
+ readonly attribute float duration; // in seconds
+ readonly attribute float sampleRate; // in sample-frames per second
+
+ attribute float gain; // linear gain (default 1.0)
+
+ // Channel access
+ readonly attribute unsigned long numberOfChannels;
+ Float32Array getChannelData(in unsigned long channelIndex);
+ };
+}
diff --git a/WebCore/webaudio/AudioListener.cpp b/WebCore/webaudio/AudioListener.cpp
new file mode 100644
index 0000000..44fb02c
--- /dev/null
+++ b/WebCore/webaudio/AudioListener.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "AudioListener.h"
+
+#include "AudioBus.h"
+
+namespace WebCore {
+
+AudioListener::AudioListener()
+ : m_position(0, 0, 0)
+ , m_orientation(0.0, 0.0, -1.0)
+ , m_upVector(0.0, 1.0, 0.0)
+ , m_velocity(0, 0, 0)
+ , m_dopplerFactor(1.0)
+ , m_speedOfSound(343.3)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/webaudio/AudioListener.h b/WebCore/webaudio/AudioListener.h
new file mode 100644
index 0000000..2ac1520
--- /dev/null
+++ b/WebCore/webaudio/AudioListener.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioListener_h
+#define AudioListener_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector3.h>
+
+namespace WebCore {
+
+// AudioListener maintains the state of the listener in the audio scene as defined in the OpenAL specification.
+
+class AudioListener : public RefCounted<AudioListener> {
+public:
+ static PassRefPtr<AudioListener> create()
+ {
+ return adoptRef(new AudioListener());
+ }
+
+ // Position
+ void setPosition(double x, double y, double z) { setPosition(Vector3(x, y, z)); }
+ void setPosition(const Vector3 &position) { m_position = position; }
+ const Vector3& position() const { return m_position; }
+
+ // Orientation
+ void setOrientation(double x, double y, double z, double upX, double upY, double upZ)
+ {
+ setOrientation(Vector3(x, y, z));
+ setUpVector(Vector3(upX, upY, upZ));
+ }
+ void setOrientation(const Vector3 &orientation) { m_orientation = orientation; }
+ const Vector3& orientation() const { return m_orientation; }
+
+ // Up-vector
+ void setUpVector(const Vector3 &upVector) { m_upVector = upVector; }
+ const Vector3& upVector() const { return m_upVector; }
+
+ // Velocity
+ void setVelocity(double x, double y, double z) { setVelocity(Vector3(x, y, z)); }
+ void setVelocity(const Vector3 &velocity) { m_velocity = velocity; }
+ const Vector3& velocity() const { return m_velocity; }
+
+ // Doppler factor
+ void setDopplerFactor(double dopplerFactor) { m_dopplerFactor = dopplerFactor; }
+ double dopplerFactor() const { return m_dopplerFactor; }
+
+ // Speed of sound
+ void setSpeedOfSound(double speedOfSound) { m_speedOfSound = speedOfSound; }
+ double speedOfSound() const { return m_speedOfSound; }
+
+private:
+ AudioListener();
+
+ // Position / Orientation
+ Vector3 m_position;
+ Vector3 m_orientation;
+ Vector3 m_upVector;
+
+ Vector3 m_velocity;
+
+ double m_dopplerFactor;
+ double m_speedOfSound;
+};
+
+} // WebCore
+
+#endif // AudioListener_h
diff --git a/WebCore/webaudio/AudioListener.idl b/WebCore/webaudio/AudioListener.idl
new file mode 100644
index 0000000..cf6d8cf
--- /dev/null
+++ b/WebCore/webaudio/AudioListener.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module audio {
+ interface [
+ Conditional=WEB_AUDIO
+ ] AudioListener {
+ attribute float dopplerFactor; // same as OpenAL (default 1.0)
+ attribute float speedOfSound; // in meters / second (default 343.3)
+
+ void setPosition(in float x, in float y, in float z);
+ void setOrientation(in float x, in float y, in float z, in float xUp, in float yUp, in float zUp);
+ void setVelocity(in float x, in float y, in float z);
+ };
+}
diff --git a/WebCore/webaudio/AudioParam.h b/WebCore/webaudio/AudioParam.h
new file mode 100644
index 0000000..2fbd805
--- /dev/null
+++ b/WebCore/webaudio/AudioParam.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioParam_h
+#define AudioParam_h
+
+#include "PlatformString.h"
+#include <math.h>
+#include <sys/types.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class AudioParam : public RefCounted<AudioParam> {
+public:
+ static const double DefaultSmoothingConstant = 0.05;
+ static const double SnapThreshold = 0.001;
+
+ static PassRefPtr<AudioParam> create(const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0)
+ {
+ return adoptRef(new AudioParam(name, defaultValue, minValue, maxValue, units));
+ }
+
+ AudioParam(const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0)
+ : m_name(name)
+ , m_value(defaultValue)
+ , m_defaultValue(defaultValue)
+ , m_minValue(minValue)
+ , m_maxValue(maxValue)
+ , m_units(units)
+ , m_smoothedValue(defaultValue)
+ , m_smoothingConstant(DefaultSmoothingConstant)
+ {
+ }
+
+ float value() const { return static_cast<float>(m_value); }
+ void setValue(float value) { m_value = value; }
+
+ String name() const { return m_name; }
+
+ float minValue() const { return static_cast<float>(m_minValue); }
+ float maxValue() const { return static_cast<float>(m_maxValue); }
+ float defaultValue() const { return static_cast<float>(m_defaultValue); }
+ unsigned units() const { return m_units; }
+
+ // Value smoothing:
+
+ // When a new value is set with setValue(), in our internal use of the parameter we don't immediately jump to it.
+ // Instead we smoothly approach this value to avoid glitching.
+ float smoothedValue() const { return static_cast<float>(m_smoothedValue); }
+
+ // Smoothly exponentially approaches to (de-zippers) the desired value.
+ // Returns true if smoothed value has already snapped exactly to value.
+ bool smooth()
+ {
+ if (m_smoothedValue == m_value) {
+ // Smoothed value has already approached and snapped to value.
+ return true;
+ }
+
+ // Exponential approach
+ m_smoothedValue += (m_value - m_smoothedValue) * m_smoothingConstant;
+
+ // If we get close enough then snap to actual value.
+ if (fabs(m_smoothedValue - m_value) < SnapThreshold) // FIXME: the threshold needs to be adjustable depending on range - but this is OK general purpose value.
+ m_smoothedValue = m_value;
+
+ return false;
+ }
+
+ void resetSmoothedValue() { m_smoothedValue = m_value; }
+ void setSmoothingConstant(double k) { m_smoothingConstant = k; }
+
+private:
+ String m_name;
+ double m_value;
+ double m_defaultValue;
+ double m_minValue;
+ double m_maxValue;
+ unsigned m_units;
+
+ // Smoothing (de-zippering)
+ double m_smoothedValue;
+ double m_smoothingConstant;
+};
+
+} // namespace WebCore
+
+#endif // AudioParam_h
diff --git a/WebCore/webaudio/AudioParam.idl b/WebCore/webaudio/AudioParam.idl
new file mode 100644
index 0000000..ff2598e
--- /dev/null
+++ b/WebCore/webaudio/AudioParam.idl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module webaudio {
+ interface [
+ Conditional=WEB_AUDIO
+ ] AudioParam {
+ attribute float value;
+ readonly attribute float minValue;
+ readonly attribute float maxValue;
+ readonly attribute float defaultValue;
+
+ readonly attribute DOMString name;
+
+ // FIXME: Could define units constants here (seconds, decibels, cents, etc.)...
+ readonly attribute unsigned short units;
+ };
+}
diff --git a/WebCore/webaudio/AudioSourceNode.h b/WebCore/webaudio/AudioSourceNode.h
new file mode 100644
index 0000000..6091371
--- /dev/null
+++ b/WebCore/webaudio/AudioSourceNode.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioSourceNode_h
+#define AudioSourceNode_h
+
+#include "AudioNode.h"
+
+namespace WebCore {
+
+class AudioSourceNode : public AudioNode {
+public:
+ AudioSourceNode(AudioContext* context, double sampleRate)
+ : AudioNode(context, sampleRate)
+ {
+ }
+};
+
+} // namespace WebCore
+
+#endif // AudioSourceNode_h
diff --git a/WebCore/webaudio/AudioSourceNode.idl b/WebCore/webaudio/AudioSourceNode.idl
new file mode 100644
index 0000000..ec3c356
--- /dev/null
+++ b/WebCore/webaudio/AudioSourceNode.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module audio {
+ interface [
+ Conditional=WEB_AUDIO
+ ] AudioSourceNode : AudioNode {
+ };
+}
diff --git a/WebCore/websockets/WebSocketChannel.cpp b/WebCore/websockets/WebSocketChannel.cpp
index 54be16a..a09224d 100644
--- a/WebCore/websockets/WebSocketChannel.cpp
+++ b/WebCore/websockets/WebSocketChannel.cpp
@@ -88,7 +88,8 @@ bool WebSocketChannel::send(const String& msg)
ASSERT(!m_suspended);
Vector<char> buf;
buf.append('\0'); // frame type
- buf.append(msg.utf8().data(), msg.utf8().length());
+ CString utf8 = msg.utf8();
+ buf.append(utf8.data(), utf8.length());
buf.append('\xff'); // frame end
return m_handle->send(buf.data(), buf.size());
}
diff --git a/WebCore/wml/WMLDocument.h b/WebCore/wml/WMLDocument.h
index f2be938..3057d9b 100644
--- a/WebCore/wml/WMLDocument.h
+++ b/WebCore/wml/WMLDocument.h
@@ -34,7 +34,7 @@ class WMLDocument : public Document {
public:
static PassRefPtr<WMLDocument> create(Frame* frame, const KURL& url)
{
- return adoptRef(adoptRef(new WMLDocument(frame, url))));
+ return adoptRef(new WMLDocument(frame, url));
}
virtual ~WMLDocument();
diff --git a/WebCore/wml/WMLFormControlElement.h b/WebCore/wml/WMLFormControlElement.h
index 43f8dee..674303b 100644
--- a/WebCore/wml/WMLFormControlElement.h
+++ b/WebCore/wml/WMLFormControlElement.h
@@ -28,7 +28,9 @@ namespace WebCore {
class WMLFormControlElement : public WMLElement {
public:
- WMLFormControlElement(const QualifiedName&, Document*);
+ static PassRefPtr<WMLFormControlElement> create(const QualifiedName&, Document*);
+
+
virtual ~WMLFormControlElement();
virtual bool isFormControlElement() const { return true; }
@@ -44,6 +46,9 @@ public:
virtual void attach();
virtual void recalcStyle(StyleChange);
+protected:
+ WMLFormControlElement(const QualifiedName&, Document*);
+
private:
bool m_valueMatchesRenderer;
};
diff --git a/WebCore/wml/WMLImageElement.cpp b/WebCore/wml/WMLImageElement.cpp
index c4f6b06..5e15ccb 100644
--- a/WebCore/wml/WMLImageElement.cpp
+++ b/WebCore/wml/WMLImageElement.cpp
@@ -101,9 +101,10 @@ void WMLImageElement::attach()
if (renderer() && renderer()->isImage() && m_imageLoader.haveFiredBeforeLoadEvent()) {
RenderImage* imageObj = toRenderImage(renderer());
- if (imageObj->hasImage())
+ RenderImageResource* renderImageResource = imageObj->imageResource();
+ if (renderImageResource->hasImage())
return;
- imageObj->setCachedImage(m_imageLoader.image());
+ renderImageResource->setCachedImage(m_imageLoader.image());
// If we have no image at all because we have no src attribute, set
// image height and width for the alt text instead.
diff --git a/WebCore/wml/WMLInputElement.h b/WebCore/wml/WMLInputElement.h
index 70d85e9..df7f497 100644
--- a/WebCore/wml/WMLInputElement.h
+++ b/WebCore/wml/WMLInputElement.h
@@ -82,6 +82,7 @@ public:
virtual void defaultEventHandler(Event*);
virtual void cacheSelection(int start, int end);
+ virtual bool isAcceptableValue(const String&) const { return true; }
virtual String sanitizeValue(const String& proposedValue) const { return constrainValue(proposedValue); }
virtual void documentDidBecomeActive();
diff --git a/WebCore/wml/WMLIntrinsicEvent.cpp b/WebCore/wml/WMLIntrinsicEvent.cpp
index ec5e987..bb631b9 100644
--- a/WebCore/wml/WMLIntrinsicEvent.cpp
+++ b/WebCore/wml/WMLIntrinsicEvent.cpp
@@ -43,11 +43,6 @@ WMLIntrinsicEvent::WMLIntrinsicEvent(Document* document, const String& targetURL
m_taskElement->setAttribute(HTMLNames::hrefAttr, targetURL);
}
-PassRefPtr<WMLIntrinsicEvent> WMLIntrinsicEvent::create(const QualifiedName& tagName, Document* document)
-{
- return adoptRef(new WMLIntrinsicEvent(tagName, document));
-}
-
WMLIntrinsicEvent::WMLIntrinsicEvent(WMLTaskElement* taskElement)
: m_taskElement(taskElement)
{
diff --git a/WebCore/wml/WMLIntrinsicEvent.h b/WebCore/wml/WMLIntrinsicEvent.h
index 2a98bee..9a974fb 100644
--- a/WebCore/wml/WMLIntrinsicEvent.h
+++ b/WebCore/wml/WMLIntrinsicEvent.h
@@ -22,12 +22,12 @@
#define WMLIntrinsicEvent_h
#if ENABLE(WML)
+#include "WMLTaskElement.h"
+
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#include "WMLTaskElement.h"
-
namespace WebCore {
class Document;
diff --git a/WebCore/wml/WMLSelectElement.cpp b/WebCore/wml/WMLSelectElement.cpp
index 81c3a77..78749b3 100644
--- a/WebCore/wml/WMLSelectElement.cpp
+++ b/WebCore/wml/WMLSelectElement.cpp
@@ -114,8 +114,9 @@ void WMLSelectElement::setSelectedIndex(int optionIndex, bool deselect)
SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, false, false);
}
-void WMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow)
+void WMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow, bool allowMultipleSelection)
{
+ UNUSED_PARAM(allowMultipleSelection);
SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, fireOnChangeNow, true);
}
diff --git a/WebCore/wml/WMLSelectElement.h b/WebCore/wml/WMLSelectElement.h
index 00b4649..16bb382 100644
--- a/WebCore/wml/WMLSelectElement.h
+++ b/WebCore/wml/WMLSelectElement.h
@@ -51,7 +51,7 @@ public:
virtual int selectedIndex() const;
virtual void setSelectedIndex(int index, bool deselect = true);
- virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false);
+ virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false);
virtual int size() const { return m_data.size(); }
virtual bool multiple() const { return m_data.multiple(); }
diff --git a/WebCore/wml/WMLTaskElement.cpp b/WebCore/wml/WMLTaskElement.cpp
index 4ef3496..d49a03e 100644
--- a/WebCore/wml/WMLTaskElement.cpp
+++ b/WebCore/wml/WMLTaskElement.cpp
@@ -39,11 +39,6 @@ WMLTaskElement::WMLTaskElement(const QualifiedName& tagName, Document* doc)
{
}
-PassRefPtr<WMLTaskElement> WMLTaskElement::create(const QualifiedName& tagName, Document* document)
-{
- return adoptRef(new WMLTaskElement(tagName, document));
-}
-
WMLTaskElement::~WMLTaskElement()
{
}
diff --git a/WebCore/wml/WMLTaskElement.h b/WebCore/wml/WMLTaskElement.h
index b7c5376..91e2a32 100644
--- a/WebCore/wml/WMLTaskElement.h
+++ b/WebCore/wml/WMLTaskElement.h
@@ -33,11 +33,6 @@ class WMLSetvarElement;
class WMLTaskElement : public WMLElement {
public:
- static PassRefPtr<WMLTaskElement> create(const QualifiedName& tagName, Document*);
-
- WMLTaskElement(const QualifiedName& tagName, Document*);
- virtual ~WMLTaskElement();
-
virtual bool isWMLTaskElement() const { return true; }
virtual void insertedIntoDocument();
@@ -48,6 +43,9 @@ public:
void deregisterVariableSetter(WMLSetvarElement*);
protected:
+ WMLTaskElement(const QualifiedName& tagName, Document*);
+ virtual ~WMLTaskElement();
+
void storeVariableState(WMLPageState*);
private:
diff --git a/WebCore/workers/Worker.cpp b/WebCore/workers/Worker.cpp
index fda7c72..32ec997 100644
--- a/WebCore/workers/Worker.cpp
+++ b/WebCore/workers/Worker.cpp
@@ -32,7 +32,7 @@
#include "Worker.h"
#include "DOMWindow.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "EventException.h"
#include "EventListener.h"
diff --git a/WebCore/workers/WorkerMessagingProxy.cpp b/WebCore/workers/WorkerMessagingProxy.cpp
index 21994cc..10700c6 100644
--- a/WebCore/workers/WorkerMessagingProxy.cpp
+++ b/WebCore/workers/WorkerMessagingProxy.cpp
@@ -54,7 +54,7 @@ public:
private:
MessageWorkerContextTask(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
- : m_message(message->release())
+ : m_message(message)
, m_channels(channels)
{
}
@@ -82,7 +82,7 @@ public:
private:
MessageWorkerTask(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels, WorkerMessagingProxy* messagingProxy)
- : m_message(message->release())
+ : m_message(message)
, m_channels(channels)
, m_messagingProxy(messagingProxy)
{
diff --git a/WebCore/xml/XSLImportRule.cpp b/WebCore/xml/XSLImportRule.cpp
index 0908d75..c32da4e 100644
--- a/WebCore/xml/XSLImportRule.cpp
+++ b/WebCore/xml/XSLImportRule.cpp
@@ -25,7 +25,7 @@
#if ENABLE(XSLT)
#include "CachedXSLStyleSheet.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "XSLStyleSheet.h"
namespace WebCore {
@@ -77,13 +77,13 @@ bool XSLImportRule::isLoading()
void XSLImportRule::loadSheet()
{
- DocLoader* docLoader = 0;
+ CachedResourceLoader* cachedResourceLoader = 0;
StyleBase* root = this;
StyleBase* parent;
while ((parent = root->parent()))
root = parent;
if (root->isXSLStyleSheet())
- docLoader = static_cast<XSLStyleSheet*>(root)->docLoader();
+ cachedResourceLoader = static_cast<XSLStyleSheet*>(root)->cachedResourceLoader();
String absHref = m_strHref;
XSLStyleSheet* parentSheet = parentStyleSheet();
@@ -98,7 +98,7 @@ void XSLImportRule::loadSheet()
return;
}
- m_cachedSheet = docLoader->requestXSLStyleSheet(absHref);
+ m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet(absHref);
if (m_cachedSheet) {
m_cachedSheet->addClient(this);
diff --git a/WebCore/xml/XSLStyleSheet.h b/WebCore/xml/XSLStyleSheet.h
index e6e4063..acf5ea3 100644
--- a/WebCore/xml/XSLStyleSheet.h
+++ b/WebCore/xml/XSLStyleSheet.h
@@ -36,7 +36,7 @@
namespace WebCore {
-class DocLoader;
+class CachedResourceLoader;
class Document;
class XSLImportRule;
@@ -71,7 +71,7 @@ public:
void loadChildSheets();
void loadChildSheet(const String& href);
- DocLoader* docLoader();
+ CachedResourceLoader* cachedResourceLoader();
Document* ownerDocument() { return m_ownerDocument; }
void setParentStyleSheet(XSLStyleSheet* parent);
diff --git a/WebCore/xml/XSLStyleSheetLibxslt.cpp b/WebCore/xml/XSLStyleSheetLibxslt.cpp
index 10919ef..3fb9eb5 100644
--- a/WebCore/xml/XSLStyleSheetLibxslt.cpp
+++ b/WebCore/xml/XSLStyleSheetLibxslt.cpp
@@ -26,7 +26,7 @@
#include "Console.h"
#include "DOMWindow.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Document.h"
#include "Frame.h"
#include "Node.h"
@@ -128,11 +128,11 @@ void XSLStyleSheet::clearDocuments()
}
}
-DocLoader* XSLStyleSheet::docLoader()
+CachedResourceLoader* XSLStyleSheet::cachedResourceLoader()
{
if (!m_ownerDocument)
return 0;
- return m_ownerDocument->docLoader();
+ return m_ownerDocument->cachedResourceLoader();
}
bool XSLStyleSheet::parseString(const String& string, bool)
@@ -148,7 +148,7 @@ bool XSLStyleSheet::parseString(const String& string, bool)
if (Frame* frame = ownerDocument()->frame())
console = frame->domWindow()->console();
- XMLDocumentParserScope scope(docLoader(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console);
+ XMLDocumentParserScope scope(cachedResourceLoader(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console);
const char* buffer = reinterpret_cast<const char*>(string.characters());
int size = string.length() * sizeof(UChar);
diff --git a/WebCore/xml/XSLStyleSheetQt.cpp b/WebCore/xml/XSLStyleSheetQt.cpp
index cb55993..0523560 100644
--- a/WebCore/xml/XSLStyleSheetQt.cpp
+++ b/WebCore/xml/XSLStyleSheetQt.cpp
@@ -61,11 +61,11 @@ void XSLStyleSheet::clearDocuments()
notImplemented();
}
-DocLoader* XSLStyleSheet::docLoader()
+CachedResourceLoader* XSLStyleSheet::cachedResourceLoader()
{
if (!m_ownerDocument)
return 0;
- return m_ownerDocument->docLoader();
+ return m_ownerDocument->cachedResourceLoader();
}
bool XSLStyleSheet::parseString(const String& string, bool)
diff --git a/WebCore/xml/XSLTProcessor.cpp b/WebCore/xml/XSLTProcessor.cpp
index 41569d7..bdae0cd 100644
--- a/WebCore/xml/XSLTProcessor.cpp
+++ b/WebCore/xml/XSLTProcessor.cpp
@@ -27,7 +27,7 @@
#include "XSLTProcessor.h"
#include "DOMImplementation.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "DocumentFragment.h"
#include "Frame.h"
#include "FrameLoader.h"
diff --git a/WebCore/xml/XSLTProcessorLibxslt.cpp b/WebCore/xml/XSLTProcessorLibxslt.cpp
index ed4303d..c2869c7 100644
--- a/WebCore/xml/XSLTProcessorLibxslt.cpp
+++ b/WebCore/xml/XSLTProcessorLibxslt.cpp
@@ -28,7 +28,7 @@
#include "Console.h"
#include "DOMWindow.h"
-#include "DocLoader.h"
+#include "CachedResourceLoader.h"
#include "Frame.h"
#include "ResourceError.h"
#include "ResourceHandle.h"
@@ -96,12 +96,12 @@ void XSLTProcessor::parseErrorFunc(void* userData, xmlError* error)
// FIXME: There seems to be no way to control the ctxt pointer for loading here, thus we have globals.
static XSLTProcessor* globalProcessor = 0;
-static DocLoader* globalDocLoader = 0;
+static CachedResourceLoader* globalCachedResourceLoader = 0;
static xmlDocPtr docLoaderFunc(const xmlChar* uri,
- xmlDictPtr,
- int options,
- void* ctxt,
- xsltLoadType type)
+ xmlDictPtr,
+ int options,
+ void* ctxt,
+ xsltLoadType type)
{
if (!globalProcessor)
return 0;
@@ -117,14 +117,14 @@ static xmlDocPtr docLoaderFunc(const xmlChar* uri,
Vector<char> data;
- bool requestAllowed = globalDocLoader->frame() && globalDocLoader->doc()->securityOrigin()->canRequest(url);
+ bool requestAllowed = globalCachedResourceLoader->frame() && globalCachedResourceLoader->doc()->securityOrigin()->canRequest(url);
if (requestAllowed) {
- globalDocLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
- requestAllowed = globalDocLoader->doc()->securityOrigin()->canRequest(response.url());
+ globalCachedResourceLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
+ requestAllowed = globalCachedResourceLoader->doc()->securityOrigin()->canRequest(response.url());
}
if (!requestAllowed) {
data.clear();
- globalDocLoader->printAccessDeniedMessage(url);
+ globalCachedResourceLoader->printAccessDeniedMessage(url);
}
Console* console = 0;
@@ -151,11 +151,11 @@ static xmlDocPtr docLoaderFunc(const xmlChar* uri,
return 0;
}
-static inline void setXSLTLoadCallBack(xsltDocLoaderFunc func, XSLTProcessor* processor, DocLoader* loader)
+static inline void setXSLTLoadCallBack(xsltDocLoaderFunc func, XSLTProcessor* processor, CachedResourceLoader* cachedResourceLoader)
{
xsltSetLoaderFunc(func);
globalProcessor = processor;
- globalDocLoader = loader;
+ globalCachedResourceLoader = cachedResourceLoader;
}
static int writeToVector(void* context, const char* buffer, int len)
@@ -245,7 +245,7 @@ static inline xmlDocPtr xmlDocPtrFromNode(Node* sourceNode, bool& shouldDelete)
if (sourceIsDocument && ownerDocument->transformSource())
sourceDoc = (xmlDocPtr)ownerDocument->transformSource()->platformSource();
if (!sourceDoc) {
- sourceDoc = (xmlDocPtr)xmlDocPtrForString(ownerDocument->docLoader(), createMarkup(sourceNode),
+ sourceDoc = (xmlDocPtr)xmlDocPtrForString(ownerDocument->cachedResourceLoader(), createMarkup(sourceNode),
sourceIsDocument ? ownerDocument->url().string() : String());
shouldDelete = sourceDoc;
}
@@ -275,7 +275,7 @@ bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String
{
RefPtr<Document> ownerDocument = sourceNode->document();
- setXSLTLoadCallBack(docLoaderFunc, this, ownerDocument->docLoader());
+ setXSLTLoadCallBack(docLoaderFunc, this, ownerDocument->cachedResourceLoader());
xsltStylesheetPtr sheet = xsltStylesheetPointer(m_stylesheet, m_stylesheetRootNode.get());
if (!sheet) {
setXSLTLoadCallBack(0, 0, 0);
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 898fc8d..bdddda0 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-02 Steve Block <steveblock@google.com>
+
+ Reviewed by Adam Barth.
+
+ Hook up LayoutTestController.setMockDeviceOrientation() on Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=43181
+
+ * WebKit.xcodeproj/project.pbxproj:
+
2010-08-30 Andy Estes <aestes@apple.com>
Reviewed by Darin Adler.
diff --git a/WebKit/WebKit.xcodeproj/project.pbxproj b/WebKit/WebKit.xcodeproj/project.pbxproj
index b76bd24..5b44054 100644
--- a/WebKit/WebKit.xcodeproj/project.pbxproj
+++ b/WebKit/WebKit.xcodeproj/project.pbxproj
@@ -111,6 +111,15 @@
51FDC4D30B0AF5C100F84EB3 /* WebHistoryItemPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FDC4D20B0AF5C100F84EB3 /* WebHistoryItemPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
5241ADF50B1BC48A004012BD /* WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5241ADF30B1BC48A004012BD /* WebCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
5241ADF60B1BC48A004012BD /* WebCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5241ADF40B1BC48A004012BD /* WebCache.mm */; };
+ 598AD91A1201CEC900ABAE4E /* WebDeviceOrientationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 598AD9191201CEC900ABAE4E /* WebDeviceOrientationClient.h */; };
+ 598AD91E1201CECF00ABAE4E /* WebDeviceOrientationClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 598AD91D1201CECF00ABAE4E /* WebDeviceOrientationClient.mm */; };
+ 598AD9201201CF0700ABAE4E /* WebDeviceOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = 598AD91F1201CF0700ABAE4E /* WebDeviceOrientation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 598AD9221201CF1000ABAE4E /* WebDeviceOrientation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 598AD9211201CF1000ABAE4E /* WebDeviceOrientation.mm */; };
+ 598AD9241201CF1900ABAE4E /* WebDeviceOrientationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 598AD9231201CF1900ABAE4E /* WebDeviceOrientationInternal.h */; };
+ 598AD9261201CF2500ABAE4E /* WebDeviceOrientationProviderMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 598AD9251201CF2500ABAE4E /* WebDeviceOrientationProviderMock.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 598AD9281201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm in Sources */ = {isa = PBXBuildFile; fileRef = 598AD9271201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm */; };
+ 598AD92A1201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 598AD9291201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h */; };
+ 598ADA461202275000ABAE4E /* WebDeviceOrientationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 598ADA451202275000ABAE4E /* WebDeviceOrientationProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D7BF8140C2A1D90008CE06D /* WebInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D7BF8120C2A1D90008CE06D /* WebInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D7BF8150C2A1D90008CE06D /* WebInspector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5D7BF8130C2A1D90008CE06D /* WebInspector.mm */; };
5DE83A7A0D0F7F9400CAD12A /* WebJavaScriptTextInputPanel.nib in Resources */ = {isa = PBXBuildFile; fileRef = 5DE83A740D0F7F9400CAD12A /* WebJavaScriptTextInputPanel.nib */; };
@@ -523,6 +532,15 @@
51FDC4D20B0AF5C100F84EB3 /* WebHistoryItemPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebHistoryItemPrivate.h; sourceTree = "<group>"; };
5241ADF30B1BC48A004012BD /* WebCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCache.h; sourceTree = "<group>"; };
5241ADF40B1BC48A004012BD /* WebCache.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCache.mm; sourceTree = "<group>"; };
+ 598AD9191201CEC900ABAE4E /* WebDeviceOrientationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDeviceOrientationClient.h; sourceTree = "<group>"; };
+ 598AD91D1201CECF00ABAE4E /* WebDeviceOrientationClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebDeviceOrientationClient.mm; sourceTree = "<group>"; };
+ 598AD91F1201CF0700ABAE4E /* WebDeviceOrientation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDeviceOrientation.h; sourceTree = "<group>"; };
+ 598AD9211201CF1000ABAE4E /* WebDeviceOrientation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebDeviceOrientation.mm; sourceTree = "<group>"; };
+ 598AD9231201CF1900ABAE4E /* WebDeviceOrientationInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDeviceOrientationInternal.h; sourceTree = "<group>"; };
+ 598AD9251201CF2500ABAE4E /* WebDeviceOrientationProviderMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDeviceOrientationProviderMock.h; sourceTree = "<group>"; };
+ 598AD9271201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebDeviceOrientationProviderMock.mm; sourceTree = "<group>"; };
+ 598AD9291201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDeviceOrientationProviderMockInternal.h; sourceTree = "<group>"; };
+ 598ADA451202275000ABAE4E /* WebDeviceOrientationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebDeviceOrientationProvider.h; sourceTree = "<group>"; };
5D7BF8120C2A1D90008CE06D /* WebInspector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebInspector.h; sourceTree = "<group>"; };
5D7BF8130C2A1D90008CE06D /* WebInspector.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = WebInspector.mm; sourceTree = "<group>"; };
5DE83A750D0F7F9400CAD12A /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/WebJavaScriptTextInputPanel.nib; sourceTree = SOURCE_ROOT; };
@@ -1124,6 +1142,13 @@
9C7CABBB0190A37C0ECA16EA /* WebView */ = {
isa = PBXGroup;
children = (
+ 598ADA451202275000ABAE4E /* WebDeviceOrientationProvider.h */,
+ 598AD9291201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h */,
+ 598AD9271201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm */,
+ 598AD9251201CF2500ABAE4E /* WebDeviceOrientationProviderMock.h */,
+ 598AD9231201CF1900ABAE4E /* WebDeviceOrientationInternal.h */,
+ 598AD9211201CF1000ABAE4E /* WebDeviceOrientation.mm */,
+ 598AD91F1201CF0700ABAE4E /* WebDeviceOrientation.h */,
F52CA6BD02DF9D0F018635CA /* HTML */,
51E94C0706C02CA300A9B09E /* PDF */,
8373435A0624EE0D00F3B289 /* WebArchive.h */,
@@ -1249,6 +1274,8 @@
F5B36B400281DE87018635CB /* WebCoreSupport */ = {
isa = PBXGroup;
children = (
+ 598AD91D1201CECF00ABAE4E /* WebDeviceOrientationClient.mm */,
+ 598AD9191201CEC900ABAE4E /* WebDeviceOrientationClient.h */,
B68049710FFBCEC1009F7F62 /* WebApplicationCache.h */,
B68049720FFBCEC1009F7F62 /* WebApplicationCache.mm */,
A5DEFC1111D5344B00885273 /* WebApplicationCacheQuotaManager.h */,
@@ -1589,6 +1616,12 @@
A57E2F24120749E600048DF3 /* WebQuotaManager.h in Headers */,
B804176F1217A83100466BAE /* WebInspectorFrontend.h in Headers */,
9391F275121B38BD00EBF7E8 /* WebFrameNetworkingContext.h in Headers */,
+ 598AD91A1201CEC900ABAE4E /* WebDeviceOrientationClient.h in Headers */,
+ 598AD9201201CF0700ABAE4E /* WebDeviceOrientation.h in Headers */,
+ 598AD9241201CF1900ABAE4E /* WebDeviceOrientationInternal.h in Headers */,
+ 598AD9261201CF2500ABAE4E /* WebDeviceOrientationProviderMock.h in Headers */,
+ 598AD92A1201CF3B00ABAE4E /* WebDeviceOrientationProviderMockInternal.h in Headers */,
+ 598ADA461202275000ABAE4E /* WebDeviceOrientationProvider.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1952,6 +1985,9 @@
A5DEFC1411D5344B00885273 /* WebApplicationCacheQuotaManager.mm in Sources */,
B80417701217A83100466BAE /* WebInspectorFrontend.mm in Sources */,
9391F276121B38BD00EBF7E8 /* WebFrameNetworkingContext.mm in Sources */,
+ 598AD91E1201CECF00ABAE4E /* WebDeviceOrientationClient.mm in Sources */,
+ 598AD9221201CF1000ABAE4E /* WebDeviceOrientation.mm in Sources */,
+ 598AD9281201CF3200ABAE4E /* WebDeviceOrientationProviderMock.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 527e8ef..e9f6354 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,437 @@
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * src/ContextMenuClientImpl.cpp:
+ (WebKit::selectMisspelledWord):
+ (WebKit::ContextMenuClientImpl::getCustomMenuFromDefaultItems):
+ * src/WebFrameImpl.cpp:
+ (WebKit::WebFrameImpl::find):
+ (WebKit::WebFrameImpl::stopFinding):
+ (WebKit::WebFrameImpl::scopeStringMatches):
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::caretOrSelectionBounds):
+ Changed call sites to use editor().
+
+2010-09-09 Kenneth Russell <kbr@google.com>
+
+ Reviewed by James Robinson.
+
+ Memory leak in red/black tree
+ https://bugs.webkit.org/show_bug.cgi?id=45472
+
+ Fixed memory leak in red/black tree where it was using operator
+ new directly to allocate its internal nodes rather than the arena
+ with which it was configured. Added allocateObject variant to
+ arena supporting single-argument constructors. Added test to
+ red/black tree unit tests to cover this functionality, and
+ refactored TrackedAllocator into helper file to share between
+ arena and red/black tree tests.
+
+ * WebKit.gyp:
+ * tests/ArenaTestHelpers.h: Added.
+ (WebCore::ArenaTestHelpers::TrackedAllocator::create):
+ (WebCore::ArenaTestHelpers::TrackedAllocator::allocate):
+ (WebCore::ArenaTestHelpers::TrackedAllocator::free):
+ (WebCore::ArenaTestHelpers::TrackedAllocator::isEmpty):
+ (WebCore::ArenaTestHelpers::TrackedAllocator::numRegions):
+ (WebCore::ArenaTestHelpers::TrackedAllocator::TrackedAllocator):
+ * tests/PODArenaTest.cpp:
+ * tests/PODRedBlackTreeTest.cpp:
+ (WebCore::TEST):
+
+2010-09-09 Tony Chang <tony@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [chromium] make linux checksums computed from pngs to match windows
+ https://bugs.webkit.org/show_bug.cgi?id=45465
+
+ * src/WebKit.cpp:
+ (WebKit::areLayoutTestImagesOpaque): Make linux match windows.
+
+2010-09-09 Chris Guillory <chris.guillory@google.com>
+
+ Reviewed by Chris Fleizach.
+
+ Add methods used to determine accessibility state.
+ https://bugs.webkit.org/show_bug.cgi?id=45434
+
+
+ * public/WebAccessibilityObject.h:
+ * src/WebAccessibilityObject.cpp:
+ (WebKit::WebAccessibilityObject::canSetSelectedAttribute):
+ (WebKit::WebAccessibilityObject::isCollapsed):
+ (WebKit::WebAccessibilityObject::isLinked):
+ (WebKit::WebAccessibilityObject::isReadOnly):
+ (WebKit::WebAccessibilityObject::isVisible):
+
+2010-09-08 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: add a sanity test for DOM storage view in the storage panel
+ https://bugs.webkit.org/show_bug.cgi?id=45294
+
+ * src/js/Tests.js: removed testStoragePanel which was superseded by inspector layout tests.
+
+2010-09-08 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: test that debugger won't pause on syntax errors
+ https://bugs.webkit.org/show_bug.cgi?id=45388
+
+ * src/js/Tests.js: removed testAutoContinueOnSyntaxError which is now covered by
+ inspector/debugger-autocontinue-on-syntax-error.html layout test
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Reviewed by David Hyatt.
+
+ Add smooth scrolling framework, and a Windows implementation.
+ https://bugs.webkit.org/show_bug.cgi?id=32356
+
+ * src/WebScrollbarImpl.cpp: Plumb new ScrollbarClient functions. Allow wheel scrolls to be animated.
+ (WebKit::WebScrollbarImpl::setLocation):
+ (WebKit::WebScrollbarImpl::setValue):
+ (WebKit::WebScrollbarImpl::scroll):
+ (WebKit::WebScrollbarImpl::onMouseWheel):
+ (WebKit::WebScrollbarImpl::onKeyDown):
+ (WebKit::WebScrollbarImpl::setScrollOffsetFromAnimation):
+ * src/WebScrollbarImpl.h: Plumb new ScrollbarClient functions.
+ * src/win/WebInputEventFactory.cpp: Update comments now that we have smooth scrolling.
+ (WebKit::WebInputEventFactory::mouseWheelEvent):
+
+2010-09-08 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: remove some obsolete interactive tests
+ https://bugs.webkit.org/show_bug.cgi?id=45371
+
+ * src/js/Tests.js:
+
+2010-09-08 Hans Wennborg <hans@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Plug leak in WebDeviceOrientationClientMock
+ https://bugs.webkit.org/show_bug.cgi?id=45305
+
+ WebDeviceOrientationClientMock is responsible for destroying the
+ WebDeviceOrientationController object pointed to by the argument
+ passed to the setController() member function.
+
+ Also use the new WebPrivateOnwPtr for m_clientMock.
+
+ * public/WebDeviceOrientationClientMock.h:
+ * src/WebDeviceOrientationClientMock.cpp:
+ (WebKit::WebDeviceOrientationClientMock::setController):
+ (WebKit::WebDeviceOrientationClientMock::initialize):
+ (WebKit::WebDeviceOrientationClientMock::reset):
+
+2010-09-07 Tony Chang <tony@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Make a public flag for how DRT generates bitmaps on Linux
+ https://bugs.webkit.org/show_bug.cgi?id=45133
+
+ This is so it's possible for me to fix
+ http://code.google.com/p/chromium/issues/detail?id=21386 .
+
+ * public/WebKit.h: Add areLayoutTestImagesOpaque()
+ * src/WebKit.cpp:
+ (WebKit::areLayoutTestImagesOpaque):
+
+2010-09-07 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Unreviewed, rolling out r66886.
+ http://trac.webkit.org/changeset/66886
+ https://bugs.webkit.org/show_bug.cgi?id=45112
+
+ Made
+
+ * public/WebGeolocationService.h:
+ * src/WebGeolocationServiceBridgeImpl.cpp:
+ (WebKit::WebGeolocationServiceBridgeImpl::WebGeolocationServiceBridgeImpl):
+ (WebKit::WebGeolocationServiceBridgeImpl::~WebGeolocationServiceBridgeImpl):
+ (WebKit::WebGeolocationServiceBridgeImpl::startUpdating):
+ (WebKit::WebGeolocationServiceBridgeImpl::stopUpdating):
+ (WebKit::WebGeolocationServiceBridgeImpl::suspend):
+ (WebKit::WebGeolocationServiceBridgeImpl::resume):
+ (WebKit::WebGeolocationServiceBridgeImpl::attachBridgeIfNeeded):
+ (WebKit::WebGeolocationServiceBridgeImpl::setIsAllowed):
+ (WebKit::WebGeolocationServiceBridgeImpl::setLastPosition):
+ (WebKit::WebGeolocationServiceBridgeImpl::setLastError):
+ (WebKit::WebGeolocationServiceBridgeImpl::getWebViewClient):
+ (WebKit::WebGeolocationServiceBridgeImpl::onWebGeolocationServiceDestroyed):
+ * src/WebGeolocationServiceMock.cpp:
+
+2010-09-07 Jonathan Dixon <joth@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Access to out-of-scope WebGeolocationServiceBridgeImpl
+ https://bugs.webkit.org/show_bug.cgi?id=45112
+
+ Keep the WebGeolocationService pointer for lifetime of the bridge, to
+ ensure it can be detached reliably
+
+ * public/WebGeolocationServiceBridge.h:
+ (WebKit::WebGeolocationServiceBridge::~WebGeolocationServiceBridge):
+ * src/WebGeolocationServiceBridgeImpl.cpp:
+ (WebKit::WebGeolocationServiceBridgeImpl::WebGeolocationServiceBridgeImpl):
+ (WebKit::WebGeolocationServiceBridgeImpl::~WebGeolocationServiceBridgeImpl):
+ (WebKit::WebGeolocationServiceBridgeImpl::startUpdating):
+ (WebKit::WebGeolocationServiceBridgeImpl::stopUpdating):
+ (WebKit::WebGeolocationServiceBridgeImpl::suspend):
+ (WebKit::WebGeolocationServiceBridgeImpl::resume):
+ (WebKit::WebGeolocationServiceBridgeImpl::attachBridgeIfNeeded):
+
+2010-09-07 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: upstream two debugger tests
+ https://bugs.webkit.org/show_bug.cgi?id=45262
+
+ * src/js/Tests.js:
+
+2010-09-06 Jonathan Dixon <joth@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Add new interface and empty impl. as precursor to bug 45112
+ https://bugs.webkit.org/show_bug.cgi?id=45257
+
+ * public/WebGeolocationServiceBridge.h:
+ (WebKit::WebGeolocationServiceBridge::~WebGeolocationServiceBridge):
+ * src/WebGeolocationServiceBridgeImpl.cpp:
+ (WebKit::WebGeolocationServiceBridgeImpl::onWebGeolocationServiceDestroyed):
+
+2010-09-06 Pavel Podivilov <podivilov@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ Web Inspector: fix chromium devtools tests
+ https://bugs.webkit.org/show_bug.cgi?id=45258
+
+ * src/js/Tests.js:
+ (.TestSuite.prototype._waitForScriptPause):
+
+2010-08-26 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ Add index insertion support to IndexedDB.
+ https://bugs.webkit.org/show_bug.cgi?id=44695
+
+ Add asserts on the [] operator.
+
+ * public/WebVector.h:
+ (WebKit::WebVector::operator[]):
+
+2010-09-06 Anton Muhin <antonm@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [v8] bypass caches when query memory usage from post GC and in crash handler.
+ https://bugs.webkit.org/show_bug.cgi?id=45036
+
+ Add Chromium-specific API to query actual memory usage which bypasses any caches.
+
+ * public/WebKitClient.h:
+ (WebKit::WebKitClient::actualMemoryUsageMB):
+ * src/ChromiumBridge.cpp:
+ (WebCore::ChromiumBridge::actualMemoryUsageMB):
+
+2010-09-05 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Adam Barth.
+
+ Make Chromium/Mac generate continuous mousewheel events with the same wheelDelta values as Safari/Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=45155
+
+ * src/mac/WebInputEventFactory.mm:
+ (WebKit::WebInputEventFactory::mouseWheelEvent):
+
+2010-09-05 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: remove WebDevToolsAgentClient::forceRepaint which is not used
+ https://bugs.webkit.org/show_bug.cgi?id=45179
+
+ * public/WebDevToolsAgentClient.h:
+ * src/DebuggerAgentImpl.cpp:
+ (WebKit::DebuggerAgentImpl::debuggerOutput):
+ * src/WebDevToolsAgentImpl.cpp:
+ * src/WebDevToolsAgentImpl.h:
+
+2010-09-05 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Add unit tests for interval tree
+ https://bugs.webkit.org/show_bug.cgi?id=45161
+
+ * WebKit.gyp:
+ * tests/PODIntervalTreeTest.cpp: Added.
+ (WebCore::valueToString):
+ (WebCore::TEST):
+ (WebCore::UserData1::valueToString):
+ (WebCore::EndpointType1::valueToString):
+
+2010-09-05 Kenneth Russell <kbr@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Add unit tests for red-black tree and (POD) arena
+ https://bugs.webkit.org/show_bug.cgi?id=45060
+
+ * WebKit.gyp:
+ * tests/PODArenaTest.cpp: Added.
+ (WebCore::TestClass1::TestClass2::TestClass2):
+ (WebCore::TEST_F):
+ * tests/PODRedBlackTreeTest.cpp: Added.
+ (WebCore::TEST):
+ * tests/TreeTestHelpers.cpp: Added.
+ (WebCore::TreeTestHelpers::generateSeed):
+ (WebCore::TreeTestHelpers::initRandom):
+ (WebCore::TreeTestHelpers::nextRandom):
+ * tests/TreeTestHelpers.h: Added.
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Add Chromium's implementation of NetworkingContext.
+
+ * src/FrameLoaderClientImpl.cpp:
+ (WebKit::FrameLoaderClientImpl::createNetworkingContext):
+ * src/FrameLoaderClientImpl.h:
+
+2010-09-02 Vangelis Kokkevis <vangelis@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Revert to software compositing if the accelerated
+ compositor fails to initialize. If we tried to initialize the compositor
+ for this WebView and failed, next time the associated chrome client is
+ asked whether it can do accelerated compositing it will return false.
+ https://bugs.webkit.org/show_bug.cgi?id=45124
+
+ * src/ChromeClientImpl.cpp:
+ (WebKit::ChromeClientImpl::allowsAcceleratedCompositing):
+ * src/ChromeClientImpl.h:
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::WebViewImpl):
+ (WebKit::WebViewImpl::paint):
+ (WebKit::WebViewImpl::allowsAcceleratedCompositing):
+ (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+ (WebKit::WebViewImpl::getOnscreenGLES2Context):
+ * src/WebViewImpl.h:
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ [chromium] Add one more include to fix the mac compile.
+
+ * src/GraphicsContext3D.cpp:
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ [chromium] Compile fixes for 66746.
+
+ * src/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas):
+
+2010-09-03 Tony Chang <tony@chromium.org>
+
+ Unreviewed, remove svn:executable flag from images and css files.
+
+ * src/js/Images/segmentChromium.png: Removed property svn:executable.
+ * src/js/Images/segmentHoverChromium.png: Removed property svn:executable.
+ * src/js/Images/segmentHoverEndChromium.png: Removed property svn:executable.
+ * src/js/Images/segmentSelectedChromium.png: Removed property svn:executable.
+ * src/js/Images/segmentSelectedEndChromium.png: Removed property svn:executable.
+ * src/js/Images/statusbarBackgroundChromium.png: Removed property svn:executable.
+ * src/js/Images/statusbarBottomBackgroundChromium.png: Removed property svn:executable.
+ * src/js/Images/statusbarButtonsChromium.png: Removed property svn:executable.
+ * src/js/Images/statusbarMenuButtonChromium.png: Removed property svn:executable.
+ * src/js/Images/statusbarMenuButtonSelectedChromium.png: Removed property svn:executable.
+ * src/js/devTools.css: Removed property svn:executable.
+
+2010-09-03 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Chris Marrin.
+
+ Multiple accelerated 2D canvases should be able to use the same GraphicsContext3D
+ https://bugs.webkit.org/show_bug.cgi?id=44926
+
+ Adds a SharedContext3D to WebViewImpl. The SharedContext3D has to live on WebViewImpl to be
+ tied to the lifetime of the compositor context.
+
+ * src/ChromeClientImpl.cpp:
+ (WebKit::ChromeClientImpl::getSharedGraphicsContext3D):
+ * src/ChromeClientImpl.h:
+ * src/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3DInternal::initialize):
+ (WebCore::GraphicsContext3DInternal::platformLayer):
+ (WebCore::GraphicsContext3D::platformLayer):
+ * src/WebViewImpl.cpp:
+ (WebKit::WebViewImpl::getSharedGraphicsContext3D):
+ * src/WebViewImpl.h:
+
+2010-08-31 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Steve Block.
+
+ IDBCursor.continue() should reuse the .openCursor's IDBRequest object
+ https://bugs.webkit.org/show_bug.cgi?id=44953
+
+ * src/WebIDBCallbacksImpl.cpp:
+ (WebCore::WebIDBCallbacksImpl::onError):
+ (WebCore::WebIDBCallbacksImpl::onSuccess):
+
+2010-09-02 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ REGRESSION: Crash occurs at objc_msgSend when closing a window that is displaying the web inspector
+ https://bugs.webkit.org/show_bug.cgi?id=44230
+
+ * src/InspectorFrontendClientImpl.cpp:
+ (WebKit::InspectorFrontendClientImpl::disconnectFromBackend):
+ * src/InspectorFrontendClientImpl.h:
+
+2010-09-02 Satish Sampath <satish@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Remove obsolete public/API methods in chromium port
+ https://bugs.webkit.org/show_bug.cgi?id=45108
+
+ * public/WebSpeechInputController.h:
+ (WebKit::WebSpeechInputController::startRecognition):
+
+2010-09-02 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [DRT/Chromium] Remove dependency to base/task.h and base/timer.h
+ https://bugs.webkit.org/show_bug.cgi?id=45091
+
+ * DEPS: Roll Chromium revision to 58277 in order to have
+ webkit_support::PostDelayedTask().
+
2010-09-02 Ilya Sherman <isherman@google.com>
Reviewed by Eric Seidel.
diff --git a/WebKit/chromium/DEPS b/WebKit/chromium/DEPS
index 6252f08..2fc218b 100644
--- a/WebKit/chromium/DEPS
+++ b/WebKit/chromium/DEPS
@@ -32,7 +32,7 @@
vars = {
'chromium_svn': 'http://src.chromium.org/svn/trunk/src',
- 'chromium_rev': '57823',
+ 'chromium_rev': '58277',
}
deps = {
diff --git a/WebKit/chromium/WebKit.gyp b/WebKit/chromium/WebKit.gyp
index c75cac7..11246fa 100644
--- a/WebKit/chromium/WebKit.gyp
+++ b/WebKit/chromium/WebKit.gyp
@@ -733,13 +733,19 @@
'src',
],
'sources': [
+ 'tests/ArenaTestHelpers.h',
'tests/DragImageTest.cpp',
'tests/IDBBindingUtilitiesTest.cpp',
'tests/IDBKeyPathTest.cpp',
'tests/KeyboardTest.cpp',
'tests/KURLTest.cpp',
+ 'tests/PODArenaTest.cpp',
+ 'tests/PODIntervalTreeTest.cpp',
+ 'tests/PODRedBlackTreeTest.cpp',
'tests/RunAllTests.cpp',
'tests/TilingDataTest.cpp',
+ 'tests/TreeTestHelpers.cpp',
+ 'tests/TreeTestHelpers.h',
],
'conditions': [
['OS=="win"', {
diff --git a/WebKit/chromium/public/WebAccessibilityObject.h b/WebKit/chromium/public/WebAccessibilityObject.h
index ddb9bda..6b55376 100644
--- a/WebKit/chromium/public/WebAccessibilityObject.h
+++ b/WebKit/chromium/public/WebAccessibilityObject.h
@@ -81,17 +81,22 @@ public:
WEBKIT_API WebAccessibilityObject parentObject() const;
WEBKIT_API WebAccessibilityObject previousSibling() const;
+ WEBKIT_API bool canSetSelectedAttribute() const;
WEBKIT_API bool isAnchor() const;
WEBKIT_API bool isChecked() const;
+ WEBKIT_API bool isCollapsed() const;
WEBKIT_API bool isFocused() const;
WEBKIT_API bool isEnabled() const;
WEBKIT_API bool isHovered() const;
WEBKIT_API bool isIndeterminate() const;
+ WEBKIT_API bool isLinked() const;
WEBKIT_API bool isMultiSelectable() const;
WEBKIT_API bool isOffScreen() const;
WEBKIT_API bool isPasswordField() const;
WEBKIT_API bool isPressed() const;
WEBKIT_API bool isReadOnly() const;
+ WEBKIT_API bool isSelected() const;
+ WEBKIT_API bool isVisible() const;
WEBKIT_API bool isVisited() const;
WEBKIT_API WebRect boundingBoxRect() const;
diff --git a/WebKit/chromium/public/WebDevToolsAgentClient.h b/WebKit/chromium/public/WebDevToolsAgentClient.h
index 087ac0b..b373b60 100644
--- a/WebKit/chromium/public/WebDevToolsAgentClient.h
+++ b/WebKit/chromium/public/WebDevToolsAgentClient.h
@@ -44,9 +44,6 @@ public:
virtual void sendDebuggerOutput(const WebString&) { }
virtual void sendDispatchToAPU(const WebString&) { }
- // Invalidates widget which leads to the repaint.
- virtual void forceRepaint() { }
-
// Returns the identifier of the entity hosting this agent.
virtual int hostIdentifier() { return -1; }
diff --git a/WebKit/chromium/public/WebDeviceOrientationClientMock.h b/WebKit/chromium/public/WebDeviceOrientationClientMock.h
index fce964b..9cbccf7 100644
--- a/WebKit/chromium/public/WebDeviceOrientationClientMock.h
+++ b/WebKit/chromium/public/WebDeviceOrientationClientMock.h
@@ -28,6 +28,7 @@
#include "WebCommon.h"
#include "WebDeviceOrientationClient.h"
+#include "WebPrivateOwnPtr.h"
namespace WebCore { class DeviceOrientationClientMock; }
@@ -49,7 +50,7 @@ private:
WEBKIT_API void initialize();
WEBKIT_API void reset();
- WebCore::DeviceOrientationClientMock* m_clientMock;
+ WebPrivateOwnPtr<WebCore::DeviceOrientationClientMock> m_clientMock;
};
} // namespace WebKit
diff --git a/WebKit/chromium/public/WebGeolocationServiceBridge.h b/WebKit/chromium/public/WebGeolocationServiceBridge.h
index 9f0ffd4..422b32b 100644
--- a/WebKit/chromium/public/WebGeolocationServiceBridge.h
+++ b/WebKit/chromium/public/WebGeolocationServiceBridge.h
@@ -47,6 +47,10 @@ public:
virtual void setIsAllowed(bool allowed) = 0;
virtual void setLastPosition(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed, long long timestamp) = 0;
virtual void setLastError(int errorCode, const WebString& message) = 0;
+ virtual void onWebGeolocationServiceDestroyed() = 0;
+
+protected:
+ virtual ~WebGeolocationServiceBridge() {}
};
} // namespace WebKit
diff --git a/WebKit/chromium/public/WebKit.h b/WebKit/chromium/public/WebKit.h
index 732cac6..5550db1 100644
--- a/WebKit/chromium/public/WebKit.h
+++ b/WebKit/chromium/public/WebKit.h
@@ -55,6 +55,11 @@ WEBKIT_API WebKitClient* webKitClient();
WEBKIT_API void setLayoutTestMode(bool);
WEBKIT_API bool layoutTestMode();
+// This is a temporary flag while we try to get Linux to match Windows'
+// checksum computation. It specifies whether or not the baseline images
+// should be opaque or not.
+WEBKIT_API bool areLayoutTestImagesOpaque();
+
// Enables the named log channel. See WebCore/platform/Logging.h for details.
WEBKIT_API void enableLogChannel(const char*);
diff --git a/WebKit/chromium/public/WebKitClient.h b/WebKit/chromium/public/WebKitClient.h
index 9c0b4c2..0f282e0 100644
--- a/WebKit/chromium/public/WebKitClient.h
+++ b/WebKit/chromium/public/WebKitClient.h
@@ -163,6 +163,9 @@ public:
// That is committed size for Windows and virtual memory size for POSIX
virtual size_t memoryUsageMB() { return 0; }
+ // Same as above, but always returns actual value, without any caches.
+ virtual size_t actualMemoryUsageMB() { return 0; }
+
// Message Ports -------------------------------------------------------
diff --git a/WebKit/chromium/public/WebSpeechInputController.h b/WebKit/chromium/public/WebSpeechInputController.h
index 0315722..5408741 100644
--- a/WebKit/chromium/public/WebSpeechInputController.h
+++ b/WebKit/chromium/public/WebSpeechInputController.h
@@ -45,11 +45,6 @@ public:
// text are returned via the listener interface.
virtual bool startRecognition(int requestId, const WebRect&)
{
- return startRecognition(requestId);
- }
- // FIXME: Remove this once chromium has picked up this change.
- virtual bool startRecognition(int)
- {
WEBKIT_ASSERT_NOT_REACHED();
return false;
}
diff --git a/WebKit/chromium/public/WebVector.h b/WebKit/chromium/public/WebVector.h
index 0520895..cf3ec95 100644
--- a/WebKit/chromium/public/WebVector.h
+++ b/WebKit/chromium/public/WebVector.h
@@ -115,8 +115,16 @@ public:
size_t size() const { return m_size; }
bool isEmpty() const { return !m_size; }
- T& operator[](size_t i) { return m_ptr[i]; }
- const T& operator[](size_t i) const { return m_ptr[i]; }
+ T& operator[](size_t i)
+ {
+ WEBKIT_ASSERT(i < m_size);
+ return m_ptr[i];
+ }
+ const T& operator[](size_t i) const
+ {
+ WEBKIT_ASSERT(i < m_size);
+ return m_ptr[i];
+ }
T* data() { return m_ptr; }
const T* data() const { return m_ptr; }
diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp
index e6f1400..8a3eda6 100644
--- a/WebKit/chromium/src/ChromeClientImpl.cpp
+++ b/WebKit/chromium/src/ChromeClientImpl.cpp
@@ -59,6 +59,7 @@
#include "SearchPopupMenuChromium.h"
#include "ScriptController.h"
#include "SecurityOrigin.h"
+#include "SharedGraphicsContext3D.h"
#include "WebGeolocationService.h"
#if USE(V8)
#include "V8Proxy.h"
@@ -749,8 +750,18 @@ void ChromeClientImpl::scheduleCompositingLayerSync()
{
m_webView->setRootLayerNeedsDisplay();
}
+
+bool ChromeClientImpl::allowsAcceleratedCompositing() const
+{
+ return m_webView->allowsAcceleratedCompositing();
+}
#endif
+WebCore::SharedGraphicsContext3D* ChromeClientImpl::getSharedGraphicsContext3D()
+{
+ return m_webView->getSharedGraphicsContext3D();
+}
+
bool ChromeClientImpl::supportsFullscreenForNode(const WebCore::Node* node)
{
if (m_webView->client() && node->hasTagName(WebCore::HTMLNames::videoTag))
diff --git a/WebKit/chromium/src/ChromeClientImpl.h b/WebKit/chromium/src/ChromeClientImpl.h
index bff9f90..d16d8f6 100644
--- a/WebKit/chromium/src/ChromeClientImpl.h
+++ b/WebKit/chromium/src/ChromeClientImpl.h
@@ -150,8 +150,13 @@ public:
// Sets a flag to specify that the view needs to be updated, so we need
// to do an eager layout before the drawing.
virtual void scheduleCompositingLayerSync();
+
+ // Returns true if accelerated compositing is supported.
+ virtual bool allowsAcceleratedCompositing() const;
#endif
+ virtual WebCore::SharedGraphicsContext3D* getSharedGraphicsContext3D();
+
virtual bool supportsFullscreenForNode(const WebCore::Node*);
virtual void enterFullscreenForNode(WebCore::Node*);
virtual void exitFullscreenForNode(WebCore::Node*);
diff --git a/WebKit/chromium/src/ChromiumBridge.cpp b/WebKit/chromium/src/ChromiumBridge.cpp
index 911dcf3..3ced7b8 100644
--- a/WebKit/chromium/src/ChromiumBridge.cpp
+++ b/WebKit/chromium/src/ChromiumBridge.cpp
@@ -823,6 +823,11 @@ int ChromiumBridge::memoryUsageMB()
return static_cast<int>(webKitClient()->memoryUsageMB());
}
+int ChromiumBridge::actualMemoryUsageMB()
+{
+ return static_cast<int>(webKitClient()->actualMemoryUsageMB());
+}
+
int ChromiumBridge::screenDepth(Widget* widget)
{
WebWidgetClient* client = toWebWidgetClient(widget);
diff --git a/WebKit/chromium/src/ContextMenuClientImpl.cpp b/WebKit/chromium/src/ContextMenuClientImpl.cpp
index 1dc2ee7..ef611e1 100644
--- a/WebKit/chromium/src/ContextMenuClientImpl.cpp
+++ b/WebKit/chromium/src/ContextMenuClientImpl.cpp
@@ -98,7 +98,7 @@ static bool isASingleWord(const String& text)
static String selectMisspelledWord(const ContextMenu* defaultMenu, Frame* selectedFrame)
{
// First select from selectedText to check for multiple word selection.
- String misspelledWord = selectedFrame->selectedText().stripWhiteSpace();
+ String misspelledWord = selectedFrame->editor()->selectedText().stripWhiteSpace();
// If some texts were already selected, we don't change the selection.
if (!misspelledWord.isEmpty()) {
@@ -119,7 +119,7 @@ static String selectMisspelledWord(const ContextMenu* defaultMenu, Frame* select
return misspelledWord; // It is empty.
WebFrameImpl::selectWordAroundPosition(selectedFrame, pos);
- misspelledWord = selectedFrame->selectedText().stripWhiteSpace();
+ misspelledWord = selectedFrame->editor()->selectedText().stripWhiteSpace();
#if OS(DARWIN)
// If misspelled word is still empty, then that portion should not be
@@ -233,7 +233,7 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems(
data.frameURL = urlFromFrame(selectedFrame);
if (r.isSelected())
- data.selectedText = selectedFrame->selectedText().stripWhiteSpace();
+ data.selectedText = selectedFrame->editor()->selectedText().stripWhiteSpace();
if (r.isContentEditable()) {
data.isEditable = true;
diff --git a/WebKit/chromium/src/DebuggerAgentImpl.cpp b/WebKit/chromium/src/DebuggerAgentImpl.cpp
index 46c6e7c..5dd5c58 100644
--- a/WebKit/chromium/src/DebuggerAgentImpl.cpp
+++ b/WebKit/chromium/src/DebuggerAgentImpl.cpp
@@ -60,7 +60,6 @@ DebuggerAgentImpl::~DebuggerAgentImpl()
void DebuggerAgentImpl::debuggerOutput(const String& command)
{
m_webdevtoolsAgentClient->sendDebuggerOutput(command);
- m_webdevtoolsAgent->forceRepaint();
}
WebCore::Page* DebuggerAgentImpl::page()
diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.cpp b/WebKit/chromium/src/FrameLoaderClientImpl.cpp
index 74186bf..ea668c7 100644
--- a/WebKit/chromium/src/FrameLoaderClientImpl.cpp
+++ b/WebKit/chromium/src/FrameLoaderClientImpl.cpp
@@ -37,6 +37,7 @@
#include "FormState.h"
#include "FrameLoader.h"
#include "FrameLoadRequest.h"
+#include "FrameNetworkingContextImpl.h"
#include "FrameView.h"
#include "HTTPParsers.h"
#include "HistoryItem.h"
@@ -1512,4 +1513,9 @@ PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver()
return ds->releasePluginLoadObserver();
}
+PassRefPtr<FrameNetworkingContext> FrameLoaderClientImpl::createNetworkingContext()
+{
+ return FrameNetworkingContextImpl::create(m_webFrame->frame());
+}
+
} // namespace WebKit
diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.h b/WebKit/chromium/src/FrameLoaderClientImpl.h
index 3a8a714..361bae4 100644
--- a/WebKit/chromium/src/FrameLoaderClientImpl.h
+++ b/WebKit/chromium/src/FrameLoaderClientImpl.h
@@ -198,6 +198,8 @@ public:
virtual void didNotAllowScript();
virtual void didNotAllowPlugins();
+ virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext();
+
private:
void makeDocumentView();
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index 6bc5ffe..3051b9b 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -35,7 +35,7 @@
#include "GraphicsContext3D.h"
#include "CachedImage.h"
-#include "CanvasLayerChromium.h"
+#include "WebGLLayerChromium.h"
#include "CanvasRenderingContext.h"
#include "Chrome.h"
#include "ChromeClientImpl.h"
@@ -55,6 +55,7 @@
#if PLATFORM(CG)
#include "GraphicsContext.h"
+#include "WebGLRenderingContext.h"
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGImage.h>
#endif
@@ -103,7 +104,7 @@ public:
void prepareTexture();
#if USE(ACCELERATED_COMPOSITING)
- CanvasLayerChromium* platformLayer() const;
+ WebGLLayerChromium* platformLayer() const;
#endif
bool isGLES2Compliant() const;
bool isGLES2NPOTStrict() const;
@@ -298,7 +299,7 @@ private:
OwnPtr<WebKit::WebGraphicsContext3D> m_impl;
WebKit::WebViewImpl* m_webViewImpl;
#if USE(ACCELERATED_COMPOSITING)
- RefPtr<CanvasLayerChromium> m_compositingLayer;
+ RefPtr<WebGLLayerChromium> m_compositingLayer;
#endif
#if PLATFORM(SKIA)
// If the width and height of the Canvas's backing store don't
@@ -360,7 +361,7 @@ bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs,
m_impl.set(webContext);
#if USE(ACCELERATED_COMPOSITING)
- m_compositingLayer = CanvasLayerChromium::create(0);
+ m_compositingLayer = WebGLLayerChromium::create(0);
#endif
return true;
}
@@ -381,7 +382,7 @@ void GraphicsContext3DInternal::prepareTexture()
}
#if USE(ACCELERATED_COMPOSITING)
-CanvasLayerChromium* GraphicsContext3DInternal::platformLayer() const
+WebGLLayerChromium* GraphicsContext3DInternal::platformLayer() const
{
return m_compositingLayer.get();
}
@@ -436,10 +437,10 @@ void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingCon
canvas.drawBitmapRect(m_resizingBitmap, 0, dst);
}
#elif PLATFORM(CG)
- if (m_renderOutput)
- context->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(),
- canvas->width(), canvas->height(),
- imageBuffer->context()->platformContext());
+ if (m_renderOutput && context->is3d()) {
+ WebGLRenderingContext* webGLContext = static_cast<WebGLRenderingContext*>(context);
+ webGLContext->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(), canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
+ }
#else
#error Must port to your platform
#endif
@@ -1039,7 +1040,7 @@ void GraphicsContext3D::prepareTexture()
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* GraphicsContext3D::platformLayer() const
{
- CanvasLayerChromium* canvasLayer = m_internal->platformLayer();
+ WebGLLayerChromium* canvasLayer = m_internal->platformLayer();
canvasLayer->setContext(this);
return canvasLayer;
}
diff --git a/WebKit/chromium/src/InspectorFrontendClientImpl.cpp b/WebKit/chromium/src/InspectorFrontendClientImpl.cpp
index 46f2cb6..51864f1 100644
--- a/WebKit/chromium/src/InspectorFrontendClientImpl.cpp
+++ b/WebKit/chromium/src/InspectorFrontendClientImpl.cpp
@@ -105,6 +105,11 @@ void InspectorFrontendClientImpl::closeWindow()
m_client->closeWindow();
}
+void InspectorFrontendClientImpl::disconnectFromBackend()
+{
+ m_client->closeWindow();
+}
+
void InspectorFrontendClientImpl::requestAttachWindow()
{
m_client->requestDockWindow();
diff --git a/WebKit/chromium/src/InspectorFrontendClientImpl.h b/WebKit/chromium/src/InspectorFrontendClientImpl.h
index 1507bf2..fc21f3e 100644
--- a/WebKit/chromium/src/InspectorFrontendClientImpl.h
+++ b/WebKit/chromium/src/InspectorFrontendClientImpl.h
@@ -61,6 +61,7 @@ public:
virtual void bringToFront();
virtual void closeWindow();
+ virtual void disconnectFromBackend();
virtual void requestAttachWindow();
virtual void requestDetachWindow();
diff --git a/WebKit/chromium/src/WebAccessibilityObject.cpp b/WebKit/chromium/src/WebAccessibilityObject.cpp
index 4263e8b..3a3e94b 100644
--- a/WebKit/chromium/src/WebAccessibilityObject.cpp
+++ b/WebKit/chromium/src/WebAccessibilityObject.cpp
@@ -182,6 +182,15 @@ WebAccessibilityObject WebAccessibilityObject::previousSibling() const
return WebAccessibilityObject(m_private->previousSibling());
}
+bool WebAccessibilityObject::canSetSelectedAttribute() const
+{
+ if (!m_private)
+ return 0;
+
+ m_private->updateBackingStore();
+ return m_private->canSetSelectedAttribute();
+}
+
bool WebAccessibilityObject::isAnchor() const
{
if (!m_private)
@@ -200,6 +209,15 @@ bool WebAccessibilityObject::isChecked() const
return m_private->isChecked();
}
+bool WebAccessibilityObject::isCollapsed() const
+{
+ if (!m_private)
+ return 0;
+
+ m_private->updateBackingStore();
+ return m_private->isCollapsed();
+}
+
bool WebAccessibilityObject::isFocused() const
{
@@ -237,6 +255,15 @@ bool WebAccessibilityObject::isIndeterminate() const
return m_private->isIndeterminate();
}
+bool WebAccessibilityObject::isLinked() const
+{
+ if (!m_private)
+ return 0;
+
+ m_private->updateBackingStore();
+ return m_private->isLinked();
+}
+
bool WebAccessibilityObject::isMultiSelectable() const
{
if (!m_private)
@@ -282,6 +309,24 @@ bool WebAccessibilityObject::isReadOnly() const
return m_private->isReadOnly();
}
+bool WebAccessibilityObject::isSelected() const
+{
+ if (!m_private)
+ return 0;
+
+ m_private->updateBackingStore();
+ return m_private->isSelected();
+}
+
+bool WebAccessibilityObject::isVisible() const
+{
+ if (!m_private)
+ return 0;
+
+ m_private->updateBackingStore();
+ return m_private->isVisible();
+}
+
bool WebAccessibilityObject::isVisited() const
{
if (!m_private)
diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp
index fbb06f8..971c290 100644
--- a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp
+++ b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp
@@ -239,11 +239,6 @@ void WebDevToolsAgentImpl::didClearWindowObject(WebFrameImpl* webframe)
DebuggerAgentManager::setHostId(webframe, m_hostId);
}
-void WebDevToolsAgentImpl::forceRepaint()
-{
- m_client->forceRepaint();
-}
-
void WebDevToolsAgentImpl::dispatchOnInspectorBackend(const WebString& message)
{
inspectorController()->inspectorBackendDispatcher()->dispatch(message);
diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.h b/WebKit/chromium/src/WebDevToolsAgentImpl.h
index da584fb..36cafcf 100644
--- a/WebKit/chromium/src/WebDevToolsAgentImpl.h
+++ b/WebKit/chromium/src/WebDevToolsAgentImpl.h
@@ -99,8 +99,6 @@ public:
virtual void timelineProfilerWasStopped();
virtual bool sendMessageToFrontend(const WTF::String&);
- void forceRepaint();
-
int hostId() { return m_hostId; }
private:
diff --git a/WebKit/chromium/src/WebDeviceOrientationClientMock.cpp b/WebKit/chromium/src/WebDeviceOrientationClientMock.cpp
index 4011d12..820c970 100644
--- a/WebKit/chromium/src/WebDeviceOrientationClientMock.cpp
+++ b/WebKit/chromium/src/WebDeviceOrientationClientMock.cpp
@@ -35,6 +35,7 @@ namespace WebKit {
void WebDeviceOrientationClientMock::setController(WebDeviceOrientationController* controller)
{
m_clientMock->setController(controller->controller());
+ delete controller;
}
void WebDeviceOrientationClientMock::startUpdating()
@@ -59,13 +60,12 @@ void WebDeviceOrientationClientMock::setOrientation(WebDeviceOrientation& orient
void WebDeviceOrientationClientMock::initialize()
{
- m_clientMock = new WebCore::DeviceOrientationClientMock();
+ m_clientMock.reset(new WebCore::DeviceOrientationClientMock());
}
void WebDeviceOrientationClientMock::reset()
{
- delete m_clientMock;
- m_clientMock = 0;
+ m_clientMock.reset(0);
}
} // namespace WebKit
diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp
index eb0db7e..a2d6a46 100644
--- a/WebKit/chromium/src/WebFrameImpl.cpp
+++ b/WebKit/chromium/src/WebFrameImpl.cpp
@@ -1356,7 +1356,7 @@ bool WebFrameImpl::find(int identifier,
}
ASSERT(frame() && frame()->view());
- bool found = frame()->findString(
+ bool found = frame()->editor()->findString(
searchText, options.forward, options.matchCase, wrapWithinFrame,
startInSelection);
if (found) {
@@ -1439,7 +1439,7 @@ void WebFrameImpl::stopFinding(bool clearSelection)
// Remove all markers for matches found and turn off the highlighting.
frame()->document()->markers()->removeMarkers(DocumentMarker::TextMatch);
- frame()->setMarkedTextMatchesAreHighlighted(false);
+ frame()->editor()->setMarkedTextMatchesAreHighlighted(false);
// Let the frame know that we don't want tickmarks or highlighting anymore.
invalidateArea(InvalidateAll);
@@ -1460,7 +1460,7 @@ void WebFrameImpl::scopeStringMatches(int identifier,
// Scoping is just about to begin.
m_scopingComplete = false;
// Clear highlighting for this frame.
- if (frame()->markedTextMatchesAreHighlighted())
+ if (frame()->editor()->markedTextMatchesAreHighlighted())
frame()->page()->unmarkAllTextMatches();
// Clear the counters from last operation.
m_lastMatchCount = 0;
@@ -1585,7 +1585,7 @@ void WebFrameImpl::scopeStringMatches(int identifier,
m_lastSearchString = searchText;
if (matchCount > 0) {
- frame()->setMarkedTextMatchesAreHighlighted(true);
+ frame()->editor()->setMarkedTextMatchesAreHighlighted(true);
m_lastMatchCount += matchCount;
diff --git a/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp
index 3c3a1db..bbb7162 100644
--- a/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp
+++ b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp
@@ -79,6 +79,7 @@ public:
virtual void setIsAllowed(bool allowed);
virtual void setLastPosition(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed, long long timestamp);
virtual void setLastError(int errorCode, const WebString& message);
+ virtual void onWebGeolocationServiceDestroyed();
private:
WebViewClient* getWebViewClient();
@@ -176,6 +177,10 @@ WebViewClient* WebGeolocationServiceBridgeImpl::getWebViewClient()
return webViewClient;
}
+void WebGeolocationServiceBridgeImpl::onWebGeolocationServiceDestroyed()
+{
+}
+
} // namespace WebKit
#endif // ENABLE(GEOLOCATION)
diff --git a/WebKit/chromium/src/WebIDBCallbacksImpl.cpp b/WebKit/chromium/src/WebIDBCallbacksImpl.cpp
index e543123..fe67789 100644
--- a/WebKit/chromium/src/WebIDBCallbacksImpl.cpp
+++ b/WebKit/chromium/src/WebIDBCallbacksImpl.cpp
@@ -57,49 +57,41 @@ WebIDBCallbacksImpl::~WebIDBCallbacksImpl()
void WebIDBCallbacksImpl::onError(const WebKit::WebIDBDatabaseError& error)
{
m_callbacks->onError(error);
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess()
{
m_callbacks->onSuccess();
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBCursor* cursor)
{
m_callbacks->onSuccess(IDBCursorBackendProxy::create(cursor));
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBDatabase* webKitInstance)
{
m_callbacks->onSuccess(IDBDatabaseProxy::create(webKitInstance));
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess(const WebKit::WebIDBKey& key)
{
m_callbacks->onSuccess(key);
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBIndex* webKitInstance)
{
m_callbacks->onSuccess(IDBIndexBackendProxy::create(webKitInstance));
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess(WebKit::WebIDBObjectStore* webKitInstance)
{
m_callbacks->onSuccess(IDBObjectStoreProxy::create(webKitInstance));
- m_callbacks.clear();
}
void WebIDBCallbacksImpl::onSuccess(const WebKit::WebSerializedScriptValue& serializedScriptValue)
{
m_callbacks->onSuccess(serializedScriptValue);
- m_callbacks.clear();
}
} // namespace WebCore
diff --git a/WebKit/chromium/src/WebKit.cpp b/WebKit/chromium/src/WebKit.cpp
index cadcb6c..f3336ea 100644
--- a/WebKit/chromium/src/WebKit.cpp
+++ b/WebKit/chromium/src/WebKit.cpp
@@ -103,6 +103,11 @@ bool layoutTestMode()
return s_layoutTestMode;
}
+bool areLayoutTestImagesOpaque()
+{
+ return true;
+}
+
void enableLogChannel(const char* name)
{
WTFLogChannel* channel = WebCore::getChannelFromName(name);
diff --git a/WebKit/chromium/src/WebScrollbarImpl.cpp b/WebKit/chromium/src/WebScrollbarImpl.cpp
index c0131cb..8b9e287 100644
--- a/WebKit/chromium/src/WebScrollbarImpl.cpp
+++ b/WebKit/chromium/src/WebScrollbarImpl.cpp
@@ -94,7 +94,7 @@ int WebScrollbarImpl::value() const
void WebScrollbarImpl::setValue(int position)
{
- m_scrollbar->setValue(position);
+ m_scrollbar->setValue(position, Scrollbar::NotFromScrollAnimator);
}
void WebScrollbarImpl::setDocumentSize(int size)
@@ -218,7 +218,7 @@ bool WebScrollbarImpl::onMouseWheel(const WebInputEvent& event)
if (negative)
delta *= -1;
}
- m_scrollbar->setValue(m_scrollbar->value() - delta);
+ m_scrollbar->scroll((m_scrollbar->orientation() == HorizontalScrollbar) ? WebCore::ScrollLeft : WebCore::ScrollUp, WebCore::ScrollByPixel, delta);
return true;
}
@@ -262,6 +262,16 @@ bool WebScrollbarImpl::onKeyDown(const WebInputEvent& event)
return false;
}
+int WebScrollbarImpl::scrollSize(WebCore::ScrollbarOrientation orientation) const
+{
+ return (orientation == m_scrollbar->orientation()) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
+}
+
+void WebScrollbarImpl::setScrollOffsetFromAnimation(const WebCore::IntPoint& offset)
+{
+ m_scrollbar->setValue((m_scrollbar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void WebScrollbarImpl::valueChanged(WebCore::Scrollbar*)
{
m_client->valueChanged(this);
diff --git a/WebKit/chromium/src/WebScrollbarImpl.h b/WebKit/chromium/src/WebScrollbarImpl.h
index a041ccc..5512867 100644
--- a/WebKit/chromium/src/WebScrollbarImpl.h
+++ b/WebKit/chromium/src/WebScrollbarImpl.h
@@ -58,6 +58,8 @@ public:
virtual bool handleInputEvent(const WebInputEvent&);
// WebCore::ScrollbarClient methods
+ virtual int scrollSize(WebCore::ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const WebCore::IntPoint&);
virtual void valueChanged(WebCore::Scrollbar*);
virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&);
virtual bool isActive() const;
diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp
index 4b129d6..137bf06 100644
--- a/WebKit/chromium/src/WebViewImpl.cpp
+++ b/WebKit/chromium/src/WebViewImpl.cpp
@@ -58,6 +58,7 @@
#include "GLES2Context.h"
#include "GLES2ContextInternal.h"
#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
#include "HTMLInputElement.h"
#include "HTMLMediaElement.h"
#include "HitTestResult.h"
@@ -86,6 +87,7 @@
#include "SecurityOrigin.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "SharedGraphicsContext3D.h"
#include "Timer.h"
#include "TypingCommand.h"
#include "UserGestureIndicator.h"
@@ -263,6 +265,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devTools
#if USE(ACCELERATED_COMPOSITING)
, m_layerRenderer(0)
, m_isAcceleratedCompositingActive(false)
+ , m_compositorCreationFailed(false)
#endif
#if ENABLE(INPUT_SPEECH)
, m_speechInputClient(client)
@@ -967,6 +970,7 @@ void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
IntRect contentRect = view->visibleContentRect(false);
// Ask the layer compositor to redraw all the layers.
+ ASSERT(m_layerRenderer->hardwareCompositing());
m_layerRenderer->drawLayers(rect, visibleRect, contentRect, IntPoint(view->scrollX(), view->scrollY()));
}
#endif
@@ -1274,7 +1278,7 @@ WebRect WebViewImpl::caretOrSelectionBounds()
if (!node || !node->renderer())
return rect;
RefPtr<Range> range = controller->toNormalizedRange();
- rect = view->contentsToWindow(focused->firstRectForRange(range.get()));
+ rect = view->contentsToWindow(focused->editor()->firstRectForRange(range.get()));
}
return rect;
}
@@ -2103,6 +2107,11 @@ bool WebViewImpl::tabsToLinks() const
}
#if USE(ACCELERATED_COMPOSITING)
+bool WebViewImpl::allowsAcceleratedCompositing()
+{
+ return !m_compositorCreationFailed;
+}
+
void WebViewImpl::setRootGraphicsLayer(WebCore::PlatformLayer* layer)
{
setIsAcceleratedCompositingActive(layer ? true : false);
@@ -2117,15 +2126,15 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
if (active) {
m_layerRenderer = LayerRendererChromium::create(getOnscreenGLES2Context());
- if (m_layerRenderer->hardwareCompositing()) {
+ if (m_layerRenderer) {
m_isAcceleratedCompositingActive = true;
// Force a redraw the entire view so that the compositor gets the entire view,
// rather than just the currently-dirty subset.
m_client->didInvalidateRect(IntRect(0, 0, m_size.width, m_size.height));
} else {
- m_layerRenderer.clear();
m_isAcceleratedCompositingActive = false;
+ m_compositorCreationFailed = true;
}
} else {
m_layerRenderer = 0;
@@ -2212,17 +2221,21 @@ void WebViewImpl::setRootLayerNeedsDisplay()
PassOwnPtr<GLES2Context> WebViewImpl::getOnscreenGLES2Context()
{
- return GLES2Context::create(GLES2ContextInternal::create(gles2Context(), false));
+ WebGLES2Context* context = gles2Context();
+ if (!context)
+ return 0;
+ return GLES2Context::create(GLES2ContextInternal::create(context, false));
}
-PassOwnPtr<GLES2Context> WebViewImpl::getOffscreenGLES2Context()
+SharedGraphicsContext3D* WebViewImpl::getSharedGraphicsContext3D()
{
- WebGLES2Context* context = webKitClient()->createGLES2Context();
- if (!context)
- return 0;
- if (!context->initialize(0, gles2Context()))
- return 0;
- return GLES2Context::create(GLES2ContextInternal::create(context, true));
+ if (!m_sharedContext3D) {
+ GraphicsContext3D::Attributes attr;
+ OwnPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, m_page->chrome());
+ m_sharedContext3D = SharedGraphicsContext3D::create(context.release());
+ }
+
+ return m_sharedContext3D.get();
}
// Returns the GLES2 context associated with this View. If one doesn't exist
diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h
index c296121..a42099c 100644
--- a/WebKit/chromium/src/WebViewImpl.h
+++ b/WebKit/chromium/src/WebViewImpl.h
@@ -324,15 +324,16 @@ public:
#if USE(ACCELERATED_COMPOSITING)
void setRootLayerNeedsDisplay();
void setRootGraphicsLayer(WebCore::PlatformLayer*);
+ bool allowsAcceleratedCompositing();
#endif
// Onscreen contexts display to the screen associated with this view.
// Offscreen contexts render offscreen but can share resources with the
// onscreen context and thus can be composited.
PassOwnPtr<WebCore::GLES2Context> getOnscreenGLES2Context();
- PassOwnPtr<WebCore::GLES2Context> getOffscreenGLES2Context();
// Returns an onscreen context
virtual WebGLES2Context* gles2Context();
+ virtual WebCore::SharedGraphicsContext3D* getSharedGraphicsContext3D();
WebCore::PopupContainer* selectPopup() const { return m_selectPopup.get(); }
@@ -512,6 +513,7 @@ private:
#if USE(ACCELERATED_COMPOSITING)
OwnPtr<WebCore::LayerRendererChromium> m_layerRenderer;
bool m_isAcceleratedCompositingActive;
+ bool m_compositorCreationFailed;
#endif
static const WebInputEvent* m_currentInputEvent;
@@ -521,6 +523,8 @@ private:
OwnPtr<WebGLES2Context> m_gles2Context;
+ RefPtr<WebCore::SharedGraphicsContext3D> m_sharedContext3D;
+
OwnPtr<DeviceOrientationClientProxy> m_deviceOrientationClientProxy;
};
diff --git a/WebKit/chromium/src/js/Tests.js b/WebKit/chromium/src/js/Tests.js
index 41574b4..2233463 100644
--- a/WebKit/chromium/src/js/Tests.js
+++ b/WebKit/chromium/src/js/Tests.js
@@ -219,40 +219,6 @@ TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_st
/**
- * Tests that the real injected host is present in the context.
- */
-TestSuite.prototype.testHostIsPresent = function()
-{
- this.assertTrue(typeof InspectorFrontendHost === "object" && !InspectorFrontendHost.isStub);
-};
-
-
-/**
- * Tests elements tree has an "HTML" root.
- */
-TestSuite.prototype.testElementsTreeRoot = function()
-{
- var doc = WebInspector.domAgent.document;
- this.assertEquals("HTML", doc.documentElement.nodeName);
- this.assertTrue(doc.documentElement.hasChildNodes());
-};
-
-
-/**
- * Tests that main resource is present in the system and that it is
- * the only resource.
- */
-TestSuite.prototype.testMainResource = function()
-{
- var tokens = [];
- var resources = WebInspector.resources;
- for (var id in resources)
- tokens.push(resources[id].lastPathComponent);
- this.assertEquals("simple_page.html", tokens.join(","));
-};
-
-
-/**
* Tests that resources tab is enabled when corresponding item is selected.
*/
TestSuite.prototype.testEnableResourcesTab = function()
@@ -628,71 +594,6 @@ TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function()
};
-/**
- * Tests that a breakpoint can be set.
- */
-TestSuite.prototype.testSetBreakpoint = function()
-{
- var test = this;
- this.showPanel("scripts");
-
- var breakpointLine = 16
-
- this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
- function() {
- test.showMainPageScriptSource_(
- "debugger_test_page.html",
- function(view, url) {
- view._addBreakpoint(breakpointLine);
-
- test.evaluateInConsole_(
- 'setTimeout("calculate()" , 0)',
- function(resultText) {
- test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
- });
- });
- });
-
- this._waitForScriptPause(
- {
- functionsOnStack: ["calculate", ""],
- lineNumber: breakpointLine,
- lineText: " result = fib(lastVal++);"
- },
- function() {
- test.releaseControl();
- });
-
- this.takeControl();
-};
-
-
-/**
- * Tests that pause on exception works.
- */
-TestSuite.prototype.testPauseOnException = function()
-{
- this.showPanel("scripts");
- var test = this;
-
- InspectorBackend.setPauseOnExceptionsState(WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions);
-
- this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html"]);
-
- this._waitForScriptPause(
- {
- functionsOnStack: ["throwAnException", "handleClick", ""],
- lineNumber: 6,
- lineText: " return unknown_var;"
- },
- function() {
- test.releaseControl();
- });
-
- this.takeControl();
-};
-
-
// Tests that debugger works correctly if pause event occurs when DevTools
// frontend is being loaded.
TestSuite.prototype.testPauseWhenLoadingDevTools = function()
@@ -864,54 +765,6 @@ TestSuite.prototype.evaluateInConsole_ = function(code, callback)
/**
- * Tests eval on call frame.
- */
-TestSuite.prototype.testEvalOnCallFrame = function()
-{
- this.showPanel("scripts");
-
- var breakpointLine = 16;
-
- var test = this;
- this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
- function() {
- test.showMainPageScriptSource_(
- "debugger_test_page.html",
- function(view, url) {
- view._addBreakpoint(breakpointLine);
-
- // Since breakpoints are ignored in evals' calculate() function is
- // execute after zero-timeout so that the breakpoint is hit.
- test.evaluateInConsole_(
- 'setTimeout("calculate(123)" , 0)',
- function(resultText) {
- test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
- waitForBreakpointHit();
- });
- });
- });
-
- function waitForBreakpointHit() {
- test.addSniffer(WebInspector,
- "pausedScript",
- function(callFrames) {
- test.assertEquals(2, callFrames.length, "Unexpected stack depth on the breakpoint. " + JSON.stringify(callFrames, null, 4));
- test.assertEquals("calculate", callFrames[0].functionName, "Unexpected top frame function.");
- // Evaluate "e+1" where "e" is an argument of "calculate" function.
- test.evaluateInConsole_(
- "e+1",
- function(resultText) {
- test.assertEquals("124", resultText, 'Unexpected "e+1" value.');
- test.releaseControl();
- });
- });
- }
-
- this.takeControl();
-};
-
-
-/**
* Tests that console auto completion works when script execution is paused.
*/
TestSuite.prototype.testCompletionOnPause = function()
@@ -968,16 +821,6 @@ TestSuite.prototype.testCompletionOnPause = function()
/**
- * Tests that inspected page doesn't hang on reload if it contains a syntax
- * error and DevTools window is open.
- */
-TestSuite.prototype.testAutoContinueOnSyntaxError = function()
-{
- // TODO(yurys): provide an implementation that works with ScriptDebugServer.
-};
-
-
-/**
* Checks current execution line against expectations.
* @param {WebInspector.SourceFrame} sourceFrame
* @param {number} lineNumber Expected line number
@@ -1029,7 +872,8 @@ TestSuite.prototype._waitForScriptPause = function(expectations, callback)
test.addSniffer(
WebInspector,
"pausedScript",
- function(callFrames) {
+ function(details) {
+ var callFrames = details.callFrames;
var functionsOnStack = [];
for (var i = 0; i < callFrames.length; i++)
functionsOnStack.push(callFrames[i].functionName);
@@ -1393,85 +1237,6 @@ TestSuite.createKeyEvent = function(keyIdentifier)
/**
- * Tests the message loop re-entrancy.
- */
-TestSuite.prototype.testMessageLoopReentrant = function()
-{
- var test = this;
- this.showPanel("scripts");
-
- var breakpointLine = 16;
-
- WebInspector.showConsole();
-
- this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
- function() {
- test.showMainPageScriptSource_(
- "debugger_test_page.html",
- function(view, url) {
- view._addBreakpoint(breakpointLine);
-
- test.evaluateInConsole_(
- 'setTimeout("calculate()", 0)',
- function(resultText) {
- test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
- });
-
- });
- });
-
- // Wait until script is paused.
- this.addSniffer(
- WebInspector,
- "pausedScript",
- function(callFrames) {
- test.evaluateInConsole_(
- 'document.cookie',
- test.releaseControl.bind(test)); // This callback will be invoked only if the test succeeds (i.e. no crash).
- });
-
- this.takeControl();
-};
-
-
-/**
- * Tests that Storage panel can be open and that local DOM storage is added
- * to the panel.
- */
-TestSuite.prototype.testShowStoragePanel = function()
-{
- var test = this;
- this.addSniffer(WebInspector.panels.storage, "addDOMStorage",
- function(storage) {
- var orig = storage.getEntries;
- storage.getEntries = function(callback) {
- orig.call(this, function(entries) {
- callback(entries);
- test.releaseControl();
- });
- };
- try {
- WebInspector.currentPanel.selectDOMStorage(storage.id);
- storage.getEntries = orig;
- } catch (e) {
- test.fail("Exception in selectDOMStorage: " + e);
- }
- });
- this.showPanel("storage");
-
- // Access localStorage so that it's pushed to the frontend.
- this.evaluateInConsole_(
- 'setTimeout("localStorage.x = 10" , 0)',
- function(resultText) {
- test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
- });
-
- // Wait until DOM storage is added to the panel.
- this.takeControl();
-};
-
-
-/**
* Test runner for the test suite.
*/
var uiTests = {};
diff --git a/WebKit/chromium/src/js/devTools.css b/WebKit/chromium/src/js/devTools.css
index 9495fb8..9495fb8 100755..100644
--- a/WebKit/chromium/src/js/devTools.css
+++ b/WebKit/chromium/src/js/devTools.css
diff --git a/WebKit/chromium/src/mac/WebInputEventFactory.mm b/WebKit/chromium/src/mac/WebInputEventFactory.mm
index 694155f..b4e09c0 100644
--- a/WebKit/chromium/src/mac/WebInputEventFactory.mm
+++ b/WebKit/chromium/src/mac/WebInputEventFactory.mm
@@ -1178,22 +1178,19 @@ WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(NSEvent* event, NSView*
// the point delta data instead, since we cannot distinguish trackpad data
// from data from any other continuous device.
+ // Conversion between wheel delta amounts and number of pixels to scroll.
+ static const double scrollbarPixelsPerCocoaTick = 40.0;
+
if (CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventIsContinuous)) {
- result.wheelTicksY = result.deltaY =
- CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
- result.wheelTicksX = result.deltaX =
- CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2);
+ result.deltaX = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2);
+ result.deltaY = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
+ result.wheelTicksX = result.deltaX / scrollbarPixelsPerCocoaTick;
+ result.wheelTicksY = result.deltaY / scrollbarPixelsPerCocoaTick;
} else {
- result.wheelTicksY =
- CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventDeltaAxis1);
- result.wheelTicksX =
- CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventDeltaAxis2);
-
- // Convert wheel delta amount to a number of pixels to scroll.
- static const double scrollbarPixelsPerCocoaTick = 40.0;
-
result.deltaX = [event deltaX] * scrollbarPixelsPerCocoaTick;
result.deltaY = [event deltaY] * scrollbarPixelsPerCocoaTick;
+ result.wheelTicksY = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventDeltaAxis1);
+ result.wheelTicksX = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventDeltaAxis2);
}
result.timeStampSeconds = [event timestamp];
diff --git a/WebKit/chromium/src/win/WebInputEventFactory.cpp b/WebKit/chromium/src/win/WebInputEventFactory.cpp
index 4d83f22..d1d5869 100644
--- a/WebKit/chromium/src/win/WebInputEventFactory.cpp
+++ b/WebKit/chromium/src/win/WebInputEventFactory.cpp
@@ -403,6 +403,9 @@ WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(HWND hwnd, UINT message
// smooth scrolling while Firefox doesn't, so it can get away with somewhat
// larger scroll values without feeling as jerky. Here we use 100 px per
// three lines (the default scroll amount is three lines per wheel tick).
+ // Even though we have smooth scrolling, we don't make this as large as IE
+ // because subjectively IE feels like it scrolls farther than you want while
+ // reading articles.
static const float scrollbarPixelsPerLine = 100.0f / 3.0f;
wheelDelta /= WHEEL_DELTA;
float scrollDelta = wheelDelta;
diff --git a/WebKit/chromium/tests/ArenaTestHelpers.h b/WebKit/chromium/tests/ArenaTestHelpers.h
new file mode 100644
index 0000000..87f827d
--- /dev/null
+++ b/WebKit/chromium/tests/ArenaTestHelpers.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ArenaTestHelpers_h
+#define ArenaTestHelpers_h
+
+#include "PODArena.h"
+#include <gtest/gtest.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+namespace ArenaTestHelpers {
+
+// An allocator for the PODArena which tracks the regions which have
+// been allocated.
+class TrackedAllocator : public PODArena::FastMallocAllocator {
+public:
+ static PassRefPtr<TrackedAllocator> create()
+ {
+ return adoptRef(new TrackedAllocator);
+ }
+
+ virtual void* allocate(size_t size)
+ {
+ void* result = PODArena::FastMallocAllocator::allocate(size);
+ m_allocatedRegions.append(result);
+ return result;
+ }
+
+ virtual void free(void* ptr)
+ {
+ size_t slot = m_allocatedRegions.find(ptr);
+ ASSERT_GE(slot, 0);
+ m_allocatedRegions.remove(slot);
+ PODArena::FastMallocAllocator::free(ptr);
+ }
+
+ bool isEmpty() const
+ {
+ return !numRegions();
+ }
+
+ int numRegions() const
+ {
+ return m_allocatedRegions.size();
+ }
+
+private:
+ TrackedAllocator() { }
+ Vector<void*> m_allocatedRegions;
+};
+
+} // namespace ArenaTestHelpers
+} // namespace WebCore
+
+#endif // ArenaTestHelpers_h
diff --git a/WebKit/chromium/tests/PODArenaTest.cpp b/WebKit/chromium/tests/PODArenaTest.cpp
new file mode 100644
index 0000000..c5b1ede
--- /dev/null
+++ b/WebKit/chromium/tests/PODArenaTest.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "PODArena.h"
+
+#include "ArenaTestHelpers.h"
+#include <algorithm>
+#include <gtest/gtest.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+using ArenaTestHelpers::TrackedAllocator;
+
+namespace {
+
+// A couple of simple structs to allocate.
+struct TestClass1 {
+ TestClass1()
+ : x(0), y(0), z(0), w(1) { }
+
+ float x, y, z, w;
+};
+
+struct TestClass2 {
+ TestClass2()
+ : a(1), b(2), c(3), d(4) { }
+
+ float a, b, c, d;
+};
+
+} // anonymous namespace
+
+class PODArenaTest : public testing::Test {
+};
+
+// Make sure the arena can successfully allocate from more than one
+// region.
+TEST_F(PODArenaTest, CanAllocateFromMoreThanOneRegion)
+{
+ RefPtr<TrackedAllocator> allocator = TrackedAllocator::create();
+ RefPtr<PODArena> arena = PODArena::create(allocator);
+ int numIterations = 10 * PODArena::DefaultChunkSize / sizeof(TestClass1);
+ for (int i = 0; i < numIterations; ++i)
+ arena->allocateObject<TestClass1>();
+ EXPECT_GT(allocator->numRegions(), 1);
+}
+
+// Make sure the arena frees all allocated regions during destruction.
+TEST_F(PODArenaTest, FreesAllAllocatedRegions)
+{
+ RefPtr<TrackedAllocator> allocator = TrackedAllocator::create();
+ {
+ RefPtr<PODArena> arena = PODArena::create(allocator);
+ for (int i = 0; i < 3; i++)
+ arena->allocateObject<TestClass1>();
+ EXPECT_GT(allocator->numRegions(), 0);
+ }
+ EXPECT_TRUE(allocator->isEmpty());
+}
+
+// Make sure the arena runs constructors of the objects allocated within.
+TEST_F(PODArenaTest, RunsConstructors)
+{
+ RefPtr<PODArena> arena = PODArena::create();
+ for (int i = 0; i < 10000; i++) {
+ TestClass1* tc1 = arena->allocateObject<TestClass1>();
+ EXPECT_EQ(0, tc1->x);
+ EXPECT_EQ(0, tc1->y);
+ EXPECT_EQ(0, tc1->z);
+ EXPECT_EQ(1, tc1->w);
+ TestClass2* tc2 = arena->allocateObject<TestClass2>();
+ EXPECT_EQ(1, tc2->a);
+ EXPECT_EQ(2, tc2->b);
+ EXPECT_EQ(3, tc2->c);
+ EXPECT_EQ(4, tc2->d);
+ }
+}
+
+} // namespace WebCore
diff --git a/WebKit/chromium/tests/PODIntervalTreeTest.cpp b/WebKit/chromium/tests/PODIntervalTreeTest.cpp
new file mode 100644
index 0000000..3a8a245
--- /dev/null
+++ b/WebKit/chromium/tests/PODIntervalTreeTest.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Tests for the interval tree class.
+
+#include "config.h"
+
+#include "PODIntervalTree.h"
+
+#include "Logging.h"
+#include "TreeTestHelpers.h"
+#include <gtest/gtest.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+using TreeTestHelpers::generateSeed;
+using TreeTestHelpers::initRandom;
+using TreeTestHelpers::nextRandom;
+
+inline String valueToString(const float& value)
+{
+ return String::number(value);
+}
+
+inline String valueToString(void* const& value)
+{
+ return String::format("0x%p", value);
+}
+
+TEST(PODIntervalTreeTest, TestInsertion)
+{
+ PODIntervalTree<float> tree;
+ tree.add(PODInterval<float>(2, 4));
+ ASSERT_TRUE(tree.checkInvariants());
+}
+
+TEST(PODIntervalTreeTest, TestInsertionAndQuery)
+{
+ PODIntervalTree<float> tree;
+ tree.add(PODInterval<float>(2, 4));
+ ASSERT_TRUE(tree.checkInvariants());
+ Vector<PODInterval<float> > result = tree.allOverlaps(PODInterval<float>(1, 3));
+ EXPECT_EQ(1U, result.size());
+ EXPECT_EQ(2, result[0].low());
+ EXPECT_EQ(4, result[0].high());
+}
+
+TEST(PODIntervalTreeTest, TestQueryAgainstZeroSizeInterval)
+{
+ PODIntervalTree<float> tree;
+ tree.add(PODInterval<float>(1, 2.5));
+ tree.add(PODInterval<float>(3.5, 5));
+ tree.add(PODInterval<float>(2, 4));
+ ASSERT_TRUE(tree.checkInvariants());
+ Vector<PODInterval<float> > result = tree.allOverlaps(PODInterval<float>(3, 3));
+ EXPECT_EQ(1U, result.size());
+ EXPECT_EQ(2, result[0].low());
+ EXPECT_EQ(4, result[0].high());
+}
+
+TEST(PODIntervalTreeTest, TestDuplicateElementInsertion)
+{
+ PODIntervalTree<float, int*> tree;
+ int tmp1 = 1;
+ int tmp2 = 2;
+ typedef PODIntervalTree<float, int*>::IntervalType IntervalType;
+ IntervalType interval1(1, 3, &tmp1);
+ IntervalType interval2(1, 3, &tmp2);
+ tree.add(interval1);
+ tree.add(interval2);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(interval1));
+ EXPECT_TRUE(tree.contains(interval2));
+ EXPECT_TRUE(tree.remove(interval1));
+ EXPECT_TRUE(tree.contains(interval2));
+ EXPECT_FALSE(tree.contains(interval1));
+ EXPECT_TRUE(tree.remove(interval2));
+ EXPECT_EQ(0, tree.size());
+}
+
+namespace {
+
+struct UserData1 {
+public:
+ UserData1()
+ : a(0), b(1) { }
+
+ float a;
+ int b;
+};
+
+inline String valueToString(const UserData1& value)
+{
+ return String("[UserData1 a=") + String::number(value.a) + " b=" + String::number(value.b) + "]";
+}
+
+} // anonymous namespace
+
+TEST(PODIntervalTreeTest, TestInsertionOfComplexUserData)
+{
+ PODIntervalTree<float, UserData1> tree;
+ UserData1 data1;
+ data1.a = 5;
+ data1.b = 6;
+ tree.add(tree.createInterval(2, 4, data1));
+ ASSERT_TRUE(tree.checkInvariants());
+}
+
+TEST(PODIntervalTreeTest, TestQueryingOfComplexUserData)
+{
+ PODIntervalTree<float, UserData1> tree;
+ UserData1 data1;
+ data1.a = 5;
+ data1.b = 6;
+ tree.add(tree.createInterval(2, 4, data1));
+ ASSERT_TRUE(tree.checkInvariants());
+ Vector<PODInterval<float, UserData1> > overlaps = tree.allOverlaps(tree.createInterval(3, 5, data1));
+ EXPECT_EQ(1U, overlaps.size());
+ EXPECT_EQ(5, overlaps[0].data().a);
+ EXPECT_EQ(6, overlaps[0].data().b);
+}
+
+namespace {
+
+class EndpointType1 {
+public:
+ explicit EndpointType1(int value)
+ : m_value(value) { }
+
+ int value() const { return m_value; }
+
+ bool operator<(const EndpointType1& other) const { return m_value < other.m_value; }
+ bool operator==(const EndpointType1& other) const { return m_value == other.m_value; }
+
+private:
+ int m_value;
+ // These operators should not be called by the interval tree.
+ bool operator>(const EndpointType1& other);
+ bool operator<=(const EndpointType1& other);
+ bool operator>=(const EndpointType1& other);
+ bool operator!=(const EndpointType1& other);
+};
+
+inline String valueToString(const EndpointType1& value)
+{
+ return String("[EndpointType1 value=") + String::number(value.value()) + "]";
+}
+
+} // anonymous namespace
+
+TEST(PODIntervalTreeTest, TestTreeDoesNotRequireMostOperators)
+{
+ PODIntervalTree<EndpointType1> tree;
+ tree.add(tree.createInterval(EndpointType1(1), EndpointType1(2)));
+ ASSERT_TRUE(tree.checkInvariants());
+}
+
+// Uncomment to debug a failure of the insertion and deletion test.
+// #define DEBUG_INSERTION_AND_DELETION_TEST
+
+namespace {
+
+void InsertionAndDeletionTest(int32_t seed, int treeSize)
+{
+ initRandom(seed);
+ int maximumValue = treeSize;
+ // Build the tree
+ PODIntervalTree<int> tree;
+ Vector<PODInterval<int> > addedElements;
+ Vector<PODInterval<int> > removedElements;
+ for (int i = 0; i < treeSize; i++) {
+ int left = nextRandom(maximumValue);
+ int length = nextRandom(maximumValue);
+ PODInterval<int> interval(left, left + length);
+ tree.add(interval);
+#ifdef DEBUG_INSERTION_AND_DELETION_TEST
+ LOG_ERROR("*** Adding element %s", valueToString(interval).ascii().data());
+#endif
+ addedElements.append(interval);
+ }
+ // Churn the tree's contents.
+ // First remove half of the elements in random order.
+ for (int i = 0; i < treeSize / 2; i++) {
+ int index = nextRandom(addedElements.size());
+#ifdef DEBUG_INSERTION_AND_DELETION_TEST
+ LOG_ERROR("*** Removing element %s", valueToString(addedElements[index]).ascii().data());
+#endif
+ ASSERT_TRUE(tree.contains(addedElements[index])) << "Test failed for seed " << seed;
+ tree.remove(addedElements[index]);
+ removedElements.append(addedElements[index]);
+ addedElements.remove(index);
+ ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
+ }
+ // Now randomly add or remove elements.
+ for (int i = 0; i < 2 * treeSize; i++) {
+ bool add = false;
+ if (!addedElements.size())
+ add = true;
+ else if (!removedElements.size())
+ add = false;
+ else
+ add = (nextRandom(2) == 1);
+ if (add) {
+ int index = nextRandom(removedElements.size());
+#ifdef DEBUG_INSERTION_AND_DELETION_TEST
+ LOG_ERROR("*** Adding element %s", valueToString(removedElements[index]).ascii().data());
+#endif
+ tree.add(removedElements[index]);
+ addedElements.append(removedElements[index]);
+ removedElements.remove(index);
+ } else {
+ int index = nextRandom(addedElements.size());
+#ifdef DEBUG_INSERTION_AND_DELETION_TEST
+ LOG_ERROR("*** Removing element %s", valueToString(addedElements[index]).ascii().data());
+#endif
+ ASSERT_TRUE(tree.contains(addedElements[index])) << "Test failed for seed " << seed;
+ ASSERT_TRUE(tree.remove(addedElements[index])) << "Test failed for seed " << seed;
+ removedElements.append(addedElements[index]);
+ addedElements.remove(index);
+ }
+ ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
+ }
+}
+
+} // anonymous namespace
+
+TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest1)
+{
+ InsertionAndDeletionTest(13972, 100);
+}
+
+TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest2)
+{
+ InsertionAndDeletionTest(1283382113, 10);
+}
+
+TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest3)
+{
+ // This is the sequence of insertions and deletions that triggered
+ // the failure in RandomDeletionAndInsertionRegressionTest2.
+ PODIntervalTree<int> tree;
+ tree.add(tree.createInterval(0, 5));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(4, 5));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(8, 9));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(1, 4));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(3, 5));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(4, 12));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(0, 2));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(0, 2));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(9, 13));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(0, 1));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(0, 2));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(9, 13));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(0, 2));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(0, 1));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(4, 5));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(4, 12));
+ ASSERT_TRUE(tree.checkInvariants());
+}
+
+TEST(PODIntervalTreeTest, RandomDeletionAndInsertionRegressionTest4)
+{
+ // Even further reduced test case for RandomDeletionAndInsertionRegressionTest3.
+ PODIntervalTree<int> tree;
+ tree.add(tree.createInterval(0, 5));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(8, 9));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(1, 4));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(3, 5));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(tree.createInterval(4, 12));
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(tree.createInterval(4, 12));
+ ASSERT_TRUE(tree.checkInvariants());
+}
+
+TEST(PODIntervalTreeTest, TestRandomDeletionAndInsertion)
+{
+ InsertionAndDeletionTest(generateSeed(), 1000);
+}
+
+} // namespace WebCore
diff --git a/WebKit/chromium/tests/PODRedBlackTreeTest.cpp b/WebKit/chromium/tests/PODRedBlackTreeTest.cpp
new file mode 100644
index 0000000..0cc10e7
--- /dev/null
+++ b/WebKit/chromium/tests/PODRedBlackTreeTest.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Tests for the red-black tree class.
+
+#include "config.h"
+
+#include "PODRedBlackTree.h"
+
+#include "ArenaTestHelpers.h"
+#include "TreeTestHelpers.h"
+#include <gtest/gtest.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+using ArenaTestHelpers::TrackedAllocator;
+using TreeTestHelpers::generateSeed;
+using TreeTestHelpers::initRandom;
+using TreeTestHelpers::nextRandom;
+
+TEST(PODRedBlackTreeTest, TestTreeAllocatesFromArena)
+{
+ RefPtr<TrackedAllocator> allocator = TrackedAllocator::create();
+ {
+ RefPtr<PODArena> arena = PODArena::create(allocator);
+ PODRedBlackTree<int> tree(arena);
+ int numAdditions = 2 * PODArena::DefaultChunkSize / sizeof(int);
+ for (int i = 0; i < numAdditions; ++i)
+ tree.add(i);
+ EXPECT_GT(allocator->numRegions(), 1);
+ }
+ EXPECT_EQ(allocator->numRegions(), 0);
+}
+
+TEST(PODRedBlackTreeTest, TestSingleElementInsertion)
+{
+ PODRedBlackTree<int> tree;
+ tree.add(5);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(5));
+}
+
+TEST(PODRedBlackTreeTest, TestMultipleElementInsertion)
+{
+ PODRedBlackTree<int> tree;
+ tree.add(4);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(4));
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(3));
+ tree.add(5);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(5));
+ EXPECT_TRUE(tree.contains(4));
+ EXPECT_TRUE(tree.contains(3));
+}
+
+TEST(PODRedBlackTreeTest, TestDuplicateElementInsertion)
+{
+ PODRedBlackTree<int> tree;
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_EQ(3, tree.size());
+ EXPECT_TRUE(tree.contains(3));
+}
+
+TEST(PODRedBlackTreeTest, TestSingleElementInsertionAndDeletion)
+{
+ PODRedBlackTree<int> tree;
+ tree.add(5);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(5));
+ tree.remove(5);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_FALSE(tree.contains(5));
+}
+
+TEST(PODRedBlackTreeTest, TestMultipleElementInsertionAndDeletion)
+{
+ PODRedBlackTree<int> tree;
+ tree.add(4);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(4));
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(3));
+ tree.add(5);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(5));
+ EXPECT_TRUE(tree.contains(4));
+ EXPECT_TRUE(tree.contains(3));
+ tree.remove(4);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(3));
+ EXPECT_FALSE(tree.contains(4));
+ EXPECT_TRUE(tree.contains(5));
+ tree.remove(5);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_TRUE(tree.contains(3));
+ EXPECT_FALSE(tree.contains(4));
+ EXPECT_FALSE(tree.contains(5));
+ EXPECT_EQ(1, tree.size());
+}
+
+TEST(PODRedBlackTreeTest, TestDuplicateElementInsertionAndDeletion)
+{
+ PODRedBlackTree<int> tree;
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_EQ(3, tree.size());
+ EXPECT_TRUE(tree.contains(3));
+ tree.remove(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.remove(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_EQ(1, tree.size());
+ EXPECT_TRUE(tree.contains(3));
+ tree.remove(3);
+ ASSERT_TRUE(tree.checkInvariants());
+ EXPECT_EQ(0, tree.size());
+ EXPECT_FALSE(tree.contains(3));
+}
+
+TEST(PODRedBlackTreeTest, FailingInsertionRegressionTest1)
+{
+ // These numbers came from a previously-failing randomized test run.
+ PODRedBlackTree<int> tree;
+ tree.add(5113);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(4517);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(3373);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(9307);
+ ASSERT_TRUE(tree.checkInvariants());
+ tree.add(7077);
+ ASSERT_TRUE(tree.checkInvariants());
+}
+
+namespace {
+void InsertionAndDeletionTest(const int32_t seed, const int treeSize)
+{
+ initRandom(seed);
+ const int maximumValue = treeSize;
+ // Build the tree.
+ PODRedBlackTree<int> tree;
+ Vector<int> values;
+ for (int i = 0; i < treeSize; i++) {
+ int value = nextRandom(maximumValue);
+ tree.add(value);
+ ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
+ values.append(value);
+ }
+ // Churn the tree's contents.
+ for (int i = 0; i < treeSize; i++) {
+ // Pick a random value to remove.
+ int index = nextRandom(treeSize);
+ int value = values[index];
+ // Remove this value.
+ tree.remove(value);
+ ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
+ // Replace it with a new one.
+ value = nextRandom(maximumValue);
+ values[index] = value;
+ tree.add(value);
+ ASSERT_TRUE(tree.checkInvariants()) << "Test failed for seed " << seed;
+ }
+}
+} // anonymous namespace
+
+TEST(PODRedBlackTreeTest, RandomDeletionAndInsertionRegressionTest1)
+{
+ InsertionAndDeletionTest(12311, 100);
+}
+
+TEST(PODRedBlackTreeTest, TestRandomDeletionAndInsertion)
+{
+ InsertionAndDeletionTest(generateSeed(), 100);
+}
+
+} // namespace WebCore
diff --git a/WebKit/chromium/tests/TreeTestHelpers.cpp b/WebKit/chromium/tests/TreeTestHelpers.cpp
new file mode 100644
index 0000000..103b871
--- /dev/null
+++ b/WebKit/chromium/tests/TreeTestHelpers.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "TreeTestHelpers.h"
+
+#include <cstdlib>
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+namespace TreeTestHelpers {
+
+int32_t generateSeed()
+{
+ // A seed of 1 has the special behavior of resetting the random
+ // number generator. Assume that if we call this routine that we
+ // don't want this behavior.
+ int32_t seed;
+ do {
+ seed = static_cast<int32_t>(currentTime());
+ } while (seed <= 1);
+ return seed;
+}
+
+void initRandom(const int32_t seed)
+{
+ srand(seed);
+}
+
+int32_t nextRandom(const int32_t maximumValue)
+{
+ // rand_r is not available on Windows
+ return rand() % maximumValue;
+}
+
+} // namespace TreeTestHelpers
+} // namespace WebCore
diff --git a/WebKit/chromium/tests/TreeTestHelpers.h b/WebKit/chromium/tests/TreeTestHelpers.h
new file mode 100644
index 0000000..af07b2a
--- /dev/null
+++ b/WebKit/chromium/tests/TreeTestHelpers.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple pseudorandom number generator helper functions, used by the
+// red-black and interval tree tests.
+//
+// These are **not** thread safe!
+
+#ifndef TreeTestHelpers_h
+#define TreeTestHelpers_h
+
+#include <stdint.h>
+
+namespace WebCore {
+namespace TreeTestHelpers {
+
+// Generates a seed value to be passed to initRandom().
+int32_t generateSeed();
+
+// Initializes the pseudo-random number generator with a specific seed.
+void initRandom(const int32_t seed);
+
+// Produces the next pseudo-random number in the sequence, in the
+// range from [0..maximumValue). Negative numbers are not allowed and will
+// produce undefined results.
+int32_t nextRandom(const int32_t maximumValue);
+
+} // namespace TreeTestHelpers
+} // namespace WebCore
+
+#endif // TreeTestHelpers_h
diff --git a/WebKit/efl/CMakeListsEfl.txt b/WebKit/efl/CMakeListsEfl.txt
index 7b5865b..2ea5ee5 100644
--- a/WebKit/efl/CMakeListsEfl.txt
+++ b/WebKit/efl/CMakeListsEfl.txt
@@ -24,10 +24,10 @@ LIST(APPEND WebKit_INCLUDE_DIRECTORIES
IF (ENABLE_VIDEO)
LIST(APPEND WebKit_INCLUDE_DIRECTORIES
"${WEBCORE_DIR}/platform/graphics/gstreamer"
- ${Gstreamer-App_INCLUDE_DIRS}
- ${Gstreamer-Interfaces_INCLUDE_DIRS}
- ${Gstreamer-Pbutils_INCLUDE_DIRS}
- ${Gstreamer-Video_INCLUDE_DIRS}
+ ${GStreamer-App_INCLUDE_DIRS}
+ ${GStreamer-Interfaces_INCLUDE_DIRS}
+ ${GStreamer-Pbutils_INCLUDE_DIRS}
+ ${GStreamer-Video_INCLUDE_DIRS}
)
ENDIF()
@@ -70,6 +70,7 @@ IF (ENABLE_GLIB_SUPPORT)
LIST(APPEND WebKit_INCLUDE_DIRECTORIES
${Gdk_INCLUDE_DIRS}
${Glib_INCLUDE_DIRS}
+ ${JAVASCRIPTCORE_DIR}/wtf/gobject
)
LIST(APPEND WebKit_LIBRARIES
${Glib_LIBRARIES}
@@ -158,54 +159,10 @@ ADD_CUSTOM_COMMAND(
VERBATIM
)
-SET(EWebLauncher_SOURCES
- efl/DefaultTheme/default.edj
- efl/EWebLauncher/main.c
-)
-
-SET(EWebLauncher_LIBRARIES
- ${JavaScriptCore_LIBRARY_NAME}
- ${WebCore_LIBRARY_NAME}
- ${WebKit_LIBRARY_NAME}
- ${Cairo_LIBRARIES}
- ${ECORE_X_LIBRARIES}
- ${EDJE_LIBRARIES}
- ${EFLDEPS_LIBRARIES}
- ${EVAS_LIBRARIES}
- ${LIBXML2_LIBRARIES}
- ${LIBXSLT_LIBRARIES}
- ${SQLITE_LIBRARIES}
-)
-
-SET(EWebLauncher_LINK_FLAGS
- ${ECORE_X_LDFLAGS}
- ${EDJE_LDFLAGS}
- ${EFLDEPS_LDFLAGS}
- ${EVAS_LDFLAGS}
+LIST(APPEND WebKit_SOURCES
+ ${WebKit_THEME}
)
-IF (ENABLE_GLIB_SUPPORT)
- LIST(APPEND EWebLauncher_LIBRARIES
- ${Gdk_LIBRARIES}
- ${Glib_LIBRARIES}
- ${Gthread_LIBRARIES}
- )
-ENDIF ()
-
-IF (WTF_USE_SOUP)
- LIST(APPEND EWebLauncher_LIBRARIES ${LIBSOUP24_LIBRARIES})
- LIST(APPEND EWebLauncher_LINK_FLAGS ${LIBSOUP24_LDFLAGS})
-ENDIF ()
-
-IF (WTF_USE_CURL)
- LIST(APPEND EWebLauncher_LIBRARIES ${CURL_LIBRARIES})
- LIST(APPEND EWebLauncher_LINK_FLAGS ${CURL_LDFLAGS})
-ENDIF ()
-
-ADD_EXECUTABLE(../Programs/EWebLauncher ${EWebLauncher_SOURCES})
-TARGET_LINK_LIBRARIES(../Programs/EWebLauncher ${EWebLauncher_LIBRARIES})
-ADD_TARGET_PROPERTIES(../Programs/EWebLauncher LINK_FLAGS "${EWebLauncher_LINK_FLAGS}")
-
IF (SHARED_CORE)
SET(LIBS_PRIVATE "-l${WTF_LIBRARY_NAME} -l${JavaScriptCore_LIBRARY_NAME} -l${WebCore_LIBRARY_NAME}")
ELSE ()
@@ -225,4 +182,7 @@ FILE(GLOB EWebKit_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/efl/ewk/*.h")
LIST(REMOVE_ITEM EWebKit_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/efl/ewk/ewk_private.h")
INSTALL(FILES ${EWebKit_HEADERS}
- DESTINATION include/EWebKit)
+ DESTINATION include/${WebKit_LIBRARY_NAME}-${PROJECT_VERSION_MAJOR})
+
+INSTALL(FILES ${WebKit_THEME}
+ DESTINATION share/${WebKit_LIBRARY_NAME}-${PROJECT_VERSION_MAJOR}/themes)
diff --git a/WebKit/efl/ChangeLog b/WebKit/efl/ChangeLog
index bafa48d..e805d2c 100644
--- a/WebKit/efl/ChangeLog
+++ b/WebKit/efl/ChangeLog
@@ -1,3 +1,138 @@
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * ewk/ewk_frame.cpp:
+ (ewk_frame_editable_set):
+ (ewk_frame_selection_get):
+ (ewk_frame_text_search):
+ (ewk_frame_text_matches_mark):
+ (ewk_frame_text_matches_highlight_set):
+ (ewk_frame_text_matches_highlight_get):
+ * ewk/ewk_view.cpp:
+ (ewk_view_selection_get):
+ Changed call sites to use editor().
+
+2010-09-09 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ Unreviewed build fix.
+
+ [EFL] Fix duplicate gstreamer macro in CMakeListEfl.txt
+ https://bugs.webkit.org/show_bug.cgi?id=45433
+
+ In WebKit/efl/CMakeListEfl.txt, duplicated ENABLE_VIDEO macros were added.
+ So, unnecessary ENABLE_VIDEO macro is deleted.
+
+ * CMakeListsEfl.txt:
+
+2010-09-08 Ryuan Choi <ryuan.choi@samsung.com>
+
+ Unreviewed build fix.
+
+ [EFL] Need to add custom dependencies.
+ https://bugs.webkit.org/show_bug.cgi?id=45247
+
+ Add WebKit_Theme into WebKit_SOURCES to make it while building.
+
+ * CMakeListsEfl.txt:
+
+2010-09-08 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [EFL] Export data directory through pkg-config
+ https://bugs.webkit.org/show_bug.cgi?id=45385
+
+ Using pkg-config it's possible for a browser to know the location of
+ installed themes. When compiling the browser, a variable might be
+ defined with the datadir, like below:
+
+ gcc -o browser browser.c $(pkg-config --libs --cflags ewebkit) \
+ -DEWEBKIT_DATA_DIR=$(pkg-config --variable=datadir)
+
+ * ewebkit.pc.in: Export datadir variable.
+
+2010-09-06 Ryuan Choi <ryuan.choi@samsung.com>
+
+ Unreviewed build fix.
+
+ [EFL] REGRESSION(66794) Need to fix build break.
+ https://bugs.webkit.org/show_bug.cgi?id=45241
+
+ Add dummy class(FrameNetworkingContextEfl) like GTK+ port and implement
+ as EFL style.
+
+ * WebCoreSupport/FrameLoaderClientEfl.cpp:
+ (WebCore::FrameLoaderClientEfl::createNetworkingContext):
+ * WebCoreSupport/FrameNetworkingContextEfl.h: Added.
+ (WebCore::FrameNetworkingContextEfl::create):
+ (WebCore::FrameNetworkingContextEfl::coreFrame):
+ (WebCore::FrameNetworkingContextEfl::FrameNetworkingContextEfl):
+
+2010-09-04 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [EFL] Move test browser to WebKitTools directory
+ https://bugs.webkit.org/show_bug.cgi?id=45212
+
+ Follow other ports like QT and GTK which moved the test browser to
+ WebKitTools directory.
+
+ * CMakeListsEfl.txt: Remove build for test browser.
+ * EWebLauncher/main.c: Removed.
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Add createNetworkingContext to EFL's FrameLoaderClient.
+
+ * WebCoreSupport/FrameLoaderClientEfl.cpp:
+ (WebCore::FrameLoaderClientEfl::createNetworkingContext):
+ * WebCoreSupport/FrameLoaderClientEfl.h:
+
+2010-09-03 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Martin Robinson.
+
+ [EFL] Regression (66531) Build break with Glib Support
+ https://bugs.webkit.org/show_bug.cgi?id=45011
+
+ Move GtkTypedefs.h to GTypedefs.h and let it inside gobject directory
+ since when glib is enabled, EFL port needs it, too.
+
+ * CMakeListsEfl.txt: Include gobject directory to find new header
+ file.
+
+2010-09-03 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Antonio Gomes.
+
+ [EFL] Install default theme
+ https://bugs.webkit.org/show_bug.cgi?id=45154
+
+ Since a theme is needed in order to create a new browser, install the
+ default one to serve as example and fall-back.
+
+ * CMakeListsEfl.txt:
+
+2010-09-02 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Antonio Gomes.
+
+ [EFL] Name install directories according to library name
+ https://bugs.webkit.org/show_bug.cgi?id=45126
+
+ * CMakeListsEfl.txt: include diretory follows library name.
+ * ewebkit.pc.in: Ditto.
+
2010-08-31 Dave Hyatt <hyatt@apple.com>
Reviewed by Sam Weinig.
diff --git a/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp b/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp
index 499d6c2..8ec783a 100644
--- a/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp
+++ b/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp
@@ -39,6 +39,7 @@
#include "EWebKit.h"
#include "FormState.h"
#include "FrameLoader.h"
+#include "FrameNetworkingContextEfl.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLFormElement.h"
@@ -945,4 +946,9 @@ void FrameLoaderClientEfl::transitionToCommittedForNewPage()
ewk_view_frame_main_cleared(m_view);
}
+PassRefPtr<FrameNetworkingContext> FrameLoaderClientEfl::createNetworkingContext()
+{
+ return FrameNetworkingContextEfl::create(ewk_frame_core_get(m_frame));
+}
+
}
diff --git a/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h b/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h
index 561760c..bd105cd 100644
--- a/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h
+++ b/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h
@@ -202,6 +202,8 @@ class FrameLoaderClientEfl : public FrameLoaderClient {
virtual bool canCachePage() const;
virtual void download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&);
+
+ virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext();
private:
Evas_Object *m_view;
Evas_Object *m_frame;
diff --git a/WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h b/WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h
new file mode 100644
index 0000000..4e67512
--- /dev/null
+++ b/WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2010 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 FrameNetworkingContextEfl_h
+#define FrameNetworkingContextEfl_h
+
+#include "FrameNetworkingContext.h"
+
+namespace WebCore {
+
+class FrameNetworkingContextEfl : public WebCore::FrameNetworkingContext {
+public:
+ static PassRefPtr<FrameNetworkingContextEfl> create(WebCore::Frame* frame)
+ {
+ return adoptRef(new FrameNetworkingContextEfl(frame));
+ }
+
+ WebCore::Frame* coreFrame() const { return frame(); }
+
+private:
+ FrameNetworkingContextEfl(WebCore::Frame* frame)
+ : WebCore::FrameNetworkingContext(frame)
+ {
+ }
+};
+
+}
+
+#endif
diff --git a/WebKit/efl/ewebkit.pc.in b/WebKit/efl/ewebkit.pc.in
index d618e30..3a1c8f5 100644
--- a/WebKit/efl/ewebkit.pc.in
+++ b/WebKit/efl/ewebkit.pc.in
@@ -2,6 +2,7 @@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
+datadir=${prefix}/share/@WebKit_LIBRARY_NAME@-@PROJECT_VERSION_MAJOR@
Name: WebKit-EFL
Description: Web content engine for EFL applications
@@ -9,4 +10,4 @@ Version: @PROJECT_VERSION@
Requires: cairo evas ecore
Libs: -L${libdir} -lewebkit @EXTRA_EWEBKIT_LINK@
Libs.private: @LIBS_PRIVATE@
-Cflags: -I${includedir}/EWebKit
+Cflags: -I${includedir}/@WebKit_LIBRARY_NAME@-@PROJECT_VERSION_MAJOR@
diff --git a/WebKit/efl/ewk/ewk_frame.cpp b/WebKit/efl/ewk/ewk_frame.cpp
index a7ce1ff..8945ee7 100644
--- a/WebKit/efl/ewk/ewk_frame.cpp
+++ b/WebKit/efl/ewk/ewk_frame.cpp
@@ -636,7 +636,7 @@ Eina_Bool ewk_frame_editable_set(Evas_Object* o, Eina_Bool editable)
if (sd->editable == editable)
return EINA_TRUE;
if (editable)
- sd->frame->applyEditingStyleToBodyElement();
+ sd->frame->editor()->applyEditingStyleToBodyElement();
return EINA_TRUE;
}
@@ -651,7 +651,7 @@ char* ewk_frame_selection_get(const Evas_Object* o)
{
EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0);
- WTF::CString s = sd->frame->selectedText().utf8();
+ WTF::CString s = sd->frame->editor()->selectedText().utf8();
if (s.isNull())
return 0;
return strdup(s.data());
@@ -751,7 +751,7 @@ Eina_Bool ewk_frame_text_search(const Evas_Object* o, const char* string, Eina_B
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
- return sd->frame->findString(WTF::String::fromUTF8(string), forward, case_sensitive, wrap, true);
+ return sd->frame->editor()->findString(WTF::String::fromUTF8(string), forward, case_sensitive, wrap, true);
}
/**
@@ -771,8 +771,8 @@ unsigned int ewk_frame_text_matches_mark(Evas_Object* o, const char* string, Ein
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
- sd->frame->setMarkedTextMatchesAreHighlighted(highlight);
- return sd->frame->countMatchesForText(WTF::String::fromUTF8(string), case_sensitive, limit, true);
+ sd->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
+ return sd->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), case_sensitive, limit, true);
}
/**
@@ -803,7 +803,7 @@ Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* o, Eina_Bool highlig
{
EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
- sd->frame->setMarkedTextMatchesAreHighlighted(highlight);
+ sd->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
return EINA_TRUE;
}
@@ -818,7 +818,7 @@ Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* o)
{
EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
- return sd->frame->markedTextMatchesAreHighlighted();
+ return sd->frame->editor()->markedTextMatchesAreHighlighted();
}
/**
diff --git a/WebKit/efl/ewk/ewk_view.cpp b/WebKit/efl/ewk/ewk_view.cpp
index ea54167..254fdfd 100644
--- a/WebKit/efl/ewk/ewk_view.cpp
+++ b/WebKit/efl/ewk/ewk_view.cpp
@@ -1445,7 +1445,7 @@ char* ewk_view_selection_get(const Evas_Object* o)
{
EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
- WTF::CString s = priv->page->focusController()->focusedOrMainFrame()->selectedText().utf8();
+ WTF::CString s = priv->page->focusController()->focusedOrMainFrame()->editor()->selectedText().utf8();
if (s.isNull())
return 0;
return strdup(s.data());
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog
index 8098b7f..25fe4fd 100644
--- a/WebKit/gtk/ChangeLog
+++ b/WebKit/gtk/ChangeLog
@@ -1,3 +1,90 @@
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * webkit/webkitwebview.cpp:
+ (webkit_web_view_set_highlight_text_matches):
+ (webkit_web_view_get_selected_text):
+ (webkit_web_view_set_editable):
+ Changed call sites to use editor().
+
+2010-09-09 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [GTK] testmimehandling falsely succeeds testing Ogg mime type
+ https://bugs.webkit.org/show_bug.cgi?id=45349
+
+ Make this actually test an ogg file request instead of pdf and
+ changed the expected result to match libsoup content-sniffing
+ result in the case of ogg/vorbis file.
+
+ * tests/testmimehandling.c:
+ (mime_type_policy_decision_requested_cb):
+ (test_mime_ogg):
+
+2010-09-08 Mario Sanchez Prada <msanchez@igalia.com>
+
+ Reviewed by Martin Robinson.
+
+ [Gtk] A list item's number/bullet should not be a child of that list item
+ https://bugs.webkit.org/show_bug.cgi?id=45190
+
+ New unit test added.
+
+ * tests/testatk.c:
+ (testWebkitAtkListsOfItems): New test to check ordered/unordered
+ list of items are properly exposed to AT technologies.
+ (main):
+
+2010-09-07 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Fix some feature guards
+ https://bugs.webkit.org/show_bug.cgi?id=45302
+
+ * webkit/webkitprivate.h: Add ENABLE(VIDEO) guards for video specific members.
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Add GTK's specific implementation of FrameNetworkingContext.
+
+ * WebCoreSupport/FrameLoaderClientGtk.cpp:
+ (WebKit::FrameLoaderClient::createNetworkingContext):
+ * WebCoreSupport/FrameLoaderClientGtk.h:
+
+2010-09-03 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Gustavo Noronha.
+
+ Dialog separators are gone in GTK+ 3.x.
+
+ * webkit/webkitsoupauthdialog.c:
+ (show_auth_dialog):
+
+2010-09-02 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ REGRESSION: Crash occurs at objc_msgSend when closing a window that is displaying the web inspector
+ https://bugs.webkit.org/show_bug.cgi?id=44230
+
+ * WebCoreSupport/InspectorClientGtk.cpp:
+ (WebKit::notifyWebViewDestroyed):
+ (WebKit::InspectorFrontendClient::destroyInspectorWindow):
+ (WebKit::InspectorFrontendClient::closeWindow):
+ (WebKit::InspectorFrontendClient::disconnectFromBackend):
+ * WebCoreSupport/InspectorClientGtk.h:
+
2010-08-31 Dave Hyatt <hyatt@apple.com>
Reviewed by Sam Weinig.
diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
index 2cf4f36..4b0da3d 100644
--- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
+++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
@@ -32,6 +32,7 @@
#include "DocumentLoaderGtk.h"
#include "FormState.h"
#include "FrameLoader.h"
+#include "FrameNetworkingContextGtk.h"
#include "FrameView.h"
#include "FrameTree.h"
#include "GOwnPtr.h"
@@ -1193,4 +1194,9 @@ void FrameLoaderClient::transitionToCommittedForNewPage()
postCommitFrameViewSetup(m_frame, frame->view(), true);
}
+PassRefPtr<FrameNetworkingContext> FrameLoaderClient::createNetworkingContext()
+{
+ return FrameNetworkingContextGtk::create(core(m_frame));
+}
+
}
diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h
index 33e9ee5..753576b 100644
--- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h
+++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h
@@ -181,6 +181,9 @@ namespace WebKit {
virtual bool canCachePage() const;
virtual void download(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
+ virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext();
+
private:
WebKitWebFrame* m_frame;
WebCore::ResourceResponse m_response;
diff --git a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp
index aedf21f..c8b42d7 100644
--- a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp
+++ b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp
@@ -36,7 +36,7 @@ namespace WebKit {
static void notifyWebViewDestroyed(WebKitWebView* webView, InspectorFrontendClient* inspectorFrontendClient)
{
- inspectorFrontendClient->destroyInspectorWindow();
+ inspectorFrontendClient->destroyInspectorWindow(true);
}
InspectorClient::InspectorClient(WebKitWebView* webView)
@@ -274,7 +274,7 @@ InspectorFrontendClient::~InspectorFrontendClient()
ASSERT(!m_webInspector);
}
-void InspectorFrontendClient::destroyInspectorWindow()
+void InspectorFrontendClient::destroyInspectorWindow(bool notifyInspectorController)
{
if (!m_webInspector)
return;
@@ -284,7 +284,8 @@ void InspectorFrontendClient::destroyInspectorWindow()
g_signal_handlers_disconnect_by_func(m_inspectorWebView, (gpointer)notifyWebViewDestroyed, (gpointer)this);
m_inspectorWebView = 0;
- core(m_inspectedWebView)->inspectorController()->disconnectFrontend();
+ if (notifyInspectorController)
+ core(m_inspectedWebView)->inspectorController()->disconnectFrontend();
if (m_inspectorClient)
m_inspectorClient->releaseFrontendPage();
@@ -326,7 +327,12 @@ void InspectorFrontendClient::bringToFront()
void InspectorFrontendClient::closeWindow()
{
- destroyInspectorWindow();
+ destroyInspectorWindow(true);
+}
+
+void InspectorFrontendClient::disconnectFromBackend()
+{
+ destroyInspectorWindow(false);
}
void InspectorFrontendClient::attachWindow()
diff --git a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h
index 8b68405..08038f6 100644
--- a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h
+++ b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h
@@ -80,7 +80,7 @@ namespace WebKit {
void disconnectInspectorClient() { m_inspectorClient = 0; }
- void destroyInspectorWindow();
+ void destroyInspectorWindow(bool notifyInspectorController);
virtual WTF::String localizedStringsURL();
@@ -88,6 +88,7 @@ namespace WebKit {
virtual void bringToFront();
virtual void closeWindow();
+ virtual void disconnectFromBackend();
virtual void attachWindow();
virtual void detachWindow();
diff --git a/WebKit/gtk/tests/testatk.c b/WebKit/gtk/tests/testatk.c
index e159f8a..9930bc2 100644
--- a/WebKit/gtk/tests/testatk.c
+++ b/WebKit/gtk/tests/testatk.c
@@ -46,6 +46,8 @@ static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo<
static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>";
+static const char* listsOfItems = "<html><body><ul><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ul><ol><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ol></body></html>";
+
static gboolean bail_out(GMainLoop* loop)
{
if (g_main_loop_is_running(loop))
@@ -843,6 +845,81 @@ static void test_webkit_atk_get_extents(void)
g_object_unref(webView);
}
+static void testWebkitAtkListsOfItems(void)
+{
+ WebKitWebView* webView;
+ AtkObject* obj;
+ AtkObject* uList;
+ AtkObject* oList;
+ AtkObject* item1;
+ AtkObject* item2;
+ AtkObject* item3;
+ GMainLoop* loop;
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation alloc = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
+ webkit_web_view_load_string(webView, listsOfItems, NULL, NULL, NULL);
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_timeout_add(100, (GSourceFunc)bail_out, loop);
+ g_main_loop_run(loop);
+
+ obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(obj);
+
+ // Unordered list
+
+ uList = atk_object_ref_accessible_child(obj, 0);
+ g_assert(ATK_OBJECT(uList));
+ g_assert(atk_object_get_role(uList) == ATK_ROLE_LIST);
+ g_assert_cmpint(atk_object_get_n_accessible_children(uList), ==, 3);
+
+ item1 = ATK_TEXT(atk_object_ref_accessible_child(uList, 0));
+ item2 = ATK_TEXT(atk_object_ref_accessible_child(uList, 1));
+ item3 = ATK_TEXT(atk_object_ref_accessible_child(uList, 2));
+
+ g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1);
+
+ g_assert_cmpstr(atk_text_get_text(item1, 0, -1), ==, "\342\200\242 text only");
+ g_assert_cmpstr(atk_text_get_text(item2, 0, -1), ==, "\342\200\242 link only");
+ g_assert_cmpstr(atk_text_get_text(item3, 0, -1), ==, "\342\200\242 text and a link");
+
+ g_object_unref(item1);
+ g_object_unref(item2);
+ g_object_unref(item3);
+
+ // Ordered list
+
+ oList = atk_object_ref_accessible_child(obj, 1);
+ g_assert(ATK_OBJECT(oList));
+ g_assert(atk_object_get_role(oList) == ATK_ROLE_LIST);
+ g_assert_cmpint(atk_object_get_n_accessible_children(oList), ==, 3);
+
+ item1 = ATK_TEXT(atk_object_ref_accessible_child(oList, 0));
+ item2 = ATK_TEXT(atk_object_ref_accessible_child(oList, 1));
+ item3 = ATK_TEXT(atk_object_ref_accessible_child(oList, 2));
+
+ g_assert_cmpstr(atk_text_get_text(item1, 0, -1), ==, "1 text only");
+ g_assert_cmpstr(atk_text_get_text(item2, 0, -1), ==, "2 link only");
+ g_assert_cmpstr(atk_text_get_text(item3, 0, -1), ==, "3 text and a link");
+
+ g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1);
+
+ g_object_unref(item1);
+ g_object_unref(item2);
+ g_object_unref(item3);
+
+ g_object_unref(uList);
+ g_object_unref(oList);
+ g_object_unref(webView);
+}
+
int main(int argc, char** argv)
{
g_thread_init(NULL);
@@ -860,6 +937,7 @@ int main(int argc, char** argv)
g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable);
g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes);
g_test_add_func("/webkit/atk/get_extents", test_webkit_atk_get_extents);
+ g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems);
return g_test_run ();
}
diff --git a/WebKit/gtk/tests/testmimehandling.c b/WebKit/gtk/tests/testmimehandling.c
index 2ab0257..3a0eded 100644
--- a/WebKit/gtk/tests/testmimehandling.c
+++ b/WebKit/gtk/tests/testmimehandling.c
@@ -125,7 +125,7 @@ static gboolean mime_type_policy_decision_requested_cb(WebKitWebView* view, WebK
g_assert_cmpstr(mime_type, ==, "text/plain");
g_assert(webkit_web_view_can_show_mime_type(view, mime_type));
} else if (g_str_equal(type, "ogg")) {
- g_assert_cmpstr(mime_type, ==, "audio/ogg");
+ g_assert_cmpstr(mime_type, ==, "audio/x-vorbis+ogg");
g_assert(webkit_web_view_can_show_mime_type(view, mime_type));
}
@@ -172,7 +172,7 @@ static void test_mime_text()
static void test_mime_ogg()
{
- test_mime_type("pdf");
+ test_mime_type("ogg");
}
int main(int argc, char** argv)
diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h
index 92bb27d..bde5b55 100644
--- a/WebKit/gtk/webkit/webkitprivate.h
+++ b/WebKit/gtk/webkit/webkitprivate.h
@@ -163,7 +163,9 @@ extern "C" {
gboolean disposing;
gboolean usePrimaryForPaste;
+#if ENABLE(VIDEO)
FullscreenVideoController* fullscreenVideoController;
+#endif
// These are hosted here because the DataSource object is
// created too late in the frame loading process.
diff --git a/WebKit/gtk/webkit/webkitsoupauthdialog.c b/WebKit/gtk/webkit/webkitsoupauthdialog.c
index daecc73..0cf1c23 100644
--- a/WebKit/gtk/webkit/webkitsoupauthdialog.c
+++ b/WebKit/gtk/webkit/webkitsoupauthdialog.c
@@ -213,7 +213,9 @@ static void show_auth_dialog(WebKitAuthData* authData, const char* login, const
NULL);
/* Set the dialog up with HIG properties */
+#ifdef GTK_API_VERSION_2
gtk_dialog_set_has_separator(dialog, FALSE);
+#endif
gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(dialog)), 2); /* 2 * 5 + 2 = 12 */
gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_action_area(dialog)), 5);
diff --git a/WebKit/gtk/webkit/webkitwebview.cpp b/WebKit/gtk/webkit/webkitwebview.cpp
index 98f8e4e..480983f 100644
--- a/WebKit/gtk/webkit/webkitwebview.cpp
+++ b/WebKit/gtk/webkit/webkitwebview.cpp
@@ -3693,7 +3693,7 @@ void webkit_web_view_set_highlight_text_matches(WebKitWebView* webView, gboolean
Frame *frame = core(webView)->mainFrame();
do {
- frame->setMarkedTextMatchesAreHighlighted(shouldHighlight);
+ frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight);
frame = frame->tree()->traverseNextWithWrap(false);
} while (frame);
}
@@ -3875,7 +3875,7 @@ gchar* webkit_web_view_get_selected_text(WebKitWebView* webView)
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
- return g_strdup(frame->selectedText().utf8().data());
+ return g_strdup(frame->editor()->selectedText().utf8().data());
}
/**
@@ -3947,7 +3947,7 @@ void webkit_web_view_set_editable(WebKitWebView* webView, gboolean flag)
priv->editable = flag;
if (flag) {
- frame->applyEditingStyleToBodyElement();
+ frame->editor()->applyEditingStyleToBodyElement();
// TODO: If the WebKitWebView is made editable and the selection is empty, set it to something.
//if (!webkit_web_view_get_selected_dom_range(webView))
// mainFrame->setSelectionFromNone();
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index 88a2fbf..df5ca46 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,245 @@
+2010-09-09 John Therrell <jtherrell@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Added statistics sampling and reporting for JavaScriptCore's RegisterFile and ExecutableAllocator classes
+ https://bugs.webkit.org/show_bug.cgi?id=45134
+
+ Added ability to enable new JavaScriptCore statistics sampling and reporting for RegisterFile
+ and ExecutableAllocator classes. Added reporting of JavaScriptCore's stack committed memory
+ and JIT code committed memory statistics to WebCoreStatistics memoryStatistics.
+
+ * Misc/WebCoreStatistics.mm:
+ (+[WebCoreStatistics memoryStatistics]):
+ Added statistics reporting for JSC RegisterFile and ExecutableAllocator.
+
+2010-09-09 Jer Noble <jer.noble@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Use of ENABLE macro in WebUIDelegatePrivate.h breaks use from outside WebKit
+ <rdar://problem/8412657>
+
+ * WebView/WebUIDelegatePrivate.h: Use ENABLE_FULLSCREEN_API instead of ENABLE(FULLSCREEN_API)
+
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * WebView/WebFrame.mm:
+ (-[WebFrame _selectedString]):
+ (-[WebFrame _firstRectForDOMRange:]):
+ (-[WebFrame _markDOMRange]):
+ (-[WebFrame _setTypingStyle:withUndoAction:]):
+ * WebView/WebHTMLRepresentation.mm:
+ (-[WebHTMLRepresentation finishedLoadingWithDataSource:]):
+ * WebView/WebHTMLView.mm:
+ (-[WebHTMLView _selectionStartFontAttributesAsRTF]):
+ (-[WebHTMLView toggleBaseWritingDirection:]):
+ (-[WebHTMLView searchFor:direction:caseSensitive:wrap:startInSelection:]):
+ (-[WebHTMLView countMatchesForText:caseSensitive:limit:markMatches:]):
+ (-[WebHTMLView setMarkedTextMatchesAreHighlighted:]):
+ (-[WebHTMLView markedTextMatchesAreHighlighted]):
+ * WebView/WebView.mm:
+ (-[WebView setEditable:]):
+ Changed call sites to use editor().
+
+2010-09-08 MORITA Hajime <morrita@google.com>
+
+ Reviewed by Tony Chang.
+
+ spelling underline gets lost on backspace
+ https://bugs.webkit.org/show_bug.cgi?id=41423
+
+ Switched to use a anchorNode of the selection instead of a focused
+ node for finer control of node selection in spellingNode():
+ With the focused node, we cannot select other nodes but the first
+ child of that node. In some case, we need to inspect these.
+
+ The API is only for LayoutTests, and the change is compatible for
+ existing test cases.
+
+ * WebView/WebFrame.mm:
+ (spellingNode):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Rubber-stamped by Eric Seidel.
+
+ Rename DocLoader to CachedResourceLoader because that's what it does.
+
+ * WebView/WebFrame.mm:
+
+2010-09-07 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix clang++ build.
+
+ * Misc/WebLocalizableStrings.h:
+ Fix a struct/tag mismatch.
+
+ * WebView/WebDeviceOrientationProviderMock.mm:
+ (-[WebDeviceOrientationProviderMock init]):
+ Remove stray semicolon.
+
+ * WebView/WebViewData.h:
+ Remove unused class forward declaration.
+
+2010-09-07 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/8381749> -Wcast-align warning emitted when building with clang
+
+ Remove the -Wcast-align-warning since it isn't really useful, and clang is more aggressive about warning than gcc.
+
+ * Configurations/Base.xcconfig:
+
+2010-09-06 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Rename SecurityOrigin::canLoad to canDisplay
+ https://bugs.webkit.org/show_bug.cgi?id=45214
+
+ Propagate name change.
+
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::NetscapePluginInstanceProxy::loadRequest):
+ * Plugins/WebNetscapePluginStream.mm:
+ (WebNetscapePluginStream::WebNetscapePluginStream):
+ * Plugins/WebNetscapePluginView.mm:
+ (-[WebNetscapePluginView loadRequest:inTarget:withNotifyData:sendNotification:]):
+ * Plugins/WebPluginContainerCheck.mm:
+ (-[WebPluginContainerCheck _isForbiddenFileLoad]):
+ * WebView/WebFrame.mm:
+ (-[WebFrame _allowsFollowingLink:]):
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Add Mac's specific implementation of FrameNetworkingContext.
+
+ * WebCoreSupport/WebFrameLoaderClient.h:
+ * WebCoreSupport/WebFrameLoaderClient.mm:
+ * WebCoreSupport/WebFrameNetworkingContext.mm:
+ (WebFrameNetworkingContext::needsSiteSpecificQuirks):
+ (WebFrameNetworkingContext::localFileContentSniffingEnabled):
+ (WebFrameNetworkingContext::scheduledRunLoopPairs):
+ (WebFrameNetworkingContext::blockedError):
+
+2010-09-03 John Sullivan <sullivan@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45175
+ [WebView unmarkAllTextMatches] will crash if the webview is already closed
+
+ Made this and related methods robust against being called when the WebView is closed.
+
+ * WebView/WebView.mm:
+ (-[WebView markAllMatchesForText:caseSensitive:highlight:limit:]):
+ Bail out if the WebView is closed.
+ (-[WebView countMatchesForText:caseSensitive:highlight:limit:markMatches:]):
+ Ditto.
+ (-[WebView unmarkAllTextMatches]):
+ Ditto.
+ (-[WebView rectsForTextMatches]):
+ Ditto.
+
+2010-09-03 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ Adds textInputController.hasSpellingMarker() to avoid using pixel tests for spellchecking tests
+ and implements it for Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=41832
+
+ * WebView/WebFrame.mm: Implemented [WebFrame hasSpellingMarker:length:].
+ (spellingNode):
+ (-[WebFrame hasSpellingMarker:length:]):
+ * WebView/WebFramePrivate.h: Added [WebFrame hasSpellingMarker:length:] so TextInputController can use it.
+
+2010-09-02 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ REGRESSION: Crash occurs at objc_msgSend when closing a window that is displaying the web inspector
+ https://bugs.webkit.org/show_bug.cgi?id=44230
+
+ * WebCoreSupport/WebInspectorClient.h:
+ * WebCoreSupport/WebInspectorClient.mm:
+ (WebInspectorFrontendClient::closeWindow):
+ (WebInspectorFrontendClient::disconnectFromBackend):
+ (-[WebInspectorWindowController windowShouldClose:]):
+ (-[WebInspectorWindowController destroyInspectorView:]):
+
+2010-09-02 Steve Block <steveblock@google.com>
+
+ Reviewed by Adam Barth.
+
+ Hook up LayoutTestController.setMockDeviceOrientation() on Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=43181
+
+ This patch hooks up the mock device orientation client on Mac for use
+ in DumpRenderTree.
+
+ The patch adds a new WebDeviceOrientationClient for Mac. This client acts
+ as a proxy to either a real or mock device orientation provider, both of
+ which implement a new WebDeviceOrientationProvider interface.
+
+ The provider is created by the embedder and passed to the WebView, from
+ where WebDeviceOrientationClient can access it.
+
+ The mock provider, WebDeviceOrientationProviderMock, is a wrapper around
+ the existing WebCore mock.
+
+ * WebCoreSupport/WebDeviceOrientationClient.h: Added.
+ * WebCoreSupport/WebDeviceOrientationClient.mm: Added.
+ (WebDeviceOrientationClient::WebDeviceOrientationClient):
+ (WebDeviceOrientationClient::setController):
+ (WebDeviceOrientationClient::startUpdating):
+ (WebDeviceOrientationClient::stopUpdating):
+ (WebDeviceOrientationClient::lastOrientation):
+ * WebKit.exp:
+ * WebView/WebDeviceOrientation.h: Added.
+ * WebView/WebDeviceOrientation.mm: Added.
+ (-[WebDeviceOrientation initWithCoreDeviceOrientation:WebCore::]):
+ (core):
+ (-[WebDeviceOrientation initWithCanProvideAlpha:alpha:canProvideBeta:beta:canProvideGamma:gamma:]):
+ (-[WebDeviceOrientation dealloc]):
+ * WebView/WebDeviceOrientationInternal.h: Added.
+ * WebView/WebDeviceOrientationProvider.h: Added.
+ * WebView/WebDeviceOrientationProviderMock.h: Added.
+ * WebView/WebDeviceOrientationProviderMock.mm: Added.
+ (-[WebDeviceOrientationProviderMockInternal setOrientation:]):
+ (-[WebDeviceOrientationProviderMockInternal setController:]):
+ (-[WebDeviceOrientationProviderMockInternal startUpdating]):
+ (-[WebDeviceOrientationProviderMockInternal stopUpdating]):
+ (-[WebDeviceOrientationProviderMockInternal lastOrientation]):
+ (-[WebDeviceOrientationProviderMock init]):
+ (-[WebDeviceOrientationProviderMock dealloc]):
+ (-[WebDeviceOrientationProviderMock setOrientation:]):
+ (-[WebDeviceOrientationProviderMock setController:]):
+ (-[WebDeviceOrientationProviderMock startUpdating]):
+ (-[WebDeviceOrientationProviderMock stopUpdating]):
+ (-[WebDeviceOrientationProviderMock lastOrientation]):
+ * WebView/WebDeviceOrientationProviderMockInternal.h: Added.
+ * WebView/WebView.mm:
+ (-[WebView _commonInitializationWithFrameName:groupName:usesDocumentViews:]):
+ (-[WebView _setDeviceOrientationProvider:]):
+ (-[WebView _deviceOrientationProvider]):
+ * WebView/WebViewData.h:
+ * WebView/WebViewPrivate.h:
+
2010-09-01 Jia Pu <jpu@apple.com>
Reviewed by Dan Bernstein.
diff --git a/WebKit/mac/Configurations/Base.xcconfig b/WebKit/mac/Configurations/Base.xcconfig
index b3f8ea6..0e84791 100644
--- a/WebKit/mac/Configurations/Base.xcconfig
+++ b/WebKit/mac/Configurations/Base.xcconfig
@@ -56,8 +56,8 @@ VALID_ARCHS_macosx = i386 ppc x86_64 ppc64;
WARNING_CFLAGS_BASE = -Wall -Wextra -Wchar-subscripts -Wextra-tokens -Wformat-security -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wno-unused-parameter -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings;
WARNING_CFLAGS = $(WARNING_CFLAGS_$(REAL_PLATFORM_NAME));
WARNING_CFLAGS_iphoneos = $(WARNING_CFLAGS_BASE);
-WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wcast-align;
-WARNING_CFLAGS_macosx = $(WARNING_CFLAGS_BASE) -Wcast-align;
+WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE);
+WARNING_CFLAGS_macosx = $(WARNING_CFLAGS_BASE);
REAL_PLATFORM_NAME = $(REAL_PLATFORM_NAME_$(PLATFORM_NAME));
diff --git a/WebKit/mac/Configurations/Version.xcconfig b/WebKit/mac/Configurations/Version.xcconfig
index 659ac62..9f9441c 100644
--- a/WebKit/mac/Configurations/Version.xcconfig
+++ b/WebKit/mac/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 534;
-MINOR_VERSION = 7;
+MINOR_VERSION = 8;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/WebKit/mac/Misc/WebCoreStatistics.mm b/WebKit/mac/Misc/WebCoreStatistics.mm
index a5d5ae1..cc68cef 100644
--- a/WebKit/mac/Misc/WebCoreStatistics.mm
+++ b/WebKit/mac/Misc/WebCoreStatistics.mm
@@ -29,6 +29,8 @@
#import "WebCoreStatistics.h"
#import "DOMElementInternal.h"
+#import <JavaScriptCore/RegisterFile.h>
+#import <JavaScriptCore/ExecutableAllocator.h>
#import "WebCache.h"
#import "WebFrameInternal.h"
#import <runtime/JSLock.h>
@@ -196,12 +198,16 @@ using namespace WebCore;
WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
JSLock lock(SilenceAssertionsOnly);
Heap::Statistics jsHeapStatistics = JSDOMWindow::commonJSGlobalData()->heap.statistics();
+ size_t jscStackBytes = RegisterFile::committedByteCount();
+ size_t jscJITBytes = ExecutableAllocator::committedByteCount();
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:fastMallocStatistics.reservedVMBytes], @"FastMallocReservedVMBytes",
[NSNumber numberWithInt:fastMallocStatistics.committedVMBytes], @"FastMallocCommittedVMBytes",
[NSNumber numberWithInt:fastMallocStatistics.freeListBytes], @"FastMallocFreeListBytes",
[NSNumber numberWithInt:jsHeapStatistics.size], @"JavaScriptHeapSize",
[NSNumber numberWithInt:jsHeapStatistics.free], @"JavaScriptFreeSize",
+ [NSNumber numberWithUnsignedInt:(unsigned int)jscStackBytes], @"JavaScriptStackSize",
+ [NSNumber numberWithUnsignedInt:(unsigned int)jscJITBytes], @"JavaScriptJITSize",
nil];
}
diff --git a/WebKit/mac/Misc/WebLocalizableStrings.h b/WebKit/mac/Misc/WebLocalizableStrings.h
index ecad83d..853b601 100644
--- a/WebKit/mac/Misc/WebLocalizableStrings.h
+++ b/WebKit/mac/Misc/WebLocalizableStrings.h
@@ -28,6 +28,8 @@
#if __OBJC__
@class NSBundle;
+#elif __cplusplus
+class NSBundle;
#else
typedef struct NSBundle NSBundle;
#endif
diff --git a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
index a8dd09b..88df4cf 100644
--- a/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
+++ b/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
@@ -762,7 +762,7 @@ NPError NetscapePluginInstanceProxy::loadRequest(NSURLRequest *request, const ch
return NPERR_GENERIC_ERROR;
}
} else {
- if (!SecurityOrigin::canLoad(URL, String(), core([m_pluginView webFrame])->document()))
+ if (!SecurityOrigin::canDisplay(URL, String(), core([m_pluginView webFrame])->document()))
return NPERR_GENERIC_ERROR;
}
diff --git a/WebKit/mac/Plugins/WebNetscapePluginStream.mm b/WebKit/mac/Plugins/WebNetscapePluginStream.mm
index 5c1e8ee..35af439 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginStream.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginStream.mm
@@ -161,7 +161,7 @@ WebNetscapePluginStream::WebNetscapePluginStream(NSURLRequest *request, NPP plug
WebNetscapePluginView *view = (WebNetscapePluginView *)plugin->ndata;
// This check has already been done by the plug-in view.
- ASSERT(SecurityOrigin::canLoad([request URL], String(), core([view webFrame])->document()));
+ ASSERT(SecurityOrigin::canDisplay([request URL], String(), core([view webFrame])->document()));
ASSERT([request URL]);
ASSERT(plugin);
diff --git a/WebKit/mac/Plugins/WebNetscapePluginView.mm b/WebKit/mac/Plugins/WebNetscapePluginView.mm
index a4481bc..e98c6b7 100644
--- a/WebKit/mac/Plugins/WebNetscapePluginView.mm
+++ b/WebKit/mac/Plugins/WebNetscapePluginView.mm
@@ -1728,7 +1728,7 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
return NPERR_INVALID_PARAM;
}
} else {
- if (!SecurityOrigin::canLoad(URL, String(), core([self webFrame])->document()))
+ if (!SecurityOrigin::canDisplay(URL, String(), core([self webFrame])->document()))
return NPERR_GENERIC_ERROR;
}
diff --git a/WebKit/mac/Plugins/WebPluginContainerCheck.mm b/WebKit/mac/Plugins/WebPluginContainerCheck.mm
index 5609d80..e273bfc 100644
--- a/WebKit/mac/Plugins/WebPluginContainerCheck.mm
+++ b/WebKit/mac/Plugins/WebPluginContainerCheck.mm
@@ -99,7 +99,7 @@ using namespace WebCore;
{
Frame* coreFrame = core([_controller webFrame]);
ASSERT(coreFrame);
- if (!SecurityOrigin::canLoad([_request URL], String(), coreFrame->document())) {
+ if (!SecurityOrigin::canDisplay([_request URL], String(), coreFrame->document())) {
[self _continueWithPolicy:PolicyIgnore];
return YES;
}
diff --git a/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.h b/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.h
new file mode 100644
index 0000000..1cbc8e2
--- /dev/null
+++ b/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientationProvider.h"
+#import <WebCore/DeviceOrientationClient.h>
+
+namespace WebCore {
+class DeviceOrientationController;
+}
+
+@class WebView;
+
+// This class is the Mac implementation of DeviceOrientationClient. It is
+// passed to the Page constructor by the WebView. It is a simple proxy to
+// either the real or mock client which is passed to the WebView. It is
+// required because the WebView must pass a client to the Page constructor,
+// but the real or mock client can not be specified until after the Page has
+// been constructed.
+class WebDeviceOrientationClient : public WebCore::DeviceOrientationClient {
+public:
+ WebDeviceOrientationClient(WebView*);
+
+ // DeviceOrientationClient methods
+ virtual void setController(WebCore::DeviceOrientationController*);
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual WebCore::DeviceOrientation* lastOrientation() const;
+
+private:
+ id<WebDeviceOrientationProvider> getProvider() const;
+
+ WebView* m_webView;
+ WebCore::DeviceOrientationController* m_controller;
+ mutable id<WebDeviceOrientationProvider> m_provider;
+};
diff --git a/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm b/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm
new file mode 100644
index 0000000..278e835
--- /dev/null
+++ b/WebKit/mac/WebCoreSupport/WebDeviceOrientationClient.mm
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientationClient.h"
+
+#import "WebDeviceOrientationInternal.h"
+#import "WebDeviceOrientationProvider.h"
+#import "WebViewInternal.h"
+#import <objc/objc-runtime.h>
+
+using namespace WebCore;
+
+WebDeviceOrientationClient::WebDeviceOrientationClient(WebView* webView)
+ : m_webView(webView)
+ , m_controller(0)
+{
+}
+
+void WebDeviceOrientationClient::setController(DeviceOrientationController* controller)
+{
+ // This is called by the Page constructor before our WebView has the provider set up.
+ // Cache the controller for later use.
+ m_controller = controller;
+}
+
+void WebDeviceOrientationClient::startUpdating()
+{
+ [getProvider() startUpdating];
+}
+
+void WebDeviceOrientationClient::stopUpdating()
+{
+ [getProvider() stopUpdating];
+}
+
+DeviceOrientation* WebDeviceOrientationClient::lastOrientation() const
+{
+ return core([getProvider() lastOrientation]);
+}
+
+id<WebDeviceOrientationProvider> WebDeviceOrientationClient::getProvider() const
+{
+ if (!m_provider) {
+ m_provider = [m_webView _deviceOrientationProvider];
+ if ([m_provider respondsToSelector:@selector(setController:)])
+ objc_msgSend(m_provider, @selector(setController:), m_controller);
+ }
+ return m_provider;
+}
diff --git a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h
index d932e66..cbb89ec 100644
--- a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h
+++ b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.h
@@ -228,6 +228,8 @@ private:
virtual bool canCachePage() const;
+ virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext();
+
RetainPtr<WebFrame> m_webFrame;
RetainPtr<WebFramePolicyListener> m_policyListener;
diff --git a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
index 3f7c471..dcbca28 100644
--- a/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
+++ b/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
@@ -47,6 +47,7 @@
#import "WebFormDelegate.h"
#import "WebFrameInternal.h"
#import "WebFrameLoadDelegate.h"
+#import "WebFrameNetworkingContext.h"
#import "WebFrameViewInternal.h"
#import "WebHTMLRepresentationPrivate.h"
#import "WebHTMLViewInternal.h"
@@ -1904,6 +1905,11 @@ void WebFrameLoaderClient::didPerformFirstNavigation() const
[preferences setCacheModel:WebCacheModelDocumentBrowser];
}
+PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
+{
+ return WebFrameNetworkingContext::create(core(m_webFrame.get()));
+}
+
#if ENABLE(JAVA_BRIDGE)
jobject WebFrameLoaderClient::javaApplet(NSView* view)
{
diff --git a/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm b/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm
index 941cfaa..98b8ce1 100644
--- a/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm
+++ b/WebKit/mac/WebCoreSupport/WebFrameNetworkingContext.mm
@@ -17,5 +17,30 @@
Boston, MA 02110-1301, USA.
*/
-// Checking this file in empty to get the build system work out of the way.
-// Will put the code in here later.
+#import "WebFrameNetworkingContext.h"
+
+#import <WebCore/Page.h>
+#import <WebCore/ResourceError.h>
+#import <WebCore/Settings.h>
+
+using namespace WebCore;
+
+bool WebFrameNetworkingContext::needsSiteSpecificQuirks() const
+{
+ return frame() && frame()->settings() && frame()->settings()->needsSiteSpecificQuirks();
+}
+
+bool WebFrameNetworkingContext::localFileContentSniffingEnabled() const
+{
+ return frame() && frame()->settings() && frame()->settings()->localFileContentSniffingEnabled();
+}
+
+SchedulePairHashSet* WebFrameNetworkingContext::scheduledRunLoopPairs() const
+{
+ return frame() && frame()->page() ? frame()->page()->scheduledRunLoopPairs() : 0;
+}
+
+ResourceError WebFrameNetworkingContext::blockedError(const ResourceRequest& request) const
+{
+ return frame()->loader()->blockedError(request);
+}
diff --git a/WebKit/mac/WebCoreSupport/WebInspectorClient.h b/WebKit/mac/WebCoreSupport/WebInspectorClient.h
index d33e3b9..75a3cc6 100644
--- a/WebKit/mac/WebCoreSupport/WebInspectorClient.h
+++ b/WebKit/mac/WebCoreSupport/WebInspectorClient.h
@@ -84,6 +84,7 @@ public:
virtual void bringToFront();
virtual void closeWindow();
+ virtual void disconnectFromBackend();
virtual void attachWindow();
virtual void detachWindow();
diff --git a/WebKit/mac/WebCoreSupport/WebInspectorClient.mm b/WebKit/mac/WebCoreSupport/WebInspectorClient.mm
index 7cae8fc..d4d0213 100644
--- a/WebKit/mac/WebCoreSupport/WebInspectorClient.mm
+++ b/WebKit/mac/WebCoreSupport/WebInspectorClient.mm
@@ -66,7 +66,7 @@ using namespace WebCore;
- (void)setFrontendClient:(WebInspectorFrontendClient*)frontendClient;
- (void)setInspectorClient:(WebInspectorClient*)inspectorClient;
- (void)setAttachedWindowHeight:(unsigned)height;
-- (void)destroyInspectorView;
+- (void)destroyInspectorView:(bool)notifyInspectorController;
@end
#pragma mark -
@@ -169,7 +169,12 @@ void WebInspectorFrontendClient::bringToFront()
void WebInspectorFrontendClient::closeWindow()
{
- [m_windowController.get() destroyInspectorView];
+ [m_windowController.get() destroyInspectorView:true];
+}
+
+void WebInspectorFrontendClient::disconnectFromBackend()
+{
+ [m_windowController.get() destroyInspectorView:false];
}
void WebInspectorFrontendClient::attachWindow()
@@ -308,7 +313,7 @@ void WebInspectorFrontendClient::updateWindowTitle() const
- (BOOL)windowShouldClose:(id)sender
{
- [self destroyInspectorView];
+ [self destroyInspectorView:true];
return YES;
}
@@ -439,7 +444,7 @@ void WebInspectorFrontendClient::updateWindowTitle() const
[frameView setFrame:frameViewRect];
}
-- (void)destroyInspectorView
+- (void)destroyInspectorView:(bool)notifyInspectorController
{
if (_destroyingInspectorView)
return;
@@ -450,10 +455,12 @@ void WebInspectorFrontendClient::updateWindowTitle() const
_visible = NO;
- if (Page* inspectedPage = [_inspectedWebView page])
- inspectedPage->inspectorController()->disconnectFrontend();
+ if (notifyInspectorController) {
+ if (Page* inspectedPage = [_inspectedWebView page])
+ inspectedPage->inspectorController()->disconnectFrontend();
- _inspectorClient->releaseFrontendPage();
+ _inspectorClient->releaseFrontendPage();
+ }
[_webView close];
}
diff --git a/WebKit/mac/WebKit.exp b/WebKit/mac/WebKit.exp
index a22179f..463ab00 100644
--- a/WebKit/mac/WebKit.exp
+++ b/WebKit/mac/WebKit.exp
@@ -7,6 +7,8 @@
.objc_class_name_WebDataSource
.objc_class_name_WebDatabaseManager
.objc_class_name_WebDefaultPolicyDelegate
+.objc_class_name_WebDeviceOrientation
+.objc_class_name_WebDeviceOrientationProviderMock
.objc_class_name_WebDownload
.objc_class_name_WebDynamicScrollBarsView
.objc_class_name_WebFormDelegate
diff --git a/WebKit/mac/WebView/WebDeviceOrientation.h b/WebKit/mac/WebView/WebDeviceOrientation.h
new file mode 100644
index 0000000..ee04199
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientation.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR 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.
+ */
+
+
+@class WebDeviceOrientationInternal;
+
+@interface WebDeviceOrientation : NSObject {
+ WebDeviceOrientationInternal* m_internal;
+}
+
+- (id)initWithCanProvideAlpha:(bool)canProvideAlpha alpha:(double)alpha canProvideBeta:(bool)canProvideBeta beta:(double)beta canProvideGamma:(bool)canProvideGamma gamma:(double)gamma;
+
+@end
diff --git a/WebKit/mac/WebView/WebDeviceOrientation.mm b/WebKit/mac/WebView/WebDeviceOrientation.mm
new file mode 100644
index 0000000..7be5d0c
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientation.mm
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientationInternal.h"
+
+using namespace WebCore;
+
+@implementation WebDeviceOrientationInternal
+
+- (id)initWithCoreDeviceOrientation:(PassRefPtr<DeviceOrientation>)coreDeviceOrientation
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ m_orientation = coreDeviceOrientation;
+ return self;
+}
+
+@end
+
+@implementation WebDeviceOrientation (Internal)
+
+- (id)initWithCoreDeviceOrientation:(PassRefPtr<WebCore::DeviceOrientation>)coreDeviceOrientation
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ m_internal = [[WebDeviceOrientationInternal alloc] initWithCoreDeviceOrientation:coreDeviceOrientation];
+ return self;
+}
+
+@end
+
+@implementation WebDeviceOrientation
+
+DeviceOrientation* core(WebDeviceOrientation* orientation)
+{
+ return orientation ? orientation->m_internal->m_orientation.get() : 0;
+}
+
+- (id)initWithCanProvideAlpha:(bool)canProvideAlpha alpha:(double)alpha canProvideBeta:(bool)canProvideBeta beta:(double)beta canProvideGamma:(bool)canProvideGamma gamma:(double)gamma
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ m_internal = [[WebDeviceOrientationInternal alloc] initWithCoreDeviceOrientation:DeviceOrientation::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma)];
+ return self;
+}
+
+- (void)dealloc
+{
+ [m_internal release];
+ [super dealloc];
+}
+
+@end
diff --git a/WebKit/mac/WebView/WebDeviceOrientationInternal.h b/WebKit/mac/WebView/WebDeviceOrientationInternal.h
new file mode 100644
index 0000000..b7c6aa5
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientationInternal.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientation.h"
+
+#import <WebCore/DeviceOrientation.h>
+#import <wtf/RefPtr.h>
+
+@interface WebDeviceOrientationInternal : NSObject {
+@public
+ RefPtr<WebCore::DeviceOrientation> m_orientation;
+}
+
+- (id)initWithCoreDeviceOrientation:(PassRefPtr<WebCore::DeviceOrientation>)coreDeviceOrientation;
+@end
+
+@interface WebDeviceOrientation (Internal)
+
+- (id)initWithCoreDeviceOrientation:(PassRefPtr<WebCore::DeviceOrientation>)coreDeviceOrientation;
+
+@end
+
+WebCore::DeviceOrientation* core(WebDeviceOrientation*);
diff --git a/WebKit/mac/WebView/WebDeviceOrientationProvider.h b/WebKit/mac/WebView/WebDeviceOrientationProvider.h
new file mode 100644
index 0000000..18b688c
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientationProvider.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR 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.
+ */
+
+@class WebDeviceOrientation;
+
+@protocol WebDeviceOrientationProvider <NSObject>
+- (void)startUpdating;
+- (void)stopUpdating;
+- (WebDeviceOrientation*)lastOrientation;
+@end
diff --git a/WebKit/mac/WebView/WebDeviceOrientationProviderMock.h b/WebKit/mac/WebView/WebDeviceOrientationProviderMock.h
new file mode 100644
index 0000000..be5a764
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientationProviderMock.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientationProvider.h"
+
+@class WebDeviceOrientationProviderMockInternal;
+@class WebDeviceOrientation;
+
+@interface WebDeviceOrientationProviderMock : NSObject<WebDeviceOrientationProvider> {
+ WebDeviceOrientationProviderMockInternal* m_internal;
+}
+
+- (id)init;
+- (void)setOrientation:(WebDeviceOrientation*)orientation;
+
+@end
diff --git a/WebKit/mac/WebView/WebDeviceOrientationProviderMock.mm b/WebKit/mac/WebView/WebDeviceOrientationProviderMock.mm
new file mode 100644
index 0000000..0435264
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientationProviderMock.mm
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientationProviderMockInternal.h"
+
+#import "WebDeviceOrientationInternal.h"
+
+using namespace WebCore;
+
+@implementation WebDeviceOrientationProviderMockInternal
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ m_core.set(new DeviceOrientationClientMock());
+ return self;
+}
+
+- (void)setOrientation:(WebDeviceOrientation*)orientation
+{
+ m_core->setOrientation(core(orientation));
+}
+
+- (void)setController:(DeviceOrientationController*)controller
+{
+ m_core->setController(controller);
+}
+
+- (void)startUpdating
+{
+ m_core->startUpdating();
+}
+
+- (void)stopUpdating
+{
+ m_core->stopUpdating();
+}
+
+- (WebDeviceOrientation*)lastOrientation
+{
+ return [[WebDeviceOrientation alloc] initWithCoreDeviceOrientation:m_core->lastOrientation()];
+}
+
+@end
+
+@implementation WebDeviceOrientationProviderMock (Internal)
+
+- (void)setController:(WebCore::DeviceOrientationController*)controller
+{
+ [m_internal setController:controller];
+}
+
+@end
+
+@implementation WebDeviceOrientationProviderMock
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+ m_internal = [[WebDeviceOrientationProviderMockInternal alloc] init];
+ return self;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+ [m_internal release];
+}
+
+- (void)setOrientation:(WebDeviceOrientation*)orientation
+{
+ [m_internal setOrientation:orientation];
+}
+
+- (void)startUpdating
+{
+ [m_internal startUpdating];
+}
+
+- (void)stopUpdating
+{
+ [m_internal stopUpdating];
+}
+
+- (WebDeviceOrientation*)lastOrientation
+{
+ return [m_internal lastOrientation];
+}
+
+@end
diff --git a/WebKit/mac/WebView/WebDeviceOrientationProviderMockInternal.h b/WebKit/mac/WebView/WebDeviceOrientationProviderMockInternal.h
new file mode 100644
index 0000000..5ac38e5
--- /dev/null
+++ b/WebKit/mac/WebView/WebDeviceOrientationProviderMockInternal.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebDeviceOrientationProviderMock.h"
+
+#import <WebCore/DeviceOrientationClientMock.h>
+#import <wtf/OwnPtr.h>
+
+@interface WebDeviceOrientationProviderMockInternal : NSObject {
+ OwnPtr<WebCore::DeviceOrientationClientMock> m_core;
+}
+
+- (id)init;
+
+- (void)setOrientation:(WebDeviceOrientation*)orientation;
+
+- (void)setController:(WebCore::DeviceOrientationController*)controller;
+
+- (void)startUpdating;
+- (void)stopUpdating;
+- (WebDeviceOrientation*)lastOrientation;
+@end
+
+@interface WebDeviceOrientationProviderMock (Internal)
+- (void)setController:(WebCore::DeviceOrientationController*)controller;
+@end
diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm
index 1feb97e..8d564a3 100644
--- a/WebKit/mac/WebView/WebFrame.mm
+++ b/WebKit/mac/WebView/WebFrame.mm
@@ -60,7 +60,7 @@
#import <WebCore/Chrome.h>
#import <WebCore/ColorMac.h>
#import <WebCore/DOMImplementation.h>
-#import <WebCore/DocLoader.h>
+#import <WebCore/CachedResourceLoader.h>
#import <WebCore/DocumentFragment.h>
#import <WebCore/EventHandler.h>
#import <WebCore/EventNames.h>
@@ -529,7 +529,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
- (NSString *)_selectedString
{
- return _private->coreFrame->displayStringModifiedByEncoding(_private->coreFrame->selectedText());
+ return _private->coreFrame->displayStringModifiedByEncoding(_private->coreFrame->editor()->selectedText());
}
- (NSString *)_stringForRange:(DOMRange *)range
@@ -662,7 +662,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
- (NSRect)_firstRectForDOMRange:(DOMRange *)range
{
- return _private->coreFrame->firstRectForRange(core(range));
+ return _private->coreFrame->editor()->firstRectForRange(core(range));
}
- (void)_scrollDOMRangeToVisible:(DOMRange *)range
@@ -788,7 +788,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
- (DOMRange *)_markDOMRange
{
- return kit(_private->coreFrame->mark().toNormalizedRange().get());
+ return kit(_private->coreFrame->editor()->mark().toNormalizedRange().get());
}
// Given proposedRange, returns an extended range that includes adjacent whitespace that should
@@ -904,7 +904,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
{
if (!_private->coreFrame)
return;
- _private->coreFrame->computeAndSetTypingStyle(core(style), undoAction);
+ _private->coreFrame->editor()->computeAndSetTypingStyle(core(style), undoAction);
}
- (void)_dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation
@@ -1282,7 +1282,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
{
if (!_private->coreFrame)
return YES;
- return SecurityOrigin::canLoad(URL, String(), _private->coreFrame->document());
+ return SecurityOrigin::canDisplay(URL, String(), _private->coreFrame->document());
}
- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string withGlobalObject:(JSObjectRef)globalObjectRef inScriptWorld:(WebScriptWorld *)world
@@ -1366,6 +1366,40 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
return coreFrame->layerTreeAsText();
}
+static Node* spellingNode(Frame* coreFrame)
+{
+ Node* focusedNode = coreFrame->selection()->start().node();
+ if (!focusedNode || !focusedNode->renderer())
+ return 0;
+
+ for (const RenderObject* renderer = focusedNode->renderer(); renderer; renderer = renderer->childAt(0)) {
+ if (renderer->isText())
+ return renderer->node();
+ }
+ return 0;
+}
+
+- (BOOL)hasSpellingMarker:(int)from length:(int)length
+{
+ Frame* coreFrame = _private->coreFrame;
+ if (!coreFrame)
+ return NO;
+
+ Node* node = spellingNode(coreFrame);
+ if (!node)
+ return NO;
+
+ unsigned int startOffset = static_cast<unsigned int>(from);
+ unsigned int endOffset = static_cast<unsigned int>(from + length);
+ Vector<DocumentMarker> markers = coreFrame->document()->markers()->markersForNode(node);
+ for (size_t i = 0; i < markers.size(); ++i) {
+ DocumentMarker marker = markers[i];
+ if (marker.startOffset <= startOffset && endOffset <= marker.endOffset && marker.type == DocumentMarker::Spelling)
+ return YES;
+ }
+ return NO;
+}
+
@end
@implementation WebFrame
diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h
index a1031f3..9cb6232 100644
--- a/WebKit/mac/WebView/WebFramePrivate.h
+++ b/WebKit/mac/WebView/WebFramePrivate.h
@@ -143,4 +143,7 @@ typedef enum {
- (NSString*)_layerTreeAsText;
+// Returns whether there is a spelling marker in the specified range of the focused node.
+- (BOOL)hasSpellingMarker:(int)location length:(int)length;
+
@end
diff --git a/WebKit/mac/WebView/WebHTMLRepresentation.mm b/WebKit/mac/WebView/WebHTMLRepresentation.mm
index 7843c9a..188747d 100644
--- a/WebKit/mac/WebView/WebHTMLRepresentation.mm
+++ b/WebKit/mac/WebView/WebHTMLRepresentation.mm
@@ -212,7 +212,7 @@ static NSArray *concatenateArrays(NSArray *first, NSArray *second)
WebView *webView = [frame webView];
if ([webView isEditable])
- core(frame)->applyEditingStyleToBodyElement();
+ core(frame)->editor()->applyEditingStyleToBodyElement();
}
}
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index 34745a1..bd71eff 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -4204,7 +4204,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
{
Frame* coreFrame = core([self _frame]);
NSAttributedString *string = [[NSAttributedString alloc] initWithString:@"x"
- attributes:coreFrame ? coreFrame->fontAttributesForSelectionStart() : nil];
+ attributes:coreFrame ? coreFrame->editor()->fontAttributesForSelectionStart() : nil];
NSData *data = [string RTFFromRange:NSMakeRange(0, [string length]) documentAttributes:nil];
[string release];
return data;
@@ -4831,7 +4831,7 @@ NSStrokeColorAttributeName /* NSColor, default nil: same as foreground co
return;
WritingDirection direction = RightToLeftWritingDirection;
- switch (coreFrame->baseWritingDirectionForSelectionStart()) {
+ switch (coreFrame->editor()->baseWritingDirectionForSelectionStart()) {
case NSWritingDirectionLeftToRight:
break;
case NSWritingDirectionRightToLeft:
@@ -6167,7 +6167,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
if (![string length])
return NO;
Frame* coreFrame = core([self _frame]);
- return coreFrame && coreFrame->findString(string, forward, caseFlag, wrapFlag, startInSelection);
+ return coreFrame && coreFrame->editor()->findString(string, forward, caseFlag, wrapFlag, startInSelection);
}
@end
@@ -6197,7 +6197,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
Frame* coreFrame = core([self _frame]);
if (!coreFrame)
return 0;
- return coreFrame->countMatchesForText(string, caseFlag, limit, markMatches);
+ return coreFrame->editor()->countMatchesForText(string, caseFlag, limit, markMatches);
}
- (void)setMarkedTextMatchesAreHighlighted:(BOOL)newValue
@@ -6205,13 +6205,13 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
Frame* coreFrame = core([self _frame]);
if (!coreFrame)
return;
- coreFrame->setMarkedTextMatchesAreHighlighted(newValue);
+ coreFrame->editor()->setMarkedTextMatchesAreHighlighted(newValue);
}
- (BOOL)markedTextMatchesAreHighlighted
{
Frame* coreFrame = core([self _frame]);
- return coreFrame && coreFrame->markedTextMatchesAreHighlighted();
+ return coreFrame && coreFrame->editor()->markedTextMatchesAreHighlighted();
}
- (void)unmarkAllTextMatches
diff --git a/WebKit/mac/WebView/WebUIDelegatePrivate.h b/WebKit/mac/WebView/WebUIDelegatePrivate.h
index 22752ae..4565a4e 100644
--- a/WebKit/mac/WebView/WebUIDelegatePrivate.h
+++ b/WebKit/mac/WebView/WebUIDelegatePrivate.h
@@ -32,6 +32,10 @@
#define ENABLE_DASHBOARD_SUPPORT 1
#endif
+#if !defined(ENABLE_FULLSCREEN_API)
+#define ENABLE_FULLSCREEN_API 1
+#endif
+
// Mail on Tiger expects the old value for WebMenuItemTagSearchInGoogle
#define WebMenuItemTagSearchInGoogle OldWebMenuItemTagSearchWeb
@@ -95,7 +99,7 @@ enum {
- (void)deny;
@end
-#if ENABLE(FULLSCREEN_API)
+#if ENABLE_FULLSCREEN_API
@protocol WebKitFullScreenListener<NSObject>
- (void)webkitWillEnterFullScreen;
- (void)webkitDidEnterFullScreen;
@@ -173,7 +177,7 @@ enum {
*/
- (void)webView:(WebView *)sender printFrame:(WebFrame *)frame;
-#if ENABLE(FULLSCREEN_API)
+#if ENABLE_FULLSCREEN_API
- (BOOL)webView:(WebView *)sender supportsFullScreenForElement:(DOMElement *)element;
- (void)webView:(WebView *)sender enterFullScreenForElement:(DOMElement *)element;
- (void)webView:(WebView *)sender exitFullScreenForElement:(DOMElement *)element;
diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm
index f2e76c1..0125e1c 100644
--- a/WebKit/mac/WebView/WebView.mm
+++ b/WebKit/mac/WebView/WebView.mm
@@ -47,6 +47,8 @@
#import "WebDefaultPolicyDelegate.h"
#import "WebDefaultUIDelegate.h"
#import "WebDelegateImplementationCaching.h"
+#import "WebDeviceOrientationClient.h"
+#import "WebDeviceOrientationProvider.h"
#import "WebDocument.h"
#import "WebDocumentInternal.h"
#import "WebDownload.h"
@@ -683,6 +685,9 @@ static bool shouldEnableLoadDeferring()
#if ENABLE(CLIENT_BASED_GEOLOCATION)
pageClients.geolocationControllerClient = new WebGeolocationControllerClient(self);
#endif
+#if ENABLE(DEVICE_ORIENTATION)
+ pageClients.deviceOrientationClient = new WebDeviceOrientationClient(self);
+#endif
_private->page = new Page(pageClients);
_private->page->setCanStartMedia([self window]);
@@ -4375,11 +4380,17 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu
- (NSUInteger)markAllMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit
{
+ if (_private->closed)
+ return 0;
+
return [self countMatchesForText:string caseSensitive:caseFlag highlight:highlight limit:limit markMatches:YES];
}
- (NSUInteger)countMatchesForText:(NSString *)string caseSensitive:(BOOL)caseFlag highlight:(BOOL)highlight limit:(NSUInteger)limit markMatches:(BOOL)markMatches
{
+ if (_private->closed)
+ return 0;
+
WebFrame *frame = [self mainFrame];
unsigned matchCount = 0;
do {
@@ -4404,6 +4415,9 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu
- (void)unmarkAllTextMatches
{
+ if (_private->closed)
+ return;
+
WebFrame *frame = [self mainFrame];
do {
id <WebDocumentView> view = [[frame frameView] documentView];
@@ -4416,6 +4430,9 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu
- (NSArray *)rectsForTextMatches
{
+ if (_private->closed)
+ return [NSArray array];
+
NSMutableArray *result = [NSMutableArray array];
WebFrame *frame = [self mainFrame];
do {
@@ -4749,7 +4766,7 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue jsValu
Frame* mainFrame = [self _mainCoreFrame];
if (mainFrame) {
if (flag) {
- mainFrame->applyEditingStyleToBodyElement();
+ mainFrame->editor()->applyEditingStyleToBodyElement();
// If the WebView is made editable and the selection is empty, set it to something.
if (![self selectedDOMRange])
mainFrame->setSelectionFromNone();
@@ -5883,6 +5900,23 @@ static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity
@end
+@implementation WebView (WebViewDeviceOrientation)
+
+- (void)_setDeviceOrientationProvider:(id<WebDeviceOrientationProvider>)deviceOrientationProvider
+{
+ if (_private)
+ _private->m_deviceOrientationProvider = deviceOrientationProvider;
+}
+
+- (id<WebDeviceOrientationProvider>)_deviceOrientationProvider
+{
+ if (_private)
+ return _private->m_deviceOrientationProvider;
+ return nil;
+}
+
+@end
+
@implementation WebView (WebViewGeolocation)
- (void)_setGeolocationProvider:(id<WebGeolocationProvider>)geolocationProvider
diff --git a/WebKit/mac/WebView/WebViewData.h b/WebKit/mac/WebView/WebViewData.h
index 3b80a89..558770e 100644
--- a/WebKit/mac/WebView/WebViewData.h
+++ b/WebKit/mac/WebView/WebViewData.h
@@ -44,6 +44,7 @@ namespace WebCore {
@class WebPreferences;
@class WebTextCompletionController;
@protocol WebFormDelegate;
+@protocol WebDeviceOrientationProvider;
@protocol WebGeolocationProvider;
#if ENABLE(VIDEO)
@class WebVideoFullscreenController;
@@ -174,5 +175,6 @@ extern int pluginDatabaseClientCount;
CFRunLoopObserverRef glibRunLoopObserver;
#endif
id<WebGeolocationProvider> _geolocationProvider;
+ id<WebDeviceOrientationProvider> m_deviceOrientationProvider;
}
@end
diff --git a/WebKit/mac/WebView/WebViewPrivate.h b/WebKit/mac/WebView/WebViewPrivate.h
index 28348cc..aeb36c7 100644
--- a/WebKit/mac/WebView/WebViewPrivate.h
+++ b/WebKit/mac/WebView/WebViewPrivate.h
@@ -44,12 +44,14 @@
@class NSError;
@class WebFrame;
+@class WebDeviceOrientation;
@class WebGeolocationPosition;
@class WebInspector;
@class WebPreferences;
@class WebScriptWorld;
@class WebTextIterator;
+@protocol WebDeviceOrientationProvider;
@protocol WebFormDelegate;
extern NSString *_WebCanGoBackKey;
@@ -605,6 +607,11 @@ Could be worth adding to the API.
- (BOOL)_selectionIsAll;
@end
+@interface WebView (WebViewDeviceOrientation)
+- (void)_setDeviceOrientationProvider:(id<WebDeviceOrientationProvider>)deviceOrientationProvider;
+- (id<WebDeviceOrientationProvider>)_deviceOrientationProvider;
+@end
+
@protocol WebGeolocationProvider <NSObject>
- (void)registerWebView:(WebView *)webView;
- (void)unregisterWebView:(WebView *)webView;
diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp
index 81eabfc..464b4a0 100644
--- a/WebKit/qt/Api/qwebframe.cpp
+++ b/WebKit/qt/Api/qwebframe.cpp
@@ -929,7 +929,7 @@ void QWebFrame::setScrollBarValue(Qt::Orientation orientation, int value)
value = 0;
else if (value > scrollBarMaximum(orientation))
value = scrollBarMaximum(orientation);
- sb->setValue(value);
+ sb->setValue(value, Scrollbar::NotFromScrollAnimator);
}
}
diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp
index ec415bb..8bf9208 100644
--- a/WebKit/qt/Api/qwebpage.cpp
+++ b/WebKit/qt/Api/qwebpage.cpp
@@ -2417,7 +2417,7 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &
QString QWebPage::selectedText() const
{
d->createMainFrame();
- return d->page->focusController()->focusedOrMainFrame()->selectedText();
+ return d->page->focusController()->focusedOrMainFrame()->editor()->selectedText();
}
#ifndef QT_NO_ACTION
@@ -2881,7 +2881,7 @@ void QWebPage::setContentEditable(bool editable)
if (d->mainFrame) {
WebCore::Frame* frame = d->mainFrame->d->frame;
if (editable) {
- frame->applyEditingStyleToBodyElement();
+ frame->editor()->applyEditingStyleToBodyElement();
// FIXME: mac port calls this if there is no selectedDOMRange
//frame->setSelectionFromNone();
}
diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog
index 996435b..95e79a4 100644
--- a/WebKit/qt/ChangeLog
+++ b/WebKit/qt/ChangeLog
@@ -1,3 +1,134 @@
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * Api/qwebpage.cpp:
+ (QWebPage::selectedText):
+ (QWebPage::setContentEditable):
+ * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
+ (DumpRenderTreeSupportQt::firstRectForCharacterRange):
+ Changed call sites to use editor().
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Reviewed by David Hyatt.
+
+ Add smooth scrolling framework, and a Windows implementation.
+ https://bugs.webkit.org/show_bug.cgi?id=32356
+
+ * Api/qwebframe.cpp:
+ (QWebFrame::setScrollBarValue):
+
+2010-09-06 Diego Gonzalez <diegohcg@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] Update NetworkAccessManager in Qt FrameNetworkingContext
+ https://bugs.webkit.org/show_bug.cgi?id=45231
+
+ Make possible to get the current QNAM when NetwokingContext request it.
+
+ * WebCoreSupport/FrameNetworkingContextQt.cpp:
+ (WebCore::FrameNetworkingContextQt::networkAccessManager):
+
+2010-09-06 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ Web Inspector: Tests crash on Qt bots revealed by r66720
+ https://bugs.webkit.org/show_bug.cgi?id=45256
+
+ * WebCoreSupport/InspectorClientQt.cpp:
+ (WebCore::InspectorClientQt::InspectorClientQt): m_frontendClient must be initialized by constructor
+
+2010-09-06 Yury Semikhatsky <yurys@chromium.org>
+
+ Unreviewed. Attempt to fix random test crashes after r66720.
+
+ * WebCoreSupport/InspectorClientQt.cpp:
+ (WebCore::InspectorFrontendClientQt::~InspectorFrontendClientQt):
+ * WebCoreSupport/InspectorClientQt.h:
+
+2010-09-05 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r66801.
+ http://trac.webkit.org/changeset/66801
+ https://bugs.webkit.org/show_bug.cgi?id=45242
+
+ 'breaks editing/pasteboard/onpaste-text-html.html' (Requested
+ by mwenge4 on #webkit).
+
+ * WebCoreSupport/ChromeClientQt.cpp:
+ (WebCore::ChromeClientQt::addMessageToConsole):
+
+2010-09-05 Robert Hogan <robert@webkit.org>
+
+ Reviewed by Antonio Gomes.
+
+ [Qt] utf8 encoding of console() messages
+
+ http/tests/security/xssAuditor/embed-tag-null-char.html
+ http/tests/security/xssAuditor/object-embed-tag-null-char.html
+
+ both fail because ChromeClientQt::addMessageToConsole() is
+ casting String to QString rather than String::utf8().data()
+
+ https://bugs.webkit.org/show_bug.cgi?id=45240
+
+ * WebCoreSupport/ChromeClientQt.cpp:
+ (WebCore::ChromeClientQt::addMessageToConsole):
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Add Qt's specific implementation of NetworkingContext.
+
+ * WebCoreSupport/FrameLoaderClientQt.cpp:
+ (WebCore::FrameLoaderClientQt::setFrame):
+ (WebCore::FrameLoaderClientQt::createNetworkingContext):
+ * WebCoreSupport/FrameLoaderClientQt.h:
+ * WebCoreSupport/FrameNetworkingContextQt.cpp:
+ (WebCore::FrameNetworkingContextQt::FrameNetworkingContextQt):
+ (WebCore::FrameNetworkingContextQt::create):
+ (WebCore::FrameNetworkingContextQt::originatingObject):
+ (WebCore::FrameNetworkingContextQt::networkAccessManager):
+
+2010-09-02 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ REGRESSION: Crash occurs at objc_msgSend when closing a window that is displaying the web inspector
+ https://bugs.webkit.org/show_bug.cgi?id=44230
+
+ * WebCoreSupport/InspectorClientQt.cpp:
+ (WebCore::InspectorClientQt::inspectorDestroyed):
+ (WebCore::InspectorClientQt::openInspectorFrontend):
+ (WebCore::InspectorClientQt::releaseFrontendPage):
+ (WebCore::InspectorFrontendClientQt::closeWindow):
+ (WebCore::InspectorFrontendClientQt::disconnectFromBackend):
+ (WebCore::InspectorFrontendClientQt::destroyInspectorView):
+ (WebCore::InspectorFrontendClientQt::inspectorClientDestroyed):
+ * WebCoreSupport/InspectorClientQt.h:
+
+2010-09-02 Andreas Kling <andreas.kling@nokia.com>
+
+ Rubber-stamped by Simon Hausmann.
+
+ [Qt] REGRESSION(r62898): tst_QWebFrame crashing
+ https://bugs.webkit.org/show_bug.cgi?id=43039
+
+ Rolling out the offending change <http://trac.webkit.org/changeset/62898>
+
+ * tests/qwebframe/tst_qwebframe.cpp:
+ (tst_QWebFrame::evalJSV):
+
2010-09-01 Mahesh Kulkarni <mahesh.kulkarni@nokia.com>
Reviewed by Laszlo Gombos.
diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
index 026866c..c1be131 100644
--- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
+++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
@@ -489,7 +489,7 @@ QVariantList DumpRenderTreeSupportQt::firstRectForCharacterRange(QWebPage* page,
if (!range)
return QVariantList();
- QRect resultRect = frame->firstRectForRange(range.get());
+ QRect resultRect = frame->editor()->firstRectForRange(range.get());
rect << resultRect.x() << resultRect.y() << resultRect.width() << resultRect.height();
return rect;
}
diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
index 59f6ac6..2d73f7f 100644
--- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
+++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
@@ -35,6 +35,7 @@
#include "CSSPropertyNames.h"
#include "FormState.h"
#include "FrameLoaderClientQt.h"
+#include "FrameNetworkingContextQt.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "DocumentLoader.h"
@@ -204,6 +205,7 @@ void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame)
{
m_webFrame = webFrame;
m_frame = frame;
+
if (!m_webFrame || !m_webFrame->page()) {
qWarning("FrameLoaderClientQt::setFrame frame without Page!");
return;
@@ -1519,6 +1521,11 @@ QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
return webFrame()->page()->chooseFile(webFrame(), oldFile);
}
+PassRefPtr<FrameNetworkingContext> FrameLoaderClientQt::createNetworkingContext()
+{
+ return FrameNetworkingContextQt::create(m_frame, m_webFrame, m_webFrame->page()->networkAccessManager());
+}
+
}
#include "moc_FrameLoaderClientQt.cpp"
diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h
index c72b82f..e506900 100644
--- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h
+++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h
@@ -35,6 +35,7 @@
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "KURL.h"
+#include <wtf/OwnPtr.h>
#include "PluginView.h"
#include "RefCounted.h"
#include "ResourceError.h"
@@ -51,6 +52,7 @@ class DocumentLoader;
class Element;
class FormState;
class NavigationAction;
+class FrameNetworkingContext;
class ResourceLoader;
struct LoadErrorResetToken;
@@ -213,6 +215,8 @@ public:
QString chooseFile(const QString& oldFile);
+ virtual PassRefPtr<FrameNetworkingContext> createNetworkingContext();
+
static bool dumpFrameLoaderCallbacks;
static bool dumpResourceLoadCallbacks;
static bool dumpResourceResponseMIMETypes;
diff --git a/WebKit/qt/WebCoreSupport/FrameNetworkingContextQt.cpp b/WebKit/qt/WebCoreSupport/FrameNetworkingContextQt.cpp
index 941cfaa..b3b0f00 100644
--- a/WebKit/qt/WebCoreSupport/FrameNetworkingContextQt.cpp
+++ b/WebKit/qt/WebCoreSupport/FrameNetworkingContextQt.cpp
@@ -17,5 +17,37 @@
Boston, MA 02110-1301, USA.
*/
-// Checking this file in empty to get the build system work out of the way.
-// Will put the code in here later.
+#include "config.h"
+
+#include "FrameNetworkingContextQt.h"
+
+#include <QNetworkAccessManager>
+#include <QObject>
+#include <QWebFrame>
+#include <QWebPage>
+
+namespace WebCore {
+
+FrameNetworkingContextQt::FrameNetworkingContextQt(Frame* frame, QObject* originatingObject, QNetworkAccessManager* networkAccessManager)
+ : FrameNetworkingContext(frame)
+ , m_originatingObject(originatingObject)
+ , m_networkAccessManager(networkAccessManager)
+{
+}
+
+PassRefPtr<FrameNetworkingContextQt> FrameNetworkingContextQt::create(Frame* frame, QObject* originatingObject, QNetworkAccessManager* networkAccessManager)
+{
+ return adoptRef(new FrameNetworkingContextQt(frame, originatingObject, networkAccessManager));
+}
+
+QObject* FrameNetworkingContextQt::originatingObject() const
+{
+ return m_originatingObject;
+}
+
+QNetworkAccessManager* FrameNetworkingContextQt::networkAccessManager() const
+{
+ return (qobject_cast<QWebFrame*>(m_originatingObject))->page()->networkAccessManager();
+}
+
+}
diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp
index e13f6c3..55aca7f 100644
--- a/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp
+++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp
@@ -96,10 +96,13 @@ public slots:
InspectorClientQt::InspectorClientQt(QWebPage* page)
: m_inspectedWebPage(page)
, m_frontendWebPage(0)
+ , m_frontendClient(0)
{}
void InspectorClientQt::inspectorDestroyed()
{
+ if (m_frontendClient)
+ m_frontendClient->inspectorClientDestroyed();
delete this;
}
@@ -131,13 +134,15 @@ void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController*)
m_inspectedWebPage->d->inspectorFrontend = inspectorView;
inspector->d->setFrontend(inspectorView);
- inspectorView->page()->d->page->inspectorController()->setInspectorFrontendClient(new InspectorFrontendClientQt(m_inspectedWebPage, inspectorView, this));
+ m_frontendClient = new InspectorFrontendClientQt(m_inspectedWebPage, inspectorView, this);
+ inspectorView->page()->d->page->inspectorController()->setInspectorFrontendClient(m_frontendClient);
m_frontendWebPage = inspectorPage;
}
void InspectorClientQt::releaseFrontendPage()
{
m_frontendWebPage = 0;
+ m_frontendClient = 0;
}
void InspectorClientQt::highlight(Node*)
@@ -250,6 +255,13 @@ InspectorFrontendClientQt::InspectorFrontendClientQt(QWebPage* inspectedWebPage,
{
}
+InspectorFrontendClientQt::~InspectorFrontendClientQt()
+{
+ ASSERT(m_destroyingInspectorView);
+ if (m_inspectorClient)
+ m_inspectorClient->releaseFrontendPage();
+}
+
void InspectorFrontendClientQt::frontendLoaded()
{
InspectorFrontendClientLocal::frontendLoaded();
@@ -275,19 +287,12 @@ void InspectorFrontendClientQt::bringToFront()
void InspectorFrontendClientQt::closeWindow()
{
- if (m_destroyingInspectorView)
- return;
- m_destroyingInspectorView = true;
-
- // Clear reference from QWebInspector to the frontend view.
- m_inspectedWebPage->d->getOrCreateInspector()->d->setFrontend(0);
-#if ENABLE(INSPECTOR)
- m_inspectedWebPage->d->inspectorController()->disconnectFrontend();
-#endif
- m_inspectorClient->releaseFrontendPage();
+ destroyInspectorView(true);
+}
- // Clear pointer before deleting WebView to avoid recursive calls to its destructor.
- OwnPtr<QWebView> inspectorView = m_inspectorView.release();
+void InspectorFrontendClientQt::disconnectFromBackend()
+{
+ destroyInspectorView(false);
}
void InspectorFrontendClientQt::attachWindow()
@@ -319,6 +324,35 @@ void InspectorFrontendClientQt::updateWindowTitle()
}
}
+void InspectorFrontendClientQt::destroyInspectorView(bool notifyInspectorController)
+{
+ if (m_destroyingInspectorView)
+ return;
+ m_destroyingInspectorView = true;
+
+ // Inspected page may have already been destroyed.
+ if (m_inspectedWebPage) {
+ // Clear reference from QWebInspector to the frontend view.
+ m_inspectedWebPage->d->getOrCreateInspector()->d->setFrontend(0);
+ }
+
+#if ENABLE(INSPECTOR)
+ if (notifyInspectorController)
+ m_inspectedWebPage->d->inspectorController()->disconnectFrontend();
+#endif
+ if (m_inspectorClient)
+ m_inspectorClient->releaseFrontendPage();
+
+ // Clear pointer before deleting WebView to avoid recursive calls to its destructor.
+ OwnPtr<QWebView> inspectorView = m_inspectorView.release();
+}
+
+void InspectorFrontendClientQt::inspectorClientDestroyed()
+{
+ m_inspectorClient = 0;
+ m_inspectedWebPage = 0;
+}
+
}
#include "InspectorClientQt.moc"
diff --git a/WebKit/qt/WebCoreSupport/InspectorClientQt.h b/WebKit/qt/WebCoreSupport/InspectorClientQt.h
index 9526c88..0074159 100644
--- a/WebKit/qt/WebCoreSupport/InspectorClientQt.h
+++ b/WebKit/qt/WebCoreSupport/InspectorClientQt.h
@@ -41,6 +41,7 @@ class QWebPage;
class QWebView;
namespace WebCore {
+class InspectorFrontendClientQt;
class Node;
class Page;
@@ -65,11 +66,13 @@ public:
private:
QWebPage* m_inspectedWebPage;
QWebPage* m_frontendWebPage;
+ InspectorFrontendClientQt* m_frontendClient;
};
class InspectorFrontendClientQt : public InspectorFrontendClientLocal {
public:
InspectorFrontendClientQt(QWebPage* inspectedWebPage, PassOwnPtr<QWebView> inspectorView, InspectorClientQt* inspectorClient);
+ virtual ~InspectorFrontendClientQt();
virtual void frontendLoaded();
@@ -79,6 +82,7 @@ public:
virtual void bringToFront();
virtual void closeWindow();
+ virtual void disconnectFromBackend();
virtual void attachWindow();
virtual void detachWindow();
@@ -87,8 +91,11 @@ public:
virtual void inspectedURLChanged(const String& newURL);
+ void inspectorClientDestroyed();
+
private:
void updateWindowTitle();
+ void destroyInspectorView(bool notifyInspectorController);
QWebPage* m_inspectedWebPage;
OwnPtr<QWebView> m_inspectorView;
QString m_inspectedURL;
diff --git a/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
index 98ce663..2c63739 100644
--- a/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
+++ b/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
@@ -38,7 +38,6 @@
#include <qsslerror.h>
#endif
#include "../util.h"
-#include "../WebCoreSupport/DumpRenderTreeSupportQt.h"
struct CustomType {
QString string;
@@ -572,11 +571,9 @@ public slots:
void cleanup();
private slots:
+ void getSetStaticProperty();
void getSetDynamicProperty();
- void getSetDynamicProperty_data();
void getSetChildren();
- void getSetChildren_data();
- void getSetStaticProperty();
void callQtInvokable();
void connectAndDisconnect();
void classEnums();
@@ -674,10 +671,6 @@ private:
evalJS("delete retvalue; delete typevalue");
return ret;
}
- void garbageCollectJS()
- {
- DumpRenderTreeSupportQt::garbageCollectorCollect();
- }
QObject* firstChildByClassName(QObject* parent, const char* className) {
const QObjectList & children = parent->children();
foreach (QObject* child, children) {
@@ -954,8 +947,6 @@ void tst_QWebFrame::getSetStaticProperty()
void tst_QWebFrame::getSetDynamicProperty()
{
- QFETCH(bool, garbageCollect);
-
// initially the object does not have the property
// In WebKit, RuntimeObjects do not inherit Object, so don't have hasOwnProperty
@@ -967,34 +958,11 @@ void tst_QWebFrame::getSetDynamicProperty()
//QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sTrue);
QCOMPARE(evalJS("typeof myObject.dynamicProperty != 'undefined'"), sTrue);
QCOMPARE(evalJS("myObject.dynamicProperty == 123"), sTrue);
- if( garbageCollect ) {
- garbageCollectJS();
- QCOMPARE(evalJS("typeof myObject.dynamicProperty != 'undefined'"), sTrue);
- }
// property change in script should be reflected in C++
QCOMPARE(evalJS("myObject.dynamicProperty = 'foo';"
"myObject.dynamicProperty"), QLatin1String("foo"));
QCOMPARE(m_myObject->property("dynamicProperty").toString(), QLatin1String("foo"));
- if( garbageCollect ) {
- garbageCollectJS();
- QCOMPARE(m_myObject->property("dynamicProperty").toString(), QLatin1String("foo"));
- }
-
- // add a dynamic property in C++ to another QObject
- QObject* propertyObject = new QObject(m_myObject);
- QCOMPARE(m_myObject->setProperty("dynamicObjectProperty", qVariantFromValue(propertyObject)), false);
- QCOMPARE(evalJS("typeof myObject.dynamicObjectProperty != 'undefined'"), sTrue);
- evalJS("myObject.dynamicObjectProperty.jsProperty = 123");
- QCOMPARE(evalJS("myObject.dynamicObjectProperty.jsProperty == 123"), sTrue);
- if( garbageCollect ) {
- garbageCollectJS();
- QCOMPARE(evalJS("typeof myObject.dynamicObjectProperty != 'undefined'"), sTrue);
- QCOMPARE(evalJS("myObject.dynamicObjectProperty.jsProperty == 123"), sTrue);
- }
- QCOMPARE(m_myObject->setProperty("dynamicObjectProperty", QVariant()), false);
- delete propertyObject;
- QCOMPARE(evalJS("typeof myObject.dynamicObjectProperty == 'undefined'"), sTrue);
// delete the property (XFAIL - can't delete properties)
QEXPECT_FAIL("", "can't delete properties", Continue);
@@ -1005,21 +973,10 @@ void tst_QWebFrame::getSetDynamicProperty()
// QCOMPARE(evalJS("myObject.hasOwnProperty('dynamicProperty')"), sFalse);
QCOMPARE(evalJS("typeof myObject.dynamicProperty"), sUndefined);
*/
-
- evalJS("myObject.dynamicProperty = undefined");
-}
-
-void tst_QWebFrame::getSetDynamicProperty_data()
-{
- QTest::addColumn<bool>("garbageCollect");
- QTest::newRow("with garbageCollect") << true;
- QTest::newRow("without garbageCollect") << false;
}
void tst_QWebFrame::getSetChildren()
{
- QFETCH(bool, garbageCollect);
-
// initially the object does not have the child
// (again, no hasOwnProperty)
@@ -1031,27 +988,12 @@ void tst_QWebFrame::getSetChildren()
child->setObjectName("child");
// QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sTrue);
QCOMPARE(evalJS("typeof myObject.child != 'undefined'"), sTrue);
- evalJS("myObject.child.jsProperty = 123");
- QCOMPARE(evalJS("myObject.child.jsProperty == 123"), sTrue);
-
- if( garbageCollect ) {
- garbageCollectJS();
- QCOMPARE(evalJS("typeof myObject.child != 'undefined'"), sTrue);
- QCOMPARE(evalJS("myObject.child.jsProperty == 123"), sTrue);
- }
// add a grandchild
MyQObject* grandChild = new MyQObject(child);
grandChild->setObjectName("grandChild");
// QCOMPARE(evalJS("myObject.child.hasOwnProperty('grandChild')"), sTrue);
QCOMPARE(evalJS("typeof myObject.child.grandChild != 'undefined'"), sTrue);
- evalJS("myObject.child.grandChild.jsProperty = 123");
- evalJS("myObject.child.grandChild.jsProperty = 123");
- if( garbageCollect ) {
- garbageCollectJS();
- QCOMPARE(evalJS("typeof myObject.child.grandChild != 'undefined'"), sTrue);
- QCOMPARE(evalJS("myObject.child.grandChild.jsProperty == 123"), sTrue);
- }
// delete grandchild
delete grandChild;
@@ -1062,18 +1004,6 @@ void tst_QWebFrame::getSetChildren()
delete child;
// QCOMPARE(evalJS("myObject.hasOwnProperty('child')"), sFalse);
QCOMPARE(evalJS("typeof myObject.child == 'undefined'"), sTrue);
- if( garbageCollect ) {
- garbageCollectJS();
- QCOMPARE(evalJS("typeof myObject.child == 'undefined'"), sTrue);
- }
-}
-
-
-void tst_QWebFrame::getSetChildren_data()
-{
- QTest::addColumn<bool>("garbageCollect");
- QTest::newRow("with garbageCollect") << true;
- QTest::newRow("without garbageCollect") << false;
}
Q_DECLARE_METATYPE(QVector<int>)
@@ -1740,7 +1670,7 @@ void tst_QWebFrame::connectAndDisconnect()
m_myObject->emitMySignal();
QCOMPARE(m_myObject->qtFunctionInvoked(), 20);
evalJS("myObject = null");
- garbageCollectJS();
+ evalJS("gc()");
m_myObject->resetQtFunctionInvoked();
m_myObject->emitMySignal();
QCOMPARE(m_myObject->qtFunctionInvoked(), 20);
diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog
index b3877dc..b7e49cf 100644
--- a/WebKit/win/ChangeLog
+++ b/WebKit/win/ChangeLog
@@ -1,3 +1,142 @@
+2010-09-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Scrollbars fail to render in composited iframes.
+ https://bugs.webkit.org/show_bug.cgi?id=45335
+
+ Use LocalWindowsContext when painting scrollbars.
+
+ * WebCoreSupport/WebChromeClient.cpp:
+ (WebChromeClient::paintCustomScrollbar):
+ (WebChromeClient::paintCustomScrollCorner):
+
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * WebCoreSupport/WebContextMenuClient.cpp:
+ (WebContextMenuClient::searchWithGoogle):
+ * WebFrame.cpp:
+ (WebFrame::selectedString):
+ * WebView.cpp:
+ (WebView::selectedText):
+ (WebView::prepareCandidateWindow):
+ (WebView::onIMERequestCharPosition):
+ Changed call sites to use editor().
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Not reviewed, build fix.
+
+ * WebScrollBar.cpp:
+ (WebScrollBar::setScrollOffsetFromAnimation):
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Not reviewed, build fix.
+
+ * WebScrollBar.cpp:
+ (WebScrollBar::scrollSize):
+ (WebScrollBar::setScrollOffsetFromAnimation):
+
+2010-09-08 Peter Kasting <pkasting@google.com>
+
+ Not reviewed, build fix.
+
+ * WebScrollBar.cpp:
+ (WebScrollBar::setValue):
+ (WebScrollBar::scrollSize):
+ (WebScrollBar::setScrollOffsetFromAnimation):
+ * WebScrollBar.h:
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Attempted Window build fix.
+
+ * WebDataSource.cpp:
+ (WebDataSource::subresourceForURL):
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Rubber-stamped by Eric Seidel.
+
+ Rename DocLoader to CachedResourceLoader because that's what it does.
+
+ * WebDataSource.cpp:
+
+2010-09-07 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Clean up a potential resource leak.
+ https://bugs.webkit.org/show_bug.cgi?id=45198
+
+ Several bitmap device context were being created and used,
+ and destroyed without returning the context to its original
+ state. This showed up as bitmap leaks in BoundsChecker.
+
+ * FullscreenVideoController.cpp:
+ * WebView.cpp:
+ (WebView::scrollBackingStore):
+ (WebView::paint):
+
+2010-09-06 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Rename SecurityOrigin::canLoad to canDisplay
+ https://bugs.webkit.org/show_bug.cgi?id=45214
+
+ Propagate name change.
+
+ * WebFrame.cpp:
+ (WebFrame::allowsFollowingLink):
+
+2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Darin Adler.
+
+ Add NetworkingContext to avoid layer violations
+ https://bugs.webkit.org/show_bug.cgi?id=42292
+
+ Add Win's specific implementation of NetworkingContext.
+
+ * WebCoreSupport/WebFrameNetworkingContext.cpp:
+ (WebFrameNetworkingContext::create):
+ (WebFrameNetworkingContext::userAgent):
+ (WebFrameNetworkingContext::referrer):
+ * WebFrame.cpp:
+ (WebFrame::createNetworkingContext):
+ * WebFrame.h:
+
+2010-09-03 Adam Roben <aroben@apple.com>
+
+ Attempt to fixing Windows nightlies again
+
+ The fix in r66438 should be sufficient, but we have to touch
+ WebKit.idl to force that change to be picked up by the build.
+
+ * Interfaces/WebKit.idl: Touched this file to force a build.
+
+2010-09-02 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by PavelFeldman.
+
+ REGRESSION: Crash occurs at objc_msgSend when closing a window that is displaying the web inspector
+ https://bugs.webkit.org/show_bug.cgi?id=44230
+
+ * WebCoreSupport/WebInspectorClient.cpp:
+ (WebInspectorFrontendClient::~WebInspectorFrontendClient):
+ (WebInspectorFrontendClient::closeWindow):
+ (WebInspectorFrontendClient::disconnectFromBackend):
+ (WebInspectorFrontendClient::closeWindowWithoutNotifications):
+ (WebInspectorFrontendClient::destroyInspectorView):
+ * WebCoreSupport/WebInspectorClient.h:
+
2010-09-01 Jessie Berlin <jberlin@apple.com>
Reviewed by Adam Roben.
diff --git a/WebKit/win/FullscreenVideoController.cpp b/WebKit/win/FullscreenVideoController.cpp
index 3aeb1ba..4b50889 100644
--- a/WebKit/win/FullscreenVideoController.cpp
+++ b/WebKit/win/FullscreenVideoController.cpp
@@ -476,7 +476,7 @@ void FullscreenVideoController::draw()
HDC windowDC = GetDC(m_hudWindow);
HDC bitmapDC = CreateCompatibleDC(windowDC);
::ReleaseDC(m_hudWindow, windowDC);
- SelectObject(bitmapDC, m_bitmap.get());
+ HGDIOBJ oldBitmap = SelectObject(bitmapDC, m_bitmap.get());
GraphicsContext context(bitmapDC, true);
@@ -543,6 +543,7 @@ void FullscreenVideoController::draw()
context.restore();
+ ::SelectObject(bitmapDC, oldBitmap);
::DeleteDC(bitmapDC);
}
diff --git a/WebKit/win/Interfaces/WebKit.idl b/WebKit/win/Interfaces/WebKit.idl
index d25cdfe..98f5da8 100644
--- a/WebKit/win/Interfaces/WebKit.idl
+++ b/WebKit/win/Interfaces/WebKit.idl
@@ -300,3 +300,4 @@ library WebKit
[default] interface IWebUserContentURLPattern;
}
}
+
diff --git a/WebKit/win/WebCoreSupport/WebChromeClient.cpp b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
index d5aea25..7a025a7 100644
--- a/WebKit/win/WebCoreSupport/WebChromeClient.cpp
+++ b/WebKit/win/WebCoreSupport/WebChromeClient.cpp
@@ -53,6 +53,7 @@
#endif
#include <WebCore/HTMLNames.h>
#include <WebCore/Icon.h>
+#include <WebCore/LocalWindowsContext.h>
#include <WebCore/LocalizedStrings.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
@@ -705,10 +706,9 @@ bool WebChromeClient::paintCustomScrollbar(GraphicsContext* context, const Float
webState |= WebPressedScrollbarState;
RECT webRect = enclosingIntRect(rect);
- HDC hDC = context->getWindowsContext(webRect);
- HRESULT hr = delegate->paintCustomScrollbar(m_webView, hDC, webRect, webSize, webState, webPressedPart,
+ LocalWindowsContext windowsContext(context, webRect);
+ HRESULT hr = delegate->paintCustomScrollbar(m_webView, windowsContext.hdc(), webRect, webSize, webState, webPressedPart,
vertical, value, proportion, webParts);
- context->releaseWindowsContext(hDC, webRect);
return SUCCEEDED(hr);
}
@@ -722,9 +722,8 @@ bool WebChromeClient::paintCustomScrollCorner(GraphicsContext* context, const Fl
return false;
RECT webRect = enclosingIntRect(rect);
- HDC hDC = context->getWindowsContext(webRect);
- HRESULT hr = delegate->paintCustomScrollCorner(m_webView, hDC, webRect);
- context->releaseWindowsContext(hDC, webRect);
+ LocalWindowsContext windowsContext(context, webRect);
+ HRESULT hr = delegate->paintCustomScrollCorner(m_webView, windowsContext.hdc(), webRect);
return SUCCEEDED(hr);
}
diff --git a/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp b/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp
index 078b725..ca0374a 100644
--- a/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp
+++ b/WebKit/win/WebCoreSupport/WebContextMenuClient.cpp
@@ -131,7 +131,7 @@ void WebContextMenuClient::downloadURL(const KURL& url)
void WebContextMenuClient::searchWithGoogle(const Frame* frame)
{
- String searchString = frame->selectedText();
+ String searchString = frame->editor()->selectedText();
searchString.stripWhiteSpace();
String encoded = encodeWithURLEscapeSequences(searchString);
encoded.replace("%20", "+");
diff --git a/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp b/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp
index 941cfaa..9fcd4b1 100644
--- a/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp
+++ b/WebKit/win/WebCoreSupport/WebFrameNetworkingContext.cpp
@@ -17,5 +17,23 @@
Boston, MA 02110-1301, USA.
*/
-// Checking this file in empty to get the build system work out of the way.
-// Will put the code in here later.
+#include "config.h"
+
+#include "WebFrameNetworkingContext.h"
+
+using namespace WebCore;
+
+PassRefPtr<WebFrameNetworkingContext> WebFrameNetworkingContext::create(Frame* frame, const String& userAgent)
+{
+ return adoptRef(new WebFrameNetworkingContext(frame, userAgent));
+}
+
+String WebFrameNetworkingContext::userAgent() const
+{
+ return m_userAgent;
+}
+
+String WebFrameNetworkingContext::referrer() const
+{
+ return frame()->loader()->referrer();
+}
diff --git a/WebKit/win/WebCoreSupport/WebInspectorClient.cpp b/WebKit/win/WebCoreSupport/WebInspectorClient.cpp
index 34fb827..1b79dde 100644
--- a/WebKit/win/WebCoreSupport/WebInspectorClient.cpp
+++ b/WebKit/win/WebCoreSupport/WebInspectorClient.cpp
@@ -228,7 +228,7 @@ WebInspectorFrontendClient::WebInspectorFrontendClient(WebView* inspectedWebView
WebInspectorFrontendClient::~WebInspectorFrontendClient()
{
- destroyInspectorView();
+ destroyInspectorView(true);
}
void WebInspectorFrontendClient::frontendLoaded()
@@ -260,7 +260,12 @@ void WebInspectorFrontendClient::bringToFront()
void WebInspectorFrontendClient::closeWindow()
{
- destroyInspectorView();
+ destroyInspectorView(true);
+}
+
+void WebInspectorFrontendClient::disconnectFromBackend()
+{
+ destroyInspectorView(false);
}
void WebInspectorFrontendClient::attachWindow()
@@ -344,8 +349,6 @@ void WebInspectorFrontendClient::closeWindowWithoutNotifications()
HWND hostWindow;
if (SUCCEEDED(m_inspectedWebView->hostWindow((OLE_HANDLE*)&hostWindow)))
SendMessage(hostWindow, WM_SIZE, 0, 0);
-
- m_inspectorClient->updateHighlight();
}
void WebInspectorFrontendClient::showWindowWithoutNotifications()
@@ -397,16 +400,20 @@ void WebInspectorFrontendClient::showWindowWithoutNotifications()
m_inspectorClient->updateHighlight();
}
-void WebInspectorFrontendClient::destroyInspectorView()
+void WebInspectorFrontendClient::destroyInspectorView(bool notifyInspectorController)
{
if (m_destroyingInspectorView)
return;
m_destroyingInspectorView = true;
- m_inspectedWebView->page()->inspectorController()->disconnectFrontend();
closeWindowWithoutNotifications();
- m_inspectorClient->frontendClosing();
+
+ if (notifyInspectorController) {
+ m_inspectedWebView->page()->inspectorController()->disconnectFrontend();
+ m_inspectorClient->updateHighlight();
+ m_inspectorClient->frontendClosing();
+ }
::DestroyWindow(m_frontendHwnd);
}
diff --git a/WebKit/win/WebCoreSupport/WebInspectorClient.h b/WebKit/win/WebCoreSupport/WebInspectorClient.h
index 4da3984..0c38247 100644
--- a/WebKit/win/WebCoreSupport/WebInspectorClient.h
+++ b/WebKit/win/WebCoreSupport/WebInspectorClient.h
@@ -93,6 +93,7 @@ public:
virtual void bringToFront();
virtual void closeWindow();
+ virtual void disconnectFromBackend();
virtual void attachWindow();
virtual void detachWindow();
@@ -106,7 +107,7 @@ private:
void closeWindowWithoutNotifications();
void showWindowWithoutNotifications();
- void destroyInspectorView();
+ void destroyInspectorView(bool notifyInspectorController);
void updateWindowTitle();
diff --git a/WebKit/win/WebDataSource.cpp b/WebKit/win/WebDataSource.cpp
index 566f174..0350373 100644
--- a/WebKit/win/WebDataSource.cpp
+++ b/WebKit/win/WebDataSource.cpp
@@ -39,7 +39,7 @@
#include "WebResource.h"
#include "WebURLResponse.h"
#include <WebCore/BString.h>
-#include <WebCore/DocLoader.h>
+#include <WebCore/CachedResourceLoader.h>
#include <WebCore/Document.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameLoader.h>
@@ -297,7 +297,7 @@ HRESULT STDMETHODCALLTYPE WebDataSource::subresourceForURL(
if (!doc)
return E_FAIL;
- CachedResource *cachedResource = doc->docLoader()->cachedResource(String(url));
+ CachedResource *cachedResource = doc->cachedResourceLoader()->cachedResource(String(url));
if (!cachedResource)
return E_FAIL;
diff --git a/WebKit/win/WebFrame.cpp b/WebKit/win/WebFrame.cpp
index d12989b..014ea15 100644
--- a/WebKit/win/WebFrame.cpp
+++ b/WebKit/win/WebFrame.cpp
@@ -42,6 +42,7 @@
#include "WebDownload.h"
#include "WebEditorClient.h"
#include "WebError.h"
+#include "WebFrameNetworkingContext.h"
#include "WebFramePolicyListener.h"
#include "WebHistory.h"
#include "WebHistoryItem.h"
@@ -1044,7 +1045,7 @@ HRESULT STDMETHODCALLTYPE WebFrame::selectedString(
if (!coreFrame)
return E_FAIL;
- String text = coreFrame->displayStringModifiedByEncoding(coreFrame->selectedText());
+ String text = coreFrame->displayStringModifiedByEncoding(coreFrame->editor()->selectedText());
*result = BString(text).release();
return S_OK;
@@ -1352,7 +1353,7 @@ HRESULT WebFrame::allowsFollowingLink(BSTR url, BOOL* result)
if (!frame)
return E_FAIL;
- *result = SecurityOrigin::canLoad(MarshallingHelpers::BSTRToKURL(url), String(), frame->document());
+ *result = SecurityOrigin::canDisplay(MarshallingHelpers::BSTRToKURL(url), String(), frame->document());
return S_OK;
}
@@ -2614,3 +2615,7 @@ void WebFrame::updateBackground()
coreFrame->view()->updateBackgroundRecursively(backgroundColor, webView()->transparent());
}
+PassRefPtr<FrameNetworkingContext> WebFrame::createNetworkingContext()
+{
+ return WebFrameNetworkingContext::create(core(this), userAgent(url()));
+}
diff --git a/WebKit/win/WebFrame.h b/WebKit/win/WebFrame.h
index 24a7e2b..f4795c8 100644
--- a/WebKit/win/WebFrame.h
+++ b/WebKit/win/WebFrame.h
@@ -343,6 +343,8 @@ public:
virtual void registerForIconNotification(bool listen);
+ virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext();
+
// WebFrame
PassRefPtr<WebCore::Frame> init(IWebView*, WebCore::Page*, WebCore::HTMLFrameOwnerElement*);
WebCore::Frame* impl();
diff --git a/WebKit/win/WebScrollBar.cpp b/WebKit/win/WebScrollBar.cpp
index ccf40d9..8613c1c 100644
--- a/WebKit/win/WebScrollBar.cpp
+++ b/WebKit/win/WebScrollBar.cpp
@@ -143,7 +143,7 @@ HRESULT STDMETHODCALLTYPE WebScrollBar::setRect(
HRESULT STDMETHODCALLTYPE WebScrollBar::setValue(
/* [in] */ int value)
{
- m_scrollBar->setValue(value);
+ m_scrollBar->setValue(value, Scrollbar::NotFromScrollAnimator);
return S_OK;
}
@@ -252,6 +252,16 @@ HRESULT STDMETHODCALLTYPE WebScrollBar::scroll(
}
// ScrollbarClient -------------------------------------------------------
+int WebScrollBar::scrollSize(ScrollbarOrientation orientation) const
+{
+ return (orientation == m_scrollBar->orientation()) ? (m_scrollBar->totalSize() - m_scrollBar->visibleSize()) : 0;
+}
+
+void WebScrollBar::setScrollOffsetFromAnimation(const IntPoint& offset)
+{
+ m_scrollBar->setValue((m_scrollBar->orientation() == HorizontalScrollbar) ? offset.x() : offset.y(), Scrollbar::FromScrollAnimator);
+}
+
void WebScrollBar::valueChanged(Scrollbar* scrollBar)
{
if (m_scrollBar != scrollBar) {
diff --git a/WebKit/win/WebScrollBar.h b/WebKit/win/WebScrollBar.h
index 0fed8a3..90f2491 100644
--- a/WebKit/win/WebScrollBar.h
+++ b/WebKit/win/WebScrollBar.h
@@ -116,6 +116,8 @@ public:
protected:
// ScrollbarClient
+ virtual int scrollSize(ScrollbarOrientation orientation) const;
+ virtual void setScrollOffsetFromAnimation(const IntPoint&);
virtual void valueChanged(Scrollbar*);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
diff --git a/WebKit/win/WebView.cpp b/WebKit/win/WebView.cpp
index 5aa4fc4..0a1e334 100644
--- a/WebKit/win/WebView.cpp
+++ b/WebKit/win/WebView.cpp
@@ -826,7 +826,7 @@ void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const Int
// Collect our device context info and select the bitmap to scroll.
HDC windowDC = ::GetDC(m_viewWindow);
HDC bitmapDC = ::CreateCompatibleDC(windowDC);
- ::SelectObject(bitmapDC, m_backingStoreBitmap->handle());
+ HGDIOBJ oldBitmap = ::SelectObject(bitmapDC, m_backingStoreBitmap->handle());
// Scroll the bitmap.
RECT scrollRectWin(scrollViewRect);
@@ -848,6 +848,7 @@ void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const Int
updateBackingStore(frameView, bitmapDC, false);
// Clean up.
+ ::SelectObject(bitmapDC, oldBitmap);
::DeleteDC(bitmapDC);
::ReleaseDC(m_viewWindow, windowDC);
}
@@ -987,7 +988,7 @@ void WebView::paint(HDC dc, LPARAM options)
m_paintCount++;
HDC bitmapDC = ::CreateCompatibleDC(hdc);
- ::SelectObject(bitmapDC, m_backingStoreBitmap->handle());
+ HGDIOBJ oldBitmap = ::SelectObject(bitmapDC, m_backingStoreBitmap->handle());
// Update our backing store if needed.
updateBackingStore(frameView, bitmapDC, backingStoreCompletelyDirty, windowsToPaint);
@@ -1012,6 +1013,7 @@ void WebView::paint(HDC dc, LPARAM options)
updateRootLayerContents();
#endif
+ ::SelectObject(bitmapDC, oldBitmap);
::DeleteDC(bitmapDC);
if (!dc)
@@ -3545,7 +3547,7 @@ HRESULT STDMETHODCALLTYPE WebView::selectedText(
if (!focusedFrame)
return E_FAIL;
- String frameSelectedText = focusedFrame->selectedText();
+ String frameSelectedText = focusedFrame->editor()->selectedText();
*text = SysAllocStringLen(frameSelectedText.characters(), frameSelectedText.length());
if (!*text && frameSelectedText.length())
return E_OUTOFMEMORY;
@@ -5265,7 +5267,7 @@ void WebView::prepareCandidateWindow(Frame* targetFrame, HIMC hInputContext)
if (RefPtr<Range> range = targetFrame->selection()->selection().toNormalizedRange()) {
ExceptionCode ec = 0;
RefPtr<Range> tempRange = range->cloneRange(ec);
- caret = targetFrame->firstRectForRange(tempRange.get());
+ caret = targetFrame->editor()->firstRectForRange(tempRange.get());
}
caret = targetFrame->view()->contentsToWindow(caret);
CANDIDATEFORM form;
@@ -5536,7 +5538,7 @@ LRESULT WebView::onIMERequestCharPosition(Frame* targetFrame, IMECHARPOSITION* c
ExceptionCode ec = 0;
RefPtr<Range> tempRange = range->cloneRange(ec);
tempRange->setStart(tempRange->startContainer(ec), tempRange->startOffset(ec) + charPos->dwCharPos, ec);
- caret = targetFrame->firstRectForRange(tempRange.get());
+ caret = targetFrame->editor()->firstRectForRange(tempRange.get());
}
caret = targetFrame->view()->contentsToWindow(caret);
charPos->pt.x = caret.x();
diff --git a/WebKit/wx/ChangeLog b/WebKit/wx/ChangeLog
index 757981f..8edf46f 100644
--- a/WebKit/wx/ChangeLog
+++ b/WebKit/wx/ChangeLog
@@ -1,3 +1,14 @@
+2010-09-08 Darin Adler <darin@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Move functions from Frame to Editor as planned
+ https://bugs.webkit.org/show_bug.cgi?id=45218
+
+ * WebFrame.cpp:
+ (wxWebFrame::FindString):
+ Changed call sites to use editor().
+
2010-08-31 Dave Hyatt <hyatt@apple.com>
Reviewed by Sam Weinig.
diff --git a/WebKit/wx/WebFrame.cpp b/WebKit/wx/WebFrame.cpp
index fe45eea..3a556d5 100644
--- a/WebKit/wx/WebFrame.cpp
+++ b/WebKit/wx/WebFrame.cpp
@@ -273,7 +273,7 @@ wxString wxWebFrame::GetEditCommandValue(const wxString& command) const
bool wxWebFrame::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
{
if (m_impl->frame)
- return m_impl->frame->findString(string, forward, caseSensitive, wrapSelection, startInSelection);
+ return m_impl->frame->editor()->findString(string, forward, caseSensitive, wrapSelection, startInSelection);
return false;
}
diff --git a/WebKitTools/CMakeListsEfl.txt b/WebKitTools/CMakeListsEfl.txt
new file mode 100644
index 0000000..b9086ac
--- /dev/null
+++ b/WebKitTools/CMakeListsEfl.txt
@@ -0,0 +1,56 @@
+SET(EWebLauncher_SOURCES
+ ${WebKit_THEME}
+ ${WEBKITTOOLS_DIR}/EWebLauncher/main.c
+)
+
+SET(EWebLauncher_LIBRARIES
+ ${JavaScriptCore_LIBRARY_NAME}
+ ${WebCore_LIBRARY_NAME}
+ ${WebKit_LIBRARY_NAME}
+ ${Cairo_LIBRARIES}
+ ${ECORE_X_LIBRARIES}
+ ${EDJE_LIBRARIES}
+ ${EFLDEPS_LIBRARIES}
+ ${EVAS_LIBRARIES}
+ ${LIBXML2_LIBRARIES}
+ ${LIBXSLT_LIBRARIES}
+ ${SQLITE_LIBRARIES}
+)
+
+SET(EWebLauncher_INCLUDE_DIRECTORIES
+ "${WEBKIT_DIR}/efl/ewk"
+ ${Cairo_INCLUDE_DIRS}
+ ${EDJE_INCLUDE_DIRS}
+ ${EFLDEPS_INCLUDE_DIRS}
+ ${EVAS_INCLUDE_DIRS}
+)
+
+SET(EWebLauncher_LINK_FLAGS
+ ${ECORE_X_LDFLAGS}
+ ${EDJE_LDFLAGS}
+ ${EFLDEPS_LDFLAGS}
+ ${EVAS_LDFLAGS}
+)
+
+IF (ENABLE_GLIB_SUPPORT)
+ LIST(APPEND EWebLauncher_LIBRARIES
+ ${Gdk_LIBRARIES}
+ ${Glib_LIBRARIES}
+ ${Gthread_LIBRARIES}
+ )
+ENDIF ()
+
+IF (WTF_USE_SOUP)
+ LIST(APPEND EWebLauncher_LIBRARIES ${LIBSOUP24_LIBRARIES})
+ LIST(APPEND EWebLauncher_LINK_FLAGS ${LIBSOUP24_LDFLAGS})
+ENDIF ()
+
+IF (WTF_USE_CURL)
+ LIST(APPEND EWebLauncher_LIBRARIES ${CURL_LIBRARIES})
+ LIST(APPEND EWebLauncher_LINK_FLAGS ${CURL_LDFLAGS})
+ENDIF ()
+
+INCLUDE_DIRECTORIES(${EWebLauncher_INCLUDE_DIRECTORIES})
+ADD_EXECUTABLE(Programs/EWebLauncher ${EWebLauncher_SOURCES})
+TARGET_LINK_LIBRARIES(Programs/EWebLauncher ${EWebLauncher_LIBRARIES})
+ADD_TARGET_PROPERTIES(Programs/EWebLauncher LINK_FLAGS "${EWebLauncher_LINK_FLAGS}")
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 905a8e2..aa525b5 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,894 @@
+2010-09-09 Hans Wennborg <hans@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Hook up LayoutTestController.setMockDeviceOrientation() in Chromium DumpRenderTree.
+ https://bugs.webkit.org/show_bug.cgi?id=45460
+
+ This enables DumpRenderTree to run layout tests for DeviceOrientation.
+
+ Also declare the LayoutTestController destructor out-of-line.
+ Otherwise the implicit destructor would cause compiler errors because
+ of the OwnPtr<WebKit::WebDeviceOrientationClientMock> member.
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::~LayoutTestController):
+ (LayoutTestController::setMockDeviceOrientation):
+ (LayoutTestController::deviceOrientationClient):
+ * DumpRenderTree/chromium/LayoutTestController.h:
+ * DumpRenderTree/chromium/WebViewHost.cpp:
+ (WebViewHost::deviceOrientationClient):
+ * DumpRenderTree/chromium/WebViewHost.h:
+
+2010-09-09 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r67119.
+ http://trac.webkit.org/changeset/67119
+ https://bugs.webkit.org/show_bug.cgi?id=45505
+
+ Extra newlines in results (Requested by tony^work on #webkit).
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::LayoutTestController):
+ (LayoutTestController::reset):
+ * DumpRenderTree/chromium/LayoutTestController.h:
+ * DumpRenderTree/chromium/TestShell.h:
+ * DumpRenderTree/chromium/WebViewHost.cpp:
+ (printResponseDescription):
+ (printNodeDescription):
+ (printRangeDescription):
+ (WebViewHost::shouldBeginEditing):
+ (WebViewHost::shouldEndEditing):
+ (WebViewHost::shouldInsertNode):
+ (WebViewHost::shouldChangeSelectedRange):
+ (WebViewHost::shouldDeleteRange):
+ (WebViewHost::shouldApplyStyle):
+ (WebViewHost::didBeginEditing):
+ (WebViewHost::didChangeSelection):
+ (WebViewHost::didChangeContents):
+ (WebViewHost::didEndEditing):
+ (WebViewHost::decidePolicyForNavigation):
+ (WebViewHost::didCancelClientRedirect):
+ (WebViewHost::didStartProvisionalLoad):
+ (WebViewHost::didReceiveServerRedirectForProvisionalLoad):
+ (WebViewHost::didFailProvisionalLoad):
+ (WebViewHost::didCommitProvisionalLoad):
+ (WebViewHost::didFinishDocumentLoad):
+ (WebViewHost::didHandleOnloadEvents):
+ (WebViewHost::didFailLoad):
+ (WebViewHost::didFinishLoad):
+ (WebViewHost::didChangeLocationWithinPage):
+ (WebViewHost::willSendRequest):
+ (WebViewHost::didReceiveResponse):
+ (WebViewHost::didFinishResourceLoad):
+ (WebViewHost::didFailResourceLoad):
+ (WebViewHost::didDisplayInsecureContent):
+ (WebViewHost::didRunInsecureContent):
+ (WebViewHost::printFrameDescription):
+
+2010-09-09 Michael Saboff <msaboff@apple.com>
+
+ Unreviewed, adding myself to committers list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-09 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ Implement layoutTestController.dumpResourceResponseMIMETypes in Chromium DRT
+ https://bugs.webkit.org/show_bug.cgi?id=45479
+
+ Implement layoutTestController.dumpResourceResponseMIMETypes (modelled after
+ implementation in ResourceLoadDelegate in the Mac port).
+
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::LayoutTestController):
+ (LayoutTestController::dumpResourceResponseMIMETypes):
+ (LayoutTestController::reset):
+ * DumpRenderTree/chromium/LayoutTestController.h:
+ (LayoutTestController::setShouldDumpResourceResponseMIMETypes):
+ (LayoutTestController::shouldDumpResourceResponseMIMETypes):
+ * DumpRenderTree/chromium/TestShell.h:
+ (TestShell::shouldDumpResourceResponseMIMETypes):
+ * DumpRenderTree/chromium/WebViewHost.cpp:
+ (WebViewHost::didReceiveResponse):
+
+2010-09-09 Mihai Parparita <mihaip@chromium.org>
+
+ Reviewed by Daniel Bates.
+
+ svn-apply tries to delete directories it shouldn't
+ https://bugs.webkit.org/show_bug.cgi?id=45424
+
+ isDirectoryEmptyForRemoval had the wrong check. If an item in the
+ directory is itself a directory, then the directory is definitely
+ not empty.
+
+ * Scripts/svn-apply:
+
+2010-09-09 Chris Fleizach <cfleizach@apple.com>
+
+ Fixing GTK and windows build failure.
+
+ AX: Support AccessibilityTextMarkers in DRT
+ https://bugs.webkit.org/show_bug.cgi?id=44778
+
+ * DumpRenderTree/AccessibilityTextMarker.h:
+ (AccessibilityTextMarker::platformTextMarker):
+ (AccessibilityTextMarkerRange::platformTextMarkerRange):
+ * DumpRenderTree/mac/AccessibilityTextMarkerMac.mm:
+ (AccessibilityTextMarker::platformTextMarker):
+ (AccessibilityTextMarkerRange::platformTextMarkerRange):
+
+2010-09-09 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by David Kilzer.
+
+ AX: Support AccessibilityTextMarkers in DRT
+ https://bugs.webkit.org/show_bug.cgi?id=44778
+
+ Add AccessibilityTextMarker and AccessibilityTextMarkerRange which encapsulate the AXTextMarkers
+ that WebCore uses when vending information about its VisiblePositions through AX.
+
+ There are a few new methods in AccessibilityUIElement to retrieve and use text markers, and some basic
+ methods for encapsulating and checking equality.
+
+ This will allow future bug fixes in the text marker system to be adequately tested.
+
+ * DumpRenderTree/AccessibilityTextMarker.cpp: Added.
+ (toTextMarker):
+ (isMarkerEqualCallback):
+ (markerFinalize):
+ (AccessibilityTextMarker::makeJSAccessibilityTextMarker):
+ (AccessibilityTextMarker::getJSClass):
+ (toTextMarkerRange):
+ (isMarkerRangeEqualCallback):
+ (markerRangeFinalize):
+ (AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange):
+ (AccessibilityTextMarkerRange::getJSClass):
+ * DumpRenderTree/AccessibilityTextMarker.h: Added.
+ (AccessibilityTextMarker::platformTextMarker):
+ (AccessibilityTextMarkerRange::platformTextMarkerRange):
+ (AccessibilityTextMarker::AccessibilityTextMarker):
+ (AccessibilityTextMarker::~AccessibilityTextMarker):
+ (AccessibilityTextMarker::isEqual):
+ (AccessibilityTextMarkerRange::AccessibilityTextMarkerRange):
+ (AccessibilityTextMarkerRange::~AccessibilityTextMarkerRange):
+ (AccessibilityTextMarkerRange::isEqual):
+ * DumpRenderTree/AccessibilityUIElement.cpp:
+ (textMarkerRangeForElementCallback):
+ (textMarkerRangeLengthCallback):
+ (textMarkerRangeForMarkersCallback):
+ (startTextMarkerForTextMarkerRangeCallback):
+ (endTextMarkerForTextMarkerRangeCallback):
+ (accessibilityElementForTextMarkerCallback):
+ (AccessibilityUIElement::textMarkerRangeForElement):
+ (AccessibilityUIElement::textMarkerRangeLength):
+ (AccessibilityUIElement::startTextMarkerForTextMarkerRange):
+ (AccessibilityUIElement::endTextMarkerForTextMarkerRange):
+ (AccessibilityUIElement::accessibilityElementForTextMarker):
+ (AccessibilityUIElement::getJSClass):
+ * DumpRenderTree/AccessibilityUIElement.h:
+ * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+ * DumpRenderTree/mac/AccessibilityTextMarkerMac.mm: Added.
+ (AccessibilityTextMarker::AccessibilityTextMarker):
+ (AccessibilityTextMarker::~AccessibilityTextMarker):
+ (AccessibilityTextMarker::isEqual):
+ (AccessibilityTextMarkerRange::AccessibilityTextMarkerRange):
+ (AccessibilityTextMarkerRange::~AccessibilityTextMarkerRange):
+ (AccessibilityTextMarkerRange::isEqual):
+ * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+ (AccessibilityUIElement::textMarkerRangeForElement):
+ (AccessibilityUIElement::textMarkerRangeLength):
+ (AccessibilityUIElement::textMarkerRangeForMarkers):
+ (AccessibilityUIElement::startTextMarkerForTextMarkerRange):
+ (AccessibilityUIElement::endTextMarkerForTextMarkerRange):
+ (AccessibilityUIElement::accessibilityElementForTextMarker):
+ * DumpRenderTree/win/DumpRenderTree.vcproj:
+
+2010-08-25 Tony Chang <tony@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ don't delete duplicates needed because of intermediate results
+ https://bugs.webkit.org/show_bug.cgi?id=44653
+
+ Also, output the full path so we can pipe the output to rm.
+
+ * Scripts/webkitpy/layout_tests/deduplicate_tests.py:
+ * Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py:
+
+2010-09-09 Balazs Kelemen <kb@inf.u-szeged.hu>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] MiniBrowser does not starts properly
+ https://bugs.webkit.org/show_bug.cgi?id=45459
+
+ Do not try set up the first window by calling newWindow on a
+ newly created BrowserWindow since it creates a new object.
+ * MiniBrowser/qt/BrowserWindow.cpp:
+ (BrowserWindow::BrowserWindow):
+ * MiniBrowser/qt/main.cpp:
+ (main):
+
+2010-09-09 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Get ImageDiff building on Win32
+ https://bugs.webkit.org/show_bug.cgi?id=45353
+
+ * DumpRenderTree/gtk/ImageDiff.cpp:
+ (main): Switch from using strtok to g_strsplit.
+
+2010-09-09 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Andreas Kling.
+
+ [Qt] Modify load method of MiniBrowser's BrowserView class
+ https://bugs.webkit.org/show_bug.cgi?id=45442
+
+ Modify load method to take a QString as argument, remove unnecessary QT_VERSION_CHECK.
+
+ * MiniBrowser/qt/BrowserView.cpp:
+ (BrowserView::load):
+ * MiniBrowser/qt/BrowserView.h:
+ * MiniBrowser/qt/BrowserWindow.cpp:
+ (BrowserWindow::load):
+
+2010-09-09 Tony Chang <tony@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ fix show_results in new-run-webkit-tests
+ https://bugs.webkit.org/show_bug.cgi?id=45413
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+
+2010-09-08 Victor Wang <victorw@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ [Chromium] Fix test results server to make sure
+ it does not have corrupted data.
+
+ results.json file size coulbe be >1M and we split
+ the data into multiple data store entries in this
+ case. This patch fixes the issue that the data may
+ be corrupted if data store error happens in the middle
+ of saving multiple entries.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45063
+
+ * TestResultServer/model/datastorefile.py:
+
+2010-09-08 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Fix ignoring return value warning in case of gcc 4.4.4
+ https://bugs.webkit.org/show_bug.cgi?id=45384
+
+ * DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp:
+ (testPostURLFile):
+ If fwrite have written zero byte then the testPostURLFile function
+ returns with false as tempFile can't be opened.
+ * DumpRenderTree/qt/ImageDiff.cpp:
+ (main):
+ Put fwrite function into an if condition without body to avoid
+ warning. It is safe because this function writes to the stdout.
+
+2010-09-08 Satish Sampath <satish@chromium.org>
+
+ Unreviewed, adding myself to committers list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-08 Hans Wennborg <hans@chromium.org>
+
+ Unreviewed.
+
+ Adding myself as a committer in committers.py.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-08 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Refactor MiniBrowser
+ https://bugs.webkit.org/show_bug.cgi?id=45173
+
+ Split BrowserWindow into two source files and headers. Remove unnecessary header includes.
+
+ * MiniBrowser/qt/BrowserView.cpp: Added.
+ (createNewPage):
+ (BrowserView::BrowserView):
+ (BrowserView::resizeEvent):
+ (BrowserView::load):
+ (BrowserView::view):
+ * MiniBrowser/qt/BrowserView.h: Added.
+ (BrowserView::~BrowserView):
+ * MiniBrowser/qt/BrowserWindow.cpp:
+ * MiniBrowser/qt/BrowserWindow.h:
+ * MiniBrowser/qt/MiniBrowser.pro:
+
+2010-09-08 Adam Barth <abarth@webkit.org>
+
+ Rubber-stamped by Eric Seidel.
+
+ Rename DocLoader to CachedResourceLoader because that's what it does.
+
+ * Scripts/do-webcore-rename:
+
+2010-09-07 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ Enable incremental results.json generation for non-layout tests.
+ https://bugs.webkit.org/show_bug.cgi?id=45315
+
+ * Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py: Enable generate_incremental_results=True by default. (This still keeps to generate results.json.) Also add a code to upload results json files to the app-engine server. Need a chromium change to actually start the uploading.
+
+ * TestResultServer/model/jsonresults.py: Make sure we save the file with test_type for incremental cases too.
+
+
+2010-09-07 Dirk Pranke <dpranke@chromium.org>
+
+ Unreviewed, build fix
+
+ Missed one test in mac_unittest.py in previous change; for some
+ reason the method is listed twice. I will fix both for now, but will
+ figure this out in a later, not-time-sensitive patch.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45357
+
+ * Scripts/webkitpy/layout_tests/port/mac_unittest.py:
+
+2010-09-07 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Tony Chang.
+
+ test-webkitpy: Fix load error of
+ webkitpy/layout_tests/port/factory_unittest.py on Win32 Python
+ https://bugs.webkit.org/show_bug.cgi?id=45356 Need a short
+
+ * Scripts/webkitpy/layout_tests/port/server_process.py:
+ Avoid to import fcntl on win32. Win32 Python doesn't have fcntl
+ and we don't use server_process.py on Win32 Python. However
+ unittest.py tries to load everything in a module.
+
+2010-09-07 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ Fix regression introduced in previous change to new-run-webkit-tests
+ (bug 45090) to not try to run unittests for the Mac implementation
+ of the Port interface if we aren't running on a Mac.
+
+ Also fix the overrides implementation mock in the chromium unittests
+ to fix the case where there are overrides checked in that cause
+ problems.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45357
+
+ * Scripts/webkitpy/layout_tests/port/chromium_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/mac_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/port_testcase.py:
+
+2010-09-01 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Ojan Vafai.
+
+ new-run-webkit-tests: still more unit tests
+
+ Clean up and remove unnecessary code. Biggest notable change is
+ moving the chromium-specific imagediff code from port/base to
+ port/chromium.
+
+ Add more unit tests for run_webkit_tests.py, port/base.py,
+ port/factory.py, port/dryrun.py, and
+ layout_package/dump_render_tree_thread.py
+
+ This covers almost all of the generic and test code paths except for
+ a few error paths involving invalid or port-specific command line
+ arguments, and the code path for uploading results files to the
+ buildbots.
+
+ https://bugs.webkit.org/show_bug.cgi?id=45090
+
+ * Scripts/webkitpy/layout_tests/data/failures/expected/hang.html: Added.
+ * Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt: Copied from WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt.
+ * Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html: Copied from WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html.
+ * Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt: Copied from WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt.
+ * Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html: Copied from WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html.
+ * Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt:
+ * Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt: Copied from WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text-expected.txt.
+ * Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html: Copied from WebKitTools/Scripts/webkitpy/layout_tests/data/passes/text.html.
+ * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py:
+ * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread_unittest.py: Added.
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/dryrun.py:
+ * Scripts/webkitpy/layout_tests/port/factory_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/mac_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/port_testcase.py: Added.
+ * Scripts/webkitpy/layout_tests/port/server_process.py:
+ * Scripts/webkitpy/layout_tests/port/test.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py:
+
+2010-09-07 Joseph Pecoraro <joepeck@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Provide a way to trigger a <select multiple> onchange event on changes
+ https://bugs.webkit.org/show_bug.cgi?id=45192
+
+ Adds a selector on ObjCController for testing
+ -[DOMHTMLSelectElement _activateItemAtIndex:allowMultipleSelection:] and
+ its different uses.
+
+ * DumpRenderTree/mac/ObjCController.m:
+ (+[ObjCController isSelectorExcludedFromWebScript:]):
+ (+[ObjCController webScriptNameForSelector:]):
+ (-[ObjCController setSelectElement:selectedIndex:allowingMultiple:]):
+
+2010-09-07 James Robinson <jamesr@chromium.org>
+
+ Rubber-stamped by Dimitri Glazkov.
+
+ Move myself from the committer to the reviewer list.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-07 Tony Chang <tony@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ [chromium] Make a public flag for how DRT generates bitmaps on Linux
+ https://bugs.webkit.org/show_bug.cgi?id=45133
+
+ * DumpRenderTree/chromium/TestShell.cpp:
+ (TestShell::dumpImage):
+
+2010-09-07 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [DRT/Chromium] Implement --check-layout-test-sys-deps
+ https://bugs.webkit.org/show_bug.cgi?id=45283
+
+ * DumpRenderTree/chromium/DumpRenderTree.cpp:
+ (main): Check --check-layout-test-sys-deps and call checkLayoutTestSystemDependencies().
+ * DumpRenderTree/chromium/TestShell.h: Declare checkLayoutTestSystemDependencies().
+ * DumpRenderTree/chromium/TestShellGtk.cpp:
+ (checkLayoutTestSystemDependencies): Add an empty implementation.
+ * DumpRenderTree/chromium/TestShellMac.mm:
+ (checkLayoutTestSystemDependencies): Add an empty implementation.
+ * DumpRenderTree/chromium/TestShellWin.cpp:
+ (checkLayoutTestSystemDependencies): Port similar function of test_shell.
+
+2010-09-07 Jessie Berlin <jberlin@apple.com>
+
+ Unreviewed. Mac build fix.
+
+ * MiniBrowser/mac/WebBundle/WebBundleMain.m:
+ (didClearWindowObjectForFrame):
+
+2010-09-07 Jessie Berlin <jberlin@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Indicate which one of the ScriptWorlds for a Frame the Window Object has been cleared for
+ https://bugs.webkit.org/show_bug.cgi?id=45217
+
+ Make WebKitTestRunner work with this change.
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::didClearWindowForFrame):
+ Make sure the ScriptWorld here is the normal world, since that is no longer being done in
+ WebFrameLoaderClient.
+ * WebKitTestRunner/InjectedBundle/InjectedBundlePage.h:
+
+2010-09-07 Philippe Normand <pnormand@igalia.com>
+
+ Unreviewed, build fix.
+
+ webkit-patch command to find the ports covering a specific layout test
+ https://bugs.webkit.org/show_bug.cgi?id=42832
+
+ * Scripts/webkitpy/layout_tests/port/chromium.py: Don't assume the
+ tests are present when building the expectations. This is needed
+ for the unittests.
+
+2010-09-06 Philippe Normand <pnormand@igalia.com>
+
+ Reviewed by Adam Barth.
+
+ webkit-patch command to find the ports covering a specific layout test
+ https://bugs.webkit.org/show_bug.cgi?id=42832
+
+ To use it: webkit-patch skipped-ports some/layout/test.html
+
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/base_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/factory.py:
+ * Scripts/webkitpy/layout_tests/port/factory_unittest.py:
+ * Scripts/webkitpy/layout_tests/port/test.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/port/webkit_unittest.py:
+ * Scripts/webkitpy/tool/commands/queries.py:
+ * Scripts/webkitpy/tool/commands/queries_unittest.py:
+ * Scripts/webkitpy/tool/main.py:
+ * Scripts/webkitpy/tool/mocktool.py:
+
+2010-09-07 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Eric Seidel.
+
+ [NRWT] Add temp directory to all running drivers.
+ https://bugs.webkit.org/show_bug.cgi?id=45261
+
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+
+2010-09-06 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ [Chromium/DRT] Empty out user stylesheet after each test run.
+ https://bugs.webkit.org/show_bug.cgi?id=45282
+
+ This should significantly cut down on the number of the mysterious flaky tests
+ whose diffs looked like the page was blown up to a very lage size. This
+ was indeed the dirty work of platform/mac/fast/loader/user-stylesheet-fast-path.html,
+ which set the base body font to 100px.
+
+ Since the user stylesheet was never reset, _all_ pixel tests that ran after it in
+ the same thread failed.
+
+ * DumpRenderTree/chromium/TestShell.cpp:
+ (TestShell::resetWebSettings): Set user stylesheet to an empty URL.
+
+2010-09-06 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [DRT/Chromium] Do not generate pixel results for text/plain resources
+ https://bugs.webkit.org/show_bug.cgi?id=45253
+
+ * DumpRenderTree/chromium/TestShell.cpp:
+ (TestShell::dump): Clear shouldGeneratePixelResults flag for text/plain.
+
+2010-09-06 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ print out correct error when a DRT thread dies in NRWT
+ https://bugs.webkit.org/show_bug.cgi?id=45281
+
+ Not sure why, but with the parens, python 2.6.5 on Linux
+ gives an error that raise takes 5 arguments and 0 were given.
+ Didn't test other platforms or python versions, but putting it
+ all on one line fixes it and correctly prints the exception
+ from the DRT thread.
+
+ * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
+
+2010-09-06 Eric Seidel <eric@webkit.org>
+
+ Unreviewed, just adding some emails from lists.webkit.org.
+
+ Update committers.py to include emails from lists.webkit.org
+ as found by the validate-committer-lists script.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-06 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Small code cleanup in DumpRenderTreeGtk.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=45213
+
+ * DumpRenderTree/gtk/DumpRenderTree.cpp:
+ (initializeFonts): Made this function do nothing for non-X11 platforms, so we don't
+ have to surround the invocation with #ifdefs.
+ (useLongRunningServerMode): Added.
+ (runTestingServerLoop): Added.
+ (initializeGlobalsFromCommandLineOptions): Added.
+ (runTest): Removed ifdefs.
+ (main): Use new helper functions.
+
+2010-09-06 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] EventSender should support modifier keys with mouseDown and mouseUp events
+ https://bugs.webkit.org/show_bug.cgi?id=45235
+
+ Add support for interpreting the modifier key arguments to the mouseDown and mouseUp
+ methods of the EventSender.
+
+ * DumpRenderTree/gtk/EventSender.cpp:
+ (prepareMouseButtonEvent): Allow passing in a modifier bitmask, which will be OR'd
+ with the current modifiers.
+ (contextClickCallback): Always send no modifiers when preparing the mouse event.
+ (gdkModifersFromJSValue): Added, converts a JSValue array into a GDK modifier bitmask.
+ (mouseDownCallback): Send in the requested modifiers to prepareMouseButtonEvent.
+ (mouseUpCallback): Ditto.
+
+2010-09-05 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Adam Barth.
+
+ Make Chromium/Mac generate continuous mousewheel events with the same wheelDelta values as Safari/Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=45155
+
+ * DumpRenderTree/chromium/EventSender.cpp: Modify Chromium DRT mousewheel event generation to match new behavior on Mac.
+ (EventSender::handleMouseWheel):
+
+2010-09-05 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: remove WebDevToolsAgentClient::forceRepaint which is not used
+ https://bugs.webkit.org/show_bug.cgi?id=45179
+
+ * DumpRenderTree/chromium/DRTDevToolsAgent.cpp:
+ * DumpRenderTree/chromium/DRTDevToolsAgent.h:
+
+2010-09-05 Andreas Kling <andreas.kling@nokia.com>
+
+ Rubber-stamped by Daniel Bates.
+
+ Adding myself as reviewer.
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-04 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Martin Robinson.
+
+ Teach svn-apply/unapply about svn:mergeinfo
+ https://bugs.webkit.org/show_bug.cgi?id=45236
+
+ Recognize the svn:mergeinfo property and ignore it for now.
+
+ Currently, svn-apply/unapply recognize only '+' and '-'
+ property changes within a diff. We should add support
+ to recognize "Merged" and "Reverse-merged" changes as well.
+ Because svn:mergeinfo is metadata that is used only by SVN
+ and tends to be error-prone and/or nuisance (*), we will ignore
+ it for now.
+ (*) See "Parting Thoughts" of <http://www.collab.net/community/subversion/articles/merge-info.html>.
+
+ * Scripts/VCSUtils.pm:
+ - Modified parseSvnProperty() to recognize "Merged" and
+ "Reverse-merged" as the start of a property value.
+ * Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl:
+ - Added the following unit tests:
+ "simple: add svn:mergeinfo"
+ "simple: delete svn:mergeinfo"
+ "simple: modified svn:mergeinfo"
+ * Scripts/webkitperl/VCSUtils_unittest/parseSvnProperty.pl:
+ - Added the following unit tests:
+ "simple: add svn:mergeinfo"
+ "simple: delete svn:mergeinfo"
+ "simple: modified svn:mergeinfo"
+ "simple: modified svn:mergeinfo using SVN 1.4 syntax"
+ "'Merged' change followed by 'Merged' change"
+ "'Reverse-merged' change followed by 'Reverse-merged' change"
+ * Scripts/webkitperl/VCSUtils_unittest/parseSvnPropertyValue.pl:
+ - Added the following unit tests:
+ "'Merged' change"
+ "'Reverse-merged' change"
+ "'Reverse-merged' change followed by 'Merge' change"
+ "'Merged' change followed by 'Merge' change"
+ "'Reverse-merged' change followed by 'Reverse-merged' change"
+ "'Reverse-merged' change followed by 'Reverse-merged' change followed by 'Merged' change"
+
+2010-09-04 Lucas De Marchi <lucas.demarchi@profusion.mobi>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [EFL] Move test browser to WebKitTools directory
+ https://bugs.webkit.org/show_bug.cgi?id=45212
+
+ Follow other ports like QT and GTK which moved the test browser to
+ WebKitTools directory.
+
+ * CMakeListsEfl.txt: Added.
+ * EWebLauncher/main.c: Added.
+ (print_history):
+ (zoom_level_set):
+ (on_ecore_evas_resize):
+ (title_set):
+ (viewport_set):
+ (on_title_changed):
+ (on_progress):
+ (on_load_finished):
+ (on_toolbars_visible_set):
+ (on_toolbars_visible_get):
+ (on_statusbar_visible_set):
+ (on_statusbar_visible_get):
+ (on_scrollbars_visible_set):
+ (on_scrollbars_visible_get):
+ (on_menubar_visible_set):
+ (on_menubar_visible_get):
+ (on_tooltip_text_set):
+ (on_inputmethod_changed):
+ (on_viewport_changed):
+ (on_mouse_down):
+ (on_focus_out):
+ (on_focus_in):
+ (on_resized):
+ (on_key_down):
+ (on_browser_del):
+ (on_closeWindow):
+ (quit):
+ (browserCreate):
+ (browserDestroy):
+ (closeWindow):
+ (main_signal_exit):
+ (findThemePath):
+ (main):
+
+2010-09-03 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Set project dependencies so that they build serially. This fixes
+ issues when running run-webkit-tests if DRT is not built yet.
+
+ * DumpRenderTree/DumpRenderTree.sln:
+
+2010-09-03 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Fix reading configuraiton in NWRT to work on Windows.
+ https://bugs.webkit.org/show_bug.cgi?id=45180
+
+ * Scripts/webkitpy/layout_tests/port/base.py: Added 'perl' argument, because Windows doesn't know what to do
+ with the file otherwise.
+
+2010-09-03 Chris Rogers <crogers@google.com>
+
+ Unreviewed
+
+ Add myself to the committers list
+ https://bugs.webkit.org/show_bug.cgi?id=45189
+
+ * Scripts/webkitpy/common/config/committers.py:
+
+2010-09-03 Andrey Kosyakov <caseq@chromium.org>
+
+ Reviewed by Yury Semikhatsky.
+
+ http/tests/inspector/console-xhr-logging.html and http/tests/inspector/resource-har-conversion.html are failing on chromium win bot
+ Changed MIME type for .js to application/x-javascript for consistency with apache used on other platforms.
+ https://bugs.webkit.org/show_bug.cgi?id=45137
+
+ * Scripts/webkitpy/layout_tests/port/lighttpd.conf:
+
+2010-09-03 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Eric Seidel.
+
+ Add feature detection support to NRWT.
+ https://bugs.webkit.org/show_bug.cgi?id=41842
+
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/qt.py:
+ * Scripts/webkitpy/layout_tests/port/webkit.py:
+ * Scripts/webkitpy/layout_tests/port/webkit_unittest.py: Added.
+
+2010-09-03 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Kent Tamura.
+
+ Adds textInputController.hasSpellingMarker() to avoid using pixel tests for spellchecking tests
+ and implements it for Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=41832
+
+ * DumpRenderTree/mac/TextInputController.m: Added [TextInputController hasSpellingMarker:length:]
+ and bind it so we can call it from JavaScript.
+ (+[TextInputController isSelectorExcludedFromWebScript:]):
+ (+[TextInputController webScriptNameForSelector:]):
+ (-[TextInputController hasSpellingMarker:length:]):
+
+2010-09-02 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Add a unit test for commit-queue retries
+ https://bugs.webkit.org/show_bug.cgi?id=45162
+
+ I think commit-queue retries are not correctly avoiding
+ build and test on retries. So I started testing the code.
+ Unfortunately this test did not find the bug. But now
+ that we have the test we might as well keep it.
+ I also fixed a broken import in validate-committer-lists.
+
+ * Scripts/validate-committer-lists:
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+
+2010-09-02 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ [DRT/Chromium] Remove dependency to base/task.h and base/timer.h
+ https://bugs.webkit.org/show_bug.cgi?id=45091
+
+ Task.{cpp,h} introduces a simpler version of Chromium
+ base/task.h. It doesn't have TupleN and Method.
+
+ * DumpRenderTree/DumpRenderTree.gypi:
+ Add Task.cpp and Task.h
+ * DumpRenderTree/chromium/DRTDevToolsAgent.cpp:
+ (DRTDevToolsAgent::DRTDevToolsAgent):
+ (DRTDevToolsAgent::reset):
+ (DRTDevToolsAgent::asyncCall):
+ (DRTDevToolsAgent::frontendLoaded):
+ * DumpRenderTree/chromium/DRTDevToolsAgent.h:
+ (DRTDevToolsAgent::taskList): Added to use MethodTask<T>.
+ * DumpRenderTree/chromium/DRTDevToolsClient.cpp:
+ (DRTDevToolsClient::DRTDevToolsClient):
+ (DRTDevToolsClient::~DRTDevToolsClient):
+ (DRTDevToolsClient::reset):
+ (DRTDevToolsClient::asyncCall):
+ * DumpRenderTree/chromium/DRTDevToolsClient.h:
+ (DRTDevToolsClient::taskList): Added to use MethodTask<T>.
+ * DumpRenderTree/chromium/EventSender.cpp:
+ (EventSender::EventSender):
+ (EventSender::reset):
+ (EventSender::scheduleAsynchronousClick):
+ * DumpRenderTree/chromium/EventSender.h:
+ (EventSender::taskList): Added to use MethodTask<T>.
+ * DumpRenderTree/chromium/LayoutTestController.cpp:
+ (LayoutTestController::LayoutTestController):
+ (LayoutTestController::WorkQueue::processWorkSoon):
+ (LayoutTestController::waitUntilDone):
+ (LayoutTestController::notifyDone):
+ (LayoutTestController::reset):
+ * DumpRenderTree/chromium/LayoutTestController.h:
+ (LayoutTestController::taskList): Added to use MethodTask<T>.
+ (LayoutTestController::WorkQueue::taskList): Added to use MethodTask<T>.
+ * DumpRenderTree/chromium/NotificationPresenter.cpp:
+ (deferredDisplayDispatch):
+ (NotificationPresenter::show):
+ * DumpRenderTree/chromium/Task.cpp: Added.
+ * DumpRenderTree/chromium/Task.h: Added.
+
+2010-09-02 Steve Block <steveblock@google.com>
+
+ Reviewed by Adam Barth.
+
+ Hook up LayoutTestController.setMockDeviceOrientation() on Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=43181
+
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (createWebViewAndOffscreenWindow):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::setMockDeviceOrientation):
+
+2010-08-31 Adam Roben <aroben@apple.com>
+
+ Fix flashiness when resizing the browser window on Windows
+
+ Reviewed by Sam Weinig.
+
+ * MiniBrowser/win/BrowserWindow.cpp:
+ (BrowserWindow::wndProc): Override WM_ERASEBKGND so Windows won't
+ periodically fill the window with white.
+
2010-09-02 Peter Kasting <pkasting@google.com>
Reviewed by Dimitri Glazkov.
diff --git a/WebKitTools/DumpRenderTree/AccessibilityTextMarker.cpp b/WebKitTools/DumpRenderTree/AccessibilityTextMarker.cpp
new file mode 100644
index 0000000..d84ee80
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/AccessibilityTextMarker.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibilityTextMarker.h"
+
+#include "AccessibilityUIElement.h"
+#include <JavaScriptCore/JSRetainPtr.h>
+
+#pragma mark AccessibilityTextMarker
+
+// Callback methods
+
+AccessibilityTextMarker* toTextMarker(JSObjectRef object)
+{
+ return static_cast<AccessibilityTextMarker*>(JSObjectGetPrivate(object));
+}
+
+static JSValueRef isMarkerEqualCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount != 1)
+ return JSValueMakeBoolean(context, false);
+
+ JSObjectRef otherMarker = JSValueToObject(context, arguments[0], exception);
+ return JSValueMakeBoolean(context, toTextMarker(thisObject)->isEqual(toTextMarker(otherMarker)));
+}
+
+// Destruction
+
+static void markerFinalize(JSObjectRef thisObject)
+{
+ delete toTextMarker(thisObject);
+}
+
+// Object Creation
+
+JSObjectRef AccessibilityTextMarker::makeJSAccessibilityTextMarker(JSContextRef context, const AccessibilityTextMarker& element)
+{
+ return JSObjectMake(context, AccessibilityTextMarker::getJSClass(), new AccessibilityTextMarker(element));
+}
+
+JSClassRef AccessibilityTextMarker::getJSClass()
+{
+ static JSStaticValue staticValues[] = {
+ { 0, 0, 0, 0 }
+ };
+
+ static JSStaticFunction staticFunctions[] = {
+ { "isEqual", isMarkerEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ static JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "AccessibilityTextMarker", 0, staticValues, staticFunctions,
+ 0, markerFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ static JSClassRef accessibilityTextMarkerClass = JSClassCreate(&classDefinition);
+ return accessibilityTextMarkerClass;
+}
+
+#pragma mark AccessibilityTextMarkerRange
+
+// Callback methods
+
+AccessibilityTextMarkerRange* toTextMarkerRange(JSObjectRef object)
+{
+ return static_cast<AccessibilityTextMarkerRange*>(JSObjectGetPrivate(object));
+}
+
+static JSValueRef isMarkerRangeEqualCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ if (argumentCount != 1)
+ return JSValueMakeBoolean(context, false);
+
+ JSObjectRef otherMarker = JSValueToObject(context, arguments[0], exception);
+ return JSValueMakeBoolean(context, toTextMarkerRange(thisObject)->isEqual(toTextMarkerRange(otherMarker)));
+}
+
+// Destruction
+
+static void markerRangeFinalize(JSObjectRef thisObject)
+{
+ delete toTextMarkerRange(thisObject);
+}
+
+// Object Creation
+
+JSObjectRef AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(JSContextRef context, const AccessibilityTextMarkerRange& element)
+{
+ return JSObjectMake(context, AccessibilityTextMarkerRange::getJSClass(), new AccessibilityTextMarkerRange(element));
+}
+
+JSClassRef AccessibilityTextMarkerRange::getJSClass()
+{
+ static JSStaticValue staticValues[] = {
+ { 0, 0, 0, 0 }
+ };
+
+ static JSStaticFunction staticFunctions[] = {
+ { "isEqual", isMarkerRangeEqualCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 }
+ };
+
+ static JSClassDefinition classDefinition = {
+ 0, kJSClassAttributeNone, "AccessibilityTextMarkerRange", 0, staticValues, staticFunctions,
+ 0, markerRangeFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ static JSClassRef accessibilityTextMarkerRangeClass = JSClassCreate(&classDefinition);
+ return accessibilityTextMarkerRangeClass;
+}
diff --git a/WebKitTools/DumpRenderTree/AccessibilityTextMarker.h b/WebKitTools/DumpRenderTree/AccessibilityTextMarker.h
new file mode 100644
index 0000000..aeb078d
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/AccessibilityTextMarker.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AccessibilityTextMarker_h
+#define AccessibilityTextMarker_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+
+#if PLATFORM(MAC)
+#define SUPPORTS_AX_TEXTMARKERS 1
+#else
+#define SUPPORTS_AX_TEXTMARKERS 0
+#endif
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+typedef CFTypeRef PlatformTextMarker;
+typedef CFTypeRef PlatformTextMarkerRange;
+#else
+typedef void* PlatformTextMarker;
+typedef void* PlatformTextMarkerRange;
+#endif
+
+class AccessibilityUIElement;
+
+class AccessibilityTextMarker {
+public:
+ AccessibilityTextMarker(PlatformTextMarker);
+ AccessibilityTextMarker(const AccessibilityTextMarker&);
+ ~AccessibilityTextMarker();
+
+ PlatformTextMarker platformTextMarker() const;
+
+ static JSObjectRef makeJSAccessibilityTextMarker(JSContextRef, const AccessibilityTextMarker&);
+ bool isEqual(AccessibilityTextMarker*);
+
+private:
+ static JSClassRef getJSClass();
+#if PLATFORM(MAC)
+ RetainPtr<PlatformTextMarker> m_textMarker;
+#else
+ PlatformTextMarker m_textMarker;
+#endif
+};
+
+class AccessibilityTextMarkerRange {
+public:
+ AccessibilityTextMarkerRange(PlatformTextMarkerRange);
+ AccessibilityTextMarkerRange(const AccessibilityTextMarkerRange&);
+ ~AccessibilityTextMarkerRange();
+
+ PlatformTextMarkerRange platformTextMarkerRange() const;
+
+ static JSObjectRef makeJSAccessibilityTextMarkerRange(JSContextRef, const AccessibilityTextMarkerRange&);
+ bool isEqual(AccessibilityTextMarkerRange*);
+
+private:
+ static JSClassRef getJSClass();
+#if PLATFORM(MAC)
+ RetainPtr<PlatformTextMarkerRange> m_textMarkerRange;
+#else
+ PlatformTextMarkerRange m_textMarkerRange;
+#endif
+};
+
+AccessibilityTextMarker* toTextMarker(JSObjectRef object);
+AccessibilityTextMarkerRange* toTextMarkerRange(JSObjectRef object);
+
+#if !SUPPORTS_AX_TEXTMARKERS
+inline AccessibilityTextMarker::AccessibilityTextMarker(PlatformTextMarker) { }
+inline AccessibilityTextMarker::AccessibilityTextMarker(const AccessibilityTextMarker&) { }
+inline AccessibilityTextMarker::~AccessibilityTextMarker() { }
+inline bool AccessibilityTextMarker::isEqual(AccessibilityTextMarker*) { return false; }
+inline PlatformTextMarker AccessibilityTextMarker::platformTextMarker() const { return m_textMarker; }
+
+inline AccessibilityTextMarkerRange::AccessibilityTextMarkerRange(PlatformTextMarkerRange) { }
+inline AccessibilityTextMarkerRange::AccessibilityTextMarkerRange(const AccessibilityTextMarkerRange&) { }
+inline AccessibilityTextMarkerRange::~AccessibilityTextMarkerRange() { }
+inline bool AccessibilityTextMarkerRange::isEqual(AccessibilityTextMarkerRange*) { return false; }
+inline PlatformTextMarkerRange AccessibilityTextMarkerRange::platformTextMarkerRange() const { return m_textMarkerRange; }
+#endif
+
+#endif // AccessibilityUIElement_h
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
index e09eb35..22bbbaa 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp
@@ -406,6 +406,62 @@ static JSValueRef removeSelectionCallback(JSContextRef context, JSObjectRef func
return JSValueMakeUndefined(context);
}
+static JSValueRef textMarkerRangeForElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityUIElement* uiElement = 0;
+ if (argumentCount == 1)
+ uiElement = toAXElement(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->textMarkerRangeForElement(uiElement));
+}
+
+static JSValueRef textMarkerRangeLengthCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarkerRange* range = 0;
+ if (argumentCount == 1)
+ range = toTextMarkerRange(JSValueToObject(context, arguments[0], exception));
+
+ return JSValueMakeNumber(context, (int)toAXElement(thisObject)->textMarkerRangeLength(range));
+}
+
+static JSValueRef textMarkerRangeForMarkersCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarker* startMarker = 0;
+ AccessibilityTextMarker* endMarker = 0;
+ if (argumentCount == 2) {
+ startMarker = toTextMarker(JSValueToObject(context, arguments[0], exception));
+ endMarker = toTextMarker(JSValueToObject(context, arguments[1], exception));
+ }
+
+ return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->textMarkerRangeForMarkers(startMarker, endMarker));
+}
+
+static JSValueRef startTextMarkerForTextMarkerRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarkerRange* markerRange = 0;
+ if (argumentCount == 1)
+ markerRange = toTextMarkerRange(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->startTextMarkerForTextMarkerRange(markerRange));
+}
+
+static JSValueRef endTextMarkerForTextMarkerRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarkerRange* markerRange = 0;
+ if (argumentCount == 1)
+ markerRange = toTextMarkerRange(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityTextMarker::makeJSAccessibilityTextMarker(context, toAXElement(thisObject)->endTextMarkerForTextMarkerRange(markerRange));
+}
+
+static JSValueRef accessibilityElementForTextMarkerCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ AccessibilityTextMarker* marker = 0;
+ if (argumentCount == 1)
+ marker = toTextMarker(JSValueToObject(context, arguments[0], exception));
+
+ return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->accessibilityElementForTextMarker(marker));
+}
// Static Value Getters
@@ -662,6 +718,42 @@ static JSValueRef removeNotificationListenerCallback(JSContextRef context, JSObj
return JSValueMakeUndefined(context);
}
+// Implementation
+
+#if !SUPPORTS_AX_TEXTMARKERS
+
+AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement*)
+{
+ return 0;
+}
+
+int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange*)
+{
+ return 0;
+}
+
+AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker*, AccessibilityTextMarker*)
+{
+ return 0;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ return 0;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*)
+{
+ return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker*)
+{
+ return 0;
+}
+
+#endif
+
// Destruction
static void finalize(JSObjectRef thisObject)
@@ -774,6 +866,12 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "takeSelection", takeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "addSelection", addSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "removeSelection", removeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textMarkerRangeForElement", textMarkerRangeForElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textMarkerRangeForMarkers", textMarkerRangeForMarkersCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "startTextMarkerForTextMarkerRange", startTextMarkerForTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "endTextMarkerForTextMarkerRange", endTextMarkerForTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "accessibilityElementForTextMarker", accessibilityElementForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "textMarkerRangeLength", textMarkerRangeLengthCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
};
diff --git a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
index 13415cd..2606795 100644
--- a/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
+++ b/WebKitTools/DumpRenderTree/AccessibilityUIElement.h
@@ -26,6 +26,7 @@
#ifndef AccessibilityUIElement_h
#define AccessibilityUIElement_h
+#include "AccessibilityTextMarker.h"
#include <JavaScriptCore/JSObjectRef.h>
#include <wtf/Platform.h>
#include <wtf/Vector.h>
@@ -40,8 +41,8 @@ typedef struct objc_object* PlatformUIElement;
#undef _WINSOCKAPI_
#define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h
-#include <oleacc.h>
#include <WebCore/COMPtr.h>
+#include <oleacc.h>
typedef COMPtr<IAccessible> PlatformUIElement;
#elif PLATFORM(GTK)
@@ -183,6 +184,14 @@ public:
// Table-specific
AccessibilityUIElement cellForColumnAndRow(unsigned column, unsigned row);
+ // Text markers.
+ AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement*);
+ AccessibilityTextMarkerRange textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
+ AccessibilityTextMarker startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
+ AccessibilityTextMarker endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
+ AccessibilityUIElement accessibilityElementForTextMarker(AccessibilityTextMarker*);
+ int textMarkerRangeLength(AccessibilityTextMarkerRange*);
+
// Notifications
// Function callback should take one argument, the name of the notification.
bool addNotificationListener(JSObjectRef functionCallback);
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.gypi b/WebKitTools/DumpRenderTree/DumpRenderTree.gypi
index a525532..b39fd2a 100644
--- a/WebKitTools/DumpRenderTree/DumpRenderTree.gypi
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.gypi
@@ -26,6 +26,8 @@
'chromium/NotificationPresenter.cpp',
'chromium/PlainTextController.cpp',
'chromium/PlainTextController.h',
+ 'chromium/Task.h',
+ 'chromium/Task.cpp',
'chromium/TestEventPrinter.h',
'chromium/TestEventPrinter.cpp',
'chromium/TestNavigationController.cpp',
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.sln b/WebKitTools/DumpRenderTree/DumpRenderTree.sln
index 3647a2a..196f872 100644
--- a/WebKitTools/DumpRenderTree/DumpRenderTree.sln
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.sln
@@ -2,12 +2,21 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DumpRenderTree", "win\DumpRenderTree.vcproj", "{6567DFD4-D6DE-4CD5-825D-17E353D160E1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C0737398-3565-439E-A2B8-AB2BE4D5430C} = {C0737398-3565-439E-A2B8-AB2BE4D5430C}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestNetscapePlugin", "TestNetscapePlugin\win\TestNetscapePlugin.vcproj", "{C0737398-3565-439E-A2B8-AB2BE4D5430C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {59CC0547-70AC-499C-9B19-EC01C6F61137} = {59CC0547-70AC-499C-9B19-EC01C6F61137}
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindSafari", "..\FindSafari\FindSafari.vcproj", "{DA31DA52-6675-48D4-89E0-333A7144397C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageDiff", "win\ImageDiff.vcproj", "{59CC0547-70AC-499C-9B19-EC01C6F61137}"
+ ProjectSection(ProjectDependencies) = postProject
+ {DA31DA52-6675-48D4-89E0-333A7144397C} = {DA31DA52-6675-48D4-89E0-333A7144397C}
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
index c92c704..c01ca4e 100644
--- a/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
+++ b/WebKitTools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
@@ -43,6 +43,9 @@
1AC77DCF120605B6005C19EF /* NPRuntimeRemoveProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */; };
1AD9D2FE12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD9D2FD12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp */; };
23BCB8900EA57623003C6289 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23BCB88F0EA57623003C6289 /* OpenGL.framework */; };
+ 29CFBA10122736E600BC30C0 /* AccessibilityTextMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 29CFBA0E122736E600BC30C0 /* AccessibilityTextMarker.h */; };
+ 29CFBA11122736E600BC30C0 /* AccessibilityTextMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29CFBA0F122736E600BC30C0 /* AccessibilityTextMarker.cpp */; };
+ 29CFBA2E12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29CFBA2D12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm */; };
3713EDE2115BE19300705720 /* ColorBits-A.png in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 3713EDDF115BE16F00705720 /* ColorBits-A.png */; };
3713EDE3115BE19300705720 /* ColorBits.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 3713EDE0115BE16F00705720 /* ColorBits.ttf */; };
5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5185F69F10714A57007AA393 /* HistoryDelegate.mm */; };
@@ -202,6 +205,9 @@
1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NPRuntimeRemoveProperty.cpp; sourceTree = "<group>"; };
1AD9D2FD12028409001A70D1 /* PluginScriptableNPObjectInvokeDefault.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginScriptableNPObjectInvokeDefault.cpp; sourceTree = "<group>"; };
23BCB88F0EA57623003C6289 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
+ 29CFBA0E122736E600BC30C0 /* AccessibilityTextMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTextMarker.h; sourceTree = "<group>"; };
+ 29CFBA0F122736E600BC30C0 /* AccessibilityTextMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTextMarker.cpp; sourceTree = "<group>"; };
+ 29CFBA2D12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityTextMarkerMac.mm; path = mac/AccessibilityTextMarkerMac.mm; sourceTree = "<group>"; };
32A70AAB03705E1F00C91783 /* DumpRenderTreePrefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumpRenderTreePrefix.h; sourceTree = "<group>"; };
3713EDDF115BE16F00705720 /* ColorBits-A.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "ColorBits-A.png"; path = "fonts/ColorBits-A.png"; sourceTree = "<group>"; };
3713EDE0115BE16F00705720 /* ColorBits.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = ColorBits.ttf; path = fonts/ColorBits.ttf; sourceTree = "<group>"; };
@@ -389,6 +395,9 @@
BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */,
BCD08A580E10496B00A7D0C1 /* AccessibilityController.h */,
BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */,
+ 29CFBA0F122736E600BC30C0 /* AccessibilityTextMarker.cpp */,
+ 29CFBA0E122736E600BC30C0 /* AccessibilityTextMarker.h */,
+ 29CFBA2D12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm */,
BC0E24DF0E2D9451001B6BC2 /* AccessibilityUIElement.cpp */,
BC0E24DE0E2D9451001B6BC2 /* AccessibilityUIElement.h */,
BC0E26140E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm */,
@@ -585,6 +594,7 @@
BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */,
5185F6B310714E12007AA393 /* HistoryDelegate.h in Headers */,
E1B7816711AF31C3007E1BC2 /* MockGeolocationProvider.h in Headers */,
+ 29CFBA10122736E600BC30C0 /* AccessibilityTextMarker.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -758,6 +768,8 @@
BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */,
5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */,
E1B7816511AF31B7007E1BC2 /* MockGeolocationProvider.mm in Sources */,
+ 29CFBA11122736E600BC30C0 /* AccessibilityTextMarker.cpp in Sources */,
+ 29CFBA2E12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
index 44fafa1..5002400 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp
@@ -690,7 +690,9 @@ static bool testPostURLFile(PluginObject* obj, const NPVariant* args, uint32_t a
if (!tempFile)
return false;
- fwrite(contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile);
+ if (!fwrite(contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile))
+ return false;
+
fclose(tempFile);
NPError error = browser->posturl(obj->npp, url, target, pathString.UTF8Length, path, TRUE);
diff --git a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp
index ba1edd7..a9a891b 100644
--- a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.cpp
@@ -43,8 +43,7 @@
using namespace WebKit;
DRTDevToolsAgent::DRTDevToolsAgent()
- : m_callMethodFactory(this)
- , m_drtDevToolsClient(0)
+ : m_drtDevToolsClient(0)
, m_webView(0)
{
static int devToolsAgentCounter = 0;
@@ -56,7 +55,7 @@ DRTDevToolsAgent::DRTDevToolsAgent()
void DRTDevToolsAgent::reset()
{
- m_callMethodFactory.RevokeAll();
+ m_taskList.revokeAll();
}
void DRTDevToolsAgent::setWebView(WebView* webView)
@@ -70,10 +69,6 @@ void DRTDevToolsAgent::sendMessageToInspectorFrontend(const WebKit::WebString& d
m_drtDevToolsClient->asyncCall(DRTDevToolsCallArgs(data));
}
-void DRTDevToolsAgent::forceRepaint()
-{
-}
-
void DRTDevToolsAgent::runtimePropertyChanged(const WebKit::WebString& name, const WebKit::WebString& value)
{
// FIXME: Implement.
@@ -89,10 +84,9 @@ WebDevToolsAgentClient::WebKitClientMessageLoop* DRTDevToolsAgent::createClientM
return webkit_support::CreateDevToolsMessageLoop();
}
-void DRTDevToolsAgent::asyncCall(const DRTDevToolsCallArgs &args)
+void DRTDevToolsAgent::asyncCall(const DRTDevToolsCallArgs& args)
{
- webkit_support::PostTaskFromHere(
- m_callMethodFactory.NewRunnableMethod(&DRTDevToolsAgent::call, args));
+ postTask(new AsyncCallTask(this, args));
}
void DRTDevToolsAgent::call(const DRTDevToolsCallArgs &args)
@@ -137,9 +131,9 @@ void DRTDevToolsAgent::detach()
m_drtDevToolsClient = 0;
}
-void DRTDevToolsAgent::frontendLoaded() {
- webkit_support::PostTaskFromHere(
- m_callMethodFactory.NewRunnableMethod(&DRTDevToolsAgent::delayedFrontendLoaded));
+void DRTDevToolsAgent::frontendLoaded()
+{
+ postTask(new DelayedFrontendLoadedTask(this));
}
bool DRTDevToolsAgent::setTimelineProfilingEnabled(bool enabled)
diff --git a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h
index 8747cea..c988fa1 100644
--- a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h
+++ b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsAgent.h
@@ -31,7 +31,8 @@
#ifndef DRTDevToolsAgent_h
#define DRTDevToolsAgent_h
-#include "base/task.h" // FIXME: remove this
+#include "DRTDevToolsCallArgs.h"
+#include "Task.h"
#include "public/WebDevToolsAgentClient.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
@@ -46,7 +47,6 @@ struct WebDevToolsMessageData;
} // namespace WebKit
-class DRTDevToolsCallArgs;
class DRTDevToolsClient;
class DRTDevToolsAgent : public WebKit::WebDevToolsAgentClient
@@ -61,7 +61,6 @@ public:
// WebDevToolsAgentClient implementation.
virtual void sendMessageToInspectorFrontend(const WebKit::WebString&);
virtual int hostIdentifier() { return m_routingID; }
- virtual void forceRepaint();
virtual void runtimePropertyChanged(const WebKit::WebString& name, const WebKit::WebString& value);
virtual WebKit::WebCString debuggerScriptSource();
virtual WebKitClientMessageLoop* createClientMessageLoop();
@@ -74,6 +73,7 @@ public:
bool evaluateInWebInspector(long callID, const std::string& script);
bool setTimelineProfilingEnabled(bool enable);
+ TaskList* taskList() { return &m_taskList; }
private:
void call(const DRTDevToolsCallArgs&);
@@ -81,7 +81,21 @@ private:
static void dispatchMessageLoop();
WebKit::WebDevToolsAgent* webDevToolsAgent();
- ScopedRunnableMethodFactory<DRTDevToolsAgent> m_callMethodFactory;
+ class AsyncCallTask: public MethodTask<DRTDevToolsAgent> {
+ public:
+ AsyncCallTask(DRTDevToolsAgent* object, const DRTDevToolsCallArgs& args)
+ : MethodTask<DRTDevToolsAgent>(object), m_args(args) {}
+ virtual void runIfValid() { m_object->call(m_args); }
+ private:
+ DRTDevToolsCallArgs m_args;
+ };
+
+ struct DelayedFrontendLoadedTask: public MethodTask<DRTDevToolsAgent> {
+ DelayedFrontendLoadedTask(DRTDevToolsAgent* object) : MethodTask<DRTDevToolsAgent>(object) {}
+ virtual void runIfValid() { m_object->delayedFrontendLoaded(); }
+ };
+
+ TaskList m_taskList;
DRTDevToolsClient* m_drtDevToolsClient;
int m_routingID;
WebKit::WebDevToolsAgent* m_webDevToolsAgent;
diff --git a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.cpp b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.cpp
index 42f3724..a53f0db 100644
--- a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.cpp
@@ -45,8 +45,7 @@
using namespace WebKit;
DRTDevToolsClient::DRTDevToolsClient(DRTDevToolsAgent* agent, WebView* webView)
- : m_callMethodFactory(this)
- , m_drtDevToolsAgent(agent)
+ : m_drtDevToolsAgent(agent)
, m_webView(webView)
{
m_webDevToolsFrontend.set(WebDevToolsFrontend::create(m_webView,
@@ -59,14 +58,14 @@ DRTDevToolsClient::~DRTDevToolsClient()
{
// There is a chance that the page will be destroyed at detach step of
// m_drtDevToolsAgent and we should clean pending requests a bit earlier.
- m_callMethodFactory.RevokeAll();
+ m_taskList.revokeAll();
if (m_drtDevToolsAgent)
m_drtDevToolsAgent->detach();
}
void DRTDevToolsClient::reset()
{
- m_callMethodFactory.RevokeAll();
+ m_taskList.revokeAll();
}
void DRTDevToolsClient::sendFrontendLoaded() {
@@ -107,8 +106,7 @@ void DRTDevToolsClient::undockWindow()
void DRTDevToolsClient::asyncCall(const DRTDevToolsCallArgs& args)
{
- webkit_support::PostTaskFromHere(
- m_callMethodFactory.NewRunnableMethod(&DRTDevToolsClient::call, args));
+ postTask(new AsyncCallTask(this, args));
}
void DRTDevToolsClient::call(const DRTDevToolsCallArgs& args)
diff --git a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.h b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.h
index 37b1e9d..f7c8fbf 100644
--- a/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.h
+++ b/WebKitTools/DumpRenderTree/chromium/DRTDevToolsClient.h
@@ -31,7 +31,8 @@
#ifndef DRTDevToolsClient_h
#define DRTDevToolsClient_h
-#include "base/task.h" // FIXME: remove this
+#include "DRTDevToolsCallArgs.h"
+#include "Task.h"
#include "public/WebDevToolsFrontendClient.h"
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -45,7 +46,6 @@ class WebView;
} // namespace WebKit
-class DRTDevToolsCallArgs;
class DRTDevToolsAgent;
class DRTDevToolsClient : public WebKit::WebDevToolsFrontendClient
@@ -68,11 +68,20 @@ public:
void asyncCall(const DRTDevToolsCallArgs&);
void allMessagesProcessed();
+ TaskList* taskList() { return &m_taskList; }
private:
void call(const DRTDevToolsCallArgs&);
+ class AsyncCallTask: public MethodTask<DRTDevToolsClient> {
+ public:
+ AsyncCallTask(DRTDevToolsClient* object, const DRTDevToolsCallArgs& args)
+ : MethodTask<DRTDevToolsClient>(object), m_args(args) {}
+ virtual void runIfValid() { m_object->call(m_args); }
+ private:
+ DRTDevToolsCallArgs m_args;
+ };
- ScopedRunnableMethodFactory<DRTDevToolsClient> m_callMethodFactory;
+ TaskList m_taskList;
WebKit::WebView* m_webView;
DRTDevToolsAgent* m_drtDevToolsAgent;
WTF::OwnPtr<WebKit::WebDevToolsFrontend> m_webDevToolsFrontend;
diff --git a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp
index 726e412..6e180d0 100644
--- a/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/DumpRenderTree.cpp
@@ -47,6 +47,7 @@ static const char optionPixelTestsWithName[] = "--pixel-tests=";
static const char optionTestShell[] = "--test-shell";
static const char optionAllowExternalPages[] = "--allow-external-pages";
static const char optionStartupDialog[] = "--testshell-startup-dialog";
+static const char optionCheckLayoutTestSystemDeps[] = "--check-layout-test-sys-deps";
static void runTest(TestShell& shell, TestParams& params, const string& testName, bool testShellMode)
{
@@ -109,6 +110,8 @@ int main(int argc, char* argv[])
allowExternalPages = true;
else if (argument == optionStartupDialog)
startupDialog = true;
+ else if (argument == optionCheckLayoutTestSystemDeps)
+ exit(checkLayoutTestSystemDependencies() ? EXIT_SUCCESS : EXIT_FAILURE);
else if (argument.size() && argument[0] == '-')
fprintf(stderr, "Unknown option: %s\n", argv[i]);
else
diff --git a/WebKitTools/DumpRenderTree/chromium/EventSender.cpp b/WebKitTools/DumpRenderTree/chromium/EventSender.cpp
index 49421f6..c2ba380 100644
--- a/WebKitTools/DumpRenderTree/chromium/EventSender.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/EventSender.cpp
@@ -244,8 +244,7 @@ enum KeyLocationCode {
};
EventSender::EventSender(TestShell* shell)
- : m_methodFactory(this)
- , m_shell(shell)
+ : m_shell(shell)
{
// Initialize the map that associates methods of this class with the names
// they will use when called by JavaScript. The actual binding of those
@@ -322,7 +321,7 @@ void EventSender::reset()
timeOffsetMs = 0;
touchModifiers = 0;
touchPoints.clear();
- m_methodFactory.RevokeAll();
+ m_taskList.revokeAll();
}
WebView* EventSender::webview()
@@ -750,14 +749,29 @@ void EventSender::contextClick(const CppArgumentList& arguments, CppVariant* res
pressedButton = WebMouseEvent::ButtonNone;
}
+class MouseDownTask: public MethodTask<EventSender> {
+public:
+ MouseDownTask(EventSender* obj, const CppArgumentList& arg)
+ : MethodTask<EventSender>(obj), m_arguments(arg) {}
+ virtual void runIfValid() { m_object->mouseDown(m_arguments, 0); }
+private:
+ CppArgumentList m_arguments;
+};
+
+class MouseUpTask: public MethodTask<EventSender> {
+public:
+ MouseUpTask(EventSender* obj, const CppArgumentList& arg)
+ : MethodTask<EventSender>(obj), m_arguments(arg) {}
+ virtual void runIfValid() { m_object->mouseUp(m_arguments, 0); }
+private:
+ CppArgumentList m_arguments;
+};
+
void EventSender::scheduleAsynchronousClick(const CppArgumentList& arguments, CppVariant* result)
{
result->setNull();
-
- webkit_support::PostTaskFromHere(m_methodFactory.NewRunnableMethod(
- &EventSender::mouseDown, arguments, static_cast<CppVariant*>(0)));
- webkit_support::PostTaskFromHere(m_methodFactory.NewRunnableMethod(
- &EventSender::mouseUp, arguments, static_cast<CppVariant*>(0)));
+ postTask(new MouseDownTask(this, arguments));
+ postTask(new MouseUpTask(this, arguments));
}
void EventSender::beginDragWithFiles(const CppArgumentList& arguments, CppVariant* result)
@@ -895,7 +909,10 @@ void EventSender::handleMouseWheel(const CppArgumentList& arguments, CppVariant*
event.wheelTicksY = static_cast<float>(vertical);
event.deltaX = event.wheelTicksX;
event.deltaY = event.wheelTicksY;
- if (!continuous) {
+ if (continuous) {
+ event.wheelTicksX /= scrollbarPixelsPerTick;
+ event.wheelTicksY /= scrollbarPixelsPerTick;
+ } else {
event.deltaX *= scrollbarPixelsPerTick;
event.deltaY *= scrollbarPixelsPerTick;
}
diff --git a/WebKitTools/DumpRenderTree/chromium/EventSender.h b/WebKitTools/DumpRenderTree/chromium/EventSender.h
index 0d8fe5d..399a132 100644
--- a/WebKitTools/DumpRenderTree/chromium/EventSender.h
+++ b/WebKitTools/DumpRenderTree/chromium/EventSender.h
@@ -38,7 +38,7 @@
#define EventSender_h
#include "CppBoundClass.h"
-#include "base/task.h"
+#include "Task.h"
#include "public/WebDragOperation.h"
#include "public/WebInputEvent.h"
#include "public/WebPoint.h"
@@ -108,6 +108,8 @@ public:
CppVariant wmSysDeadChar;
#endif
+ TaskList* taskList() { return &m_taskList; }
+
private:
// Returns the test shell's webview.
WebKit::WebView* webview();
@@ -141,7 +143,7 @@ private:
// Handle a request to send a wheel event.
void handleMouseWheel(const CppArgumentList&, CppVariant*, bool continuous);
- ScopedRunnableMethodFactory<EventSender> m_methodFactory;
+ TaskList m_taskList;
// Non-owning pointer. The EventSender is owned by the TestShell.
TestShell* m_shell;
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
index 2999d3a..6f962bf 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.cpp
@@ -38,6 +38,8 @@
#include "public/WebAnimationController.h"
#include "public/WebBindings.h"
#include "public/WebConsoleMessage.h"
+#include "public/WebDeviceOrientation.h"
+#include "public/WebDeviceOrientationClientMock.h"
#include "public/WebDocument.h"
#include "public/WebElement.h"
#include "public/WebFrame.h"
@@ -67,8 +69,7 @@ using namespace WebKit;
using namespace std;
LayoutTestController::LayoutTestController(TestShell* shell)
- : m_timeoutFactory(this)
- , m_shell(shell)
+ : m_shell(shell)
, m_workQueue(this)
{
@@ -195,6 +196,10 @@ LayoutTestController::LayoutTestController(TestShell* shell)
bindProperty("webHistoryItemCount", &m_webHistoryItemCount);
}
+LayoutTestController::~LayoutTestController()
+{
+}
+
LayoutTestController::WorkQueue::~WorkQueue()
{
reset();
@@ -207,10 +212,9 @@ void LayoutTestController::WorkQueue::processWorkSoon()
if (!m_queue.isEmpty()) {
// We delay processing queued work to avoid recursion problems.
- m_timer.Start(base::TimeDelta(), this, &WorkQueue::processWork);
- } else if (!m_controller->m_waitUntilDone) {
+ postTask(new WorkQueueTask(this));
+ } else if (!m_controller->m_waitUntilDone)
m_controller->m_shell->testFinished();
- }
}
void LayoutTestController::WorkQueue::processWork()
@@ -320,11 +324,8 @@ void LayoutTestController::setAcceptsEditing(const CppArgumentList& arguments, C
void LayoutTestController::waitUntilDone(const CppArgumentList&, CppVariant* result)
{
- if (!webkit_support::BeingDebugged()) {
- webkit_support::PostDelayedTaskFromHere(
- m_timeoutFactory.NewRunnableMethod(&LayoutTestController::notifyDoneTimedOut),
- m_shell->layoutTestTimeout());
- }
+ if (!webkit_support::BeingDebugged())
+ postDelayedTask(new NotifyDoneTimedOutTask(this), m_shell->layoutTestTimeout());
m_waitUntilDone = true;
result->setNull();
}
@@ -332,17 +333,12 @@ void LayoutTestController::waitUntilDone(const CppArgumentList&, CppVariant* res
void LayoutTestController::notifyDone(const CppArgumentList&, CppVariant* result)
{
// Test didn't timeout. Kill the timeout timer.
- m_timeoutFactory.RevokeAll();
+ m_taskList.revokeAll();
completeNotifyDone(false);
result->setNull();
}
-void LayoutTestController::notifyDoneTimedOut()
-{
- completeNotifyDone(true);
-}
-
void LayoutTestController::completeNotifyDone(bool isTimeout)
{
if (m_waitUntilDone && !m_shell->webViewHost()->topLoadingFrame() && m_workQueue.isEmpty()) {
@@ -521,7 +517,7 @@ void LayoutTestController::reset()
else
m_closeRemainingWindows = true;
m_workQueue.reset();
- m_timeoutFactory.RevokeAll();
+ m_taskList.revokeAll();
}
void LayoutTestController::locationChangeDone()
@@ -1397,8 +1393,14 @@ void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments,
void LayoutTestController::setMockDeviceOrientation(const CppArgumentList& arguments, CppVariant* result)
{
- // FIXME: Implement for DeviceOrientation layout tests.
- // See https://bugs.webkit.org/show_bug.cgi?id=30335.
+ result->setNull();
+ if (arguments.size() < 6 || !arguments[0].isBool() || !arguments[1].isNumber() || !arguments[2].isBool() || !arguments[3].isNumber() || !arguments[4].isBool() || !arguments[5].isNumber())
+ return;
+
+ WebKit::WebDeviceOrientation orientation(arguments[0].toBoolean(), arguments[1].toDouble(), arguments[2].toBoolean(), arguments[3].toDouble(), arguments[4].toBoolean(), arguments[5].toDouble());
+
+ ASSERT(m_deviceOrientationClientMock);
+ m_deviceOrientationClientMock->setOrientation(orientation);
}
void LayoutTestController::setGeolocationPermission(const CppArgumentList& arguments, CppVariant* result)
@@ -1454,3 +1456,10 @@ void LayoutTestController::markerTextForListItem(const CppArgumentList& args, Cp
else
result->set(element.document().frame()->markerTextForListItem(element).utf8());
}
+
+WebKit::WebDeviceOrientationClient* LayoutTestController::deviceOrientationClient()
+{
+ if (!m_deviceOrientationClientMock.get())
+ m_deviceOrientationClientMock.set(new WebKit::WebDeviceOrientationClientMock());
+ return m_deviceOrientationClientMock.get();
+}
diff --git a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
index 6706157..7bb22ca 100644
--- a/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/chromium/LayoutTestController.h
@@ -42,13 +42,15 @@
#define LayoutTestController_h
#include "CppBoundClass.h"
-#include "base/timer.h" // FIXME: Remove this.
+#include "Task.h"
#include "public/WebString.h"
#include "public/WebURL.h"
#include <wtf/Deque.h>
#include <wtf/OwnPtr.h>
namespace WebKit {
+class WebDeviceOrientationClient;
+class WebDeviceOrientationClientMock;
class WebSpeechInputController;
class WebSpeechInputControllerMock;
class WebSpeechInputListener;
@@ -62,6 +64,8 @@ public:
// object.
LayoutTestController(TestShell*);
+ ~LayoutTestController();
+
// This function sets a flag that tells the test_shell to dump pages as
// plain text, rather than as a text representation of the renderer's state.
// It takes an optional argument, whether to dump pixels results or not.
@@ -116,7 +120,6 @@ public:
// to delay the completion of the test until notifyDone is called.
void waitUntilDone(const CppArgumentList&, CppVariant*);
void notifyDone(const CppArgumentList&, CppVariant*);
- void notifyDoneTimedOut();
// Methods for adding actions to the work queue. Used in conjunction with
// waitUntilDone/notifyDone above.
@@ -319,6 +322,7 @@ public:
void setWorkQueueFrozen(bool frozen) { m_workQueue.setFrozen(frozen); }
WebKit::WebSpeechInputController* speechInputController(WebKit::WebSpeechInputListener*);
+ WebKit::WebDeviceOrientationClient* deviceOrientationClient();
bool shouldDumpAsText() { return m_dumpAsText; }
bool shouldDumpEditingCallbacks() { return m_dumpEditingCallbacks; }
bool shouldDumpFrameLoadCallbacks() { return m_dumpFrameLoadCallbacks; }
@@ -360,6 +364,8 @@ public:
virtual bool run(TestShell* shell) = 0;
};
+ TaskList* taskList() { return &m_taskList; }
+
private:
friend class WorkItem;
friend class WorkQueue;
@@ -379,11 +385,17 @@ private:
void setFrozen(bool frozen) { m_frozen = frozen; }
bool isEmpty() { return m_queue.isEmpty(); }
+ TaskList* taskList() { return &m_taskList; }
private:
void processWork();
+ class WorkQueueTask: public MethodTask<WorkQueue> {
+ public:
+ WorkQueueTask(WorkQueue* object): MethodTask<WorkQueue>(object) {}
+ virtual void runIfValid() { m_object->processWork(); }
+ };
- base::OneShotTimer<WorkQueue> m_timer;
+ TaskList m_taskList;
Deque<WorkItem*> m_queue;
bool m_frozen;
LayoutTestController* m_controller;
@@ -396,6 +408,12 @@ private:
void logErrorToConsole(const std::string&);
void completeNotifyDone(bool isTimeout);
+ class NotifyDoneTimedOutTask: public MethodTask<LayoutTestController> {
+ public:
+ NotifyDoneTimedOutTask(LayoutTestController* object): MethodTask<LayoutTestController>(object) {}
+ virtual void runIfValid() { m_object->completeNotifyDone(true); }
+ };
+
bool pauseAnimationAtTimeOnElementWithId(const WebKit::WebString& animationName, double time, const WebKit::WebString& elementId);
bool pauseTransitionAtTimeOnElementWithId(const WebKit::WebString& propertyName, double time, const WebKit::WebString& elementId);
@@ -405,7 +423,7 @@ private:
void resumeAnimations();
// Used for test timeouts.
- ScopedRunnableMethodFactory<LayoutTestController> m_timeoutFactory;
+ TaskList m_taskList;
// Non-owning pointer. The LayoutTestController is owned by the host.
TestShell* m_shell;
@@ -493,6 +511,8 @@ private:
WebKit::WebURL m_userStyleSheetLocation;
OwnPtr<WebKit::WebSpeechInputControllerMock> m_speechInputControllerMock;
+
+ OwnPtr<WebKit::WebDeviceOrientationClientMock> m_deviceOrientationClientMock;
};
#endif // LayoutTestController_h
diff --git a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp
index 1098e38..7d4cbe3 100644
--- a/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/NotificationPresenter.cpp
@@ -31,14 +31,14 @@
#include "config.h"
#include "NotificationPresenter.h"
-#include "base/task.h" // FIXME: Remove this
#include "googleurl/src/gurl.h"
+#include "public/WebKit.h"
+#include "public/WebKitClient.h"
#include "public/WebNotification.h"
#include "public/WebNotificationPermissionCallback.h"
#include "public/WebSecurityOrigin.h"
#include "public/WebString.h"
#include "public/WebURL.h"
-#include "webkit/support/webkit_support.h"
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
@@ -51,9 +51,11 @@ static WebString identifierForNotification(const WebNotification& notification)
return notification.title();
}
-static void deferredDisplayDispatch(WebNotification notification)
+static void deferredDisplayDispatch(void* context)
{
- notification.dispatchDisplayEvent();
+ WebNotification* notification = static_cast<WebNotification*>(context);
+ notification->dispatchDisplayEvent();
+ delete notification;
}
void NotificationPresenter::grantPermission(const WebString& origin)
@@ -105,8 +107,7 @@ bool NotificationPresenter::show(const WebNotification& notification)
WTF::String id(identifier.data(), identifier.length());
m_activeNotifications.set(id, notification);
- WebNotification eventTarget(notification);
- webkit_support::PostTaskFromHere(NewRunnableFunction(&deferredDisplayDispatch, eventTarget));
+ webKitClient()->callOnMainThread(deferredDisplayDispatch, new WebNotification(notification));
return true;
}
diff --git a/WebKitTools/DumpRenderTree/chromium/Task.cpp b/WebKitTools/DumpRenderTree/chromium/Task.cpp
new file mode 100644
index 0000000..3f90d8c
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/chromium/Task.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Task.h"
+
+#include "public/WebKit.h"
+#include "public/WebKitClient.h"
+#include "webkit/support/webkit_support.h"
+
+WebTask::WebTask(TaskList* list): m_taskList(list) { m_taskList->registerTask(this); }
+WebTask::~WebTask() { m_taskList->unregisterTask(this); }
+
+void TaskList::unregisterTask(WebTask* task)
+{
+ size_t index = m_tasks.find(task);
+ if (index != notFound)
+ m_tasks.remove(index);
+}
+
+void TaskList::revokeAll()
+{
+ for (unsigned i = 0; i < m_tasks.size(); ++i)
+ m_tasks[i]->cancel();
+ m_tasks.clear();
+}
+
+static void invokeTask(void* context)
+{
+ WebTask* task = static_cast<WebTask*>(context);
+ task->run();
+ delete task;
+}
+
+void postTask(WebTask* task)
+{
+ WebKit::webKitClient()->callOnMainThread(invokeTask, static_cast<void*>(task));
+}
+
+void postDelayedTask(WebTask* task, int64_t ms)
+{
+ webkit_support::PostDelayedTask(invokeTask, static_cast<void*>(task), ms);
+}
+
+
diff --git a/WebKitTools/DumpRenderTree/chromium/Task.h b/WebKitTools/DumpRenderTree/chromium/Task.h
new file mode 100644
index 0000000..39fb8f2
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/chromium/Task.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * 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 Task_h
+#define Task_h
+
+#include <wtf/Vector.h>
+
+class TaskList;
+
+// WebTask represents a task which can run by postTask() or postDelayedTask().
+// it is named "WebTask", not "Task", to avoid conflist with base/task.h.
+class WebTask {
+public:
+ WebTask(TaskList*);
+ // The main code of this task.
+ // An implementation of run() should return immediately if cancel() was called.
+ virtual void run() = 0;
+ virtual void cancel() = 0;
+ virtual ~WebTask();
+private:
+ TaskList* m_taskList;
+};
+
+class TaskList {
+public:
+ TaskList() {}
+ ~TaskList() { revokeAll(); }
+ void registerTask(WebTask* task) { m_tasks.append(task); }
+ void unregisterTask(WebTask* task);
+ void revokeAll();
+private:
+ Vector<WebTask*> m_tasks;
+};
+
+// A task containing an object pointer of class T. Is is supposed that
+// runifValid() calls a member function of the object pointer.
+// Class T must have "TaskList* taskList()".
+template<class T> class MethodTask: public WebTask {
+public:
+ MethodTask(T* object): WebTask(object->taskList()), m_object(object) {}
+ virtual void run()
+ {
+ if (m_object)
+ runIfValid();
+ }
+ virtual void cancel() { m_object = 0; }
+ virtual void runIfValid() = 0;
+protected:
+ T* m_object;
+};
+
+void postTask(WebTask* task);
+void postDelayedTask(WebTask* task, int64_t ms);
+
+#endif // Task_h
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
index 21a153d..4557803 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestShell.cpp
@@ -42,6 +42,7 @@
#include "public/WebElement.h"
#include "public/WebFrame.h"
#include "public/WebHistoryItem.h"
+#include "public/WebKit.h"
#include "public/WebRuntimeFeatures.h"
#include "public/WebScriptController.h"
#include "public/WebSettings.h"
@@ -204,6 +205,7 @@ void TestShell::resetWebSettings(WebView& webView)
settings->setLocalStorageEnabled(true);
settings->setOfflineWebApplicationCacheEnabled(true);
settings->setAllowFileAccessFromFileURLs(true);
+ settings->setUserStyleSheetLocation(WebURL());
// LayoutTests were written with Safari Mac in mind which does not allow
// tabbing to links by default.
@@ -493,6 +495,7 @@ void TestShell::dump()
if (!frame)
return;
bool shouldDumpAsText = m_layoutTestController->shouldDumpAsText();
+ bool shouldGeneratePixelResults = m_layoutTestController->shouldGeneratePixelResults();
bool dumpedAnything = false;
if (m_params.dumpTree) {
dumpedAnything = true;
@@ -502,7 +505,10 @@ void TestShell::dump()
if (!shouldDumpAsText) {
// Plain text pages should be dumped as text
string mimeType = frame->dataSource()->response().mimeType().utf8();
- shouldDumpAsText = mimeType == "text/plain";
+ if (mimeType == "text/plain") {
+ shouldDumpAsText = true;
+ shouldGeneratePixelResults = false;
+ }
}
if (shouldDumpAsText) {
bool recursive = m_layoutTestController->shouldDumpChildFramesAsText();
@@ -520,7 +526,7 @@ void TestShell::dump()
if (dumpedAnything && m_params.printSeparators)
m_printer->handleTextFooter();
- if (m_params.dumpPixels && m_layoutTestController->shouldGeneratePixelResults()) {
+ if (m_params.dumpPixels && shouldGeneratePixelResults) {
// Image output: we write the image data to the file given on the
// command line (for the dump pixels argument), and the MD5 sum to
// stdout.
@@ -587,6 +593,8 @@ void TestShell::dumpImage(skia::PlatformCanvas* canvas) const
bool discardTransparency = false;
#elif OS(UNIX)
bool discardTransparency = true;
+ if (areLayoutTestImagesOpaque())
+ device.makeOpaque(0, 0, sourceBitmap.width(), sourceBitmap.height());
#endif
// Compute MD5 sum. We should have done this before calling
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShell.h b/WebKitTools/DumpRenderTree/chromium/TestShell.h
index 47261a3..cb5f862 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShell.h
+++ b/WebKitTools/DumpRenderTree/chromium/TestShell.h
@@ -186,5 +186,6 @@ private:
void platformInit(int*, char***);
void openStartupDialog();
+bool checkLayoutTestSystemDependencies();
#endif // TestShell_h
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp
index 56ee618..60408b9 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestShellGtk.cpp
@@ -203,3 +203,8 @@ void openStartupDialog()
gtk_dialog_run(GTK_DIALOG(dialog)); // Runs a nested message loop.
gtk_widget_destroy(dialog);
}
+
+bool checkLayoutTestSystemDependencies()
+{
+ return true;
+}
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm b/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm
index 71d990e..53ede56 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm
+++ b/WebKitTools/DumpRenderTree/chromium/TestShellMac.mm
@@ -137,3 +137,9 @@ void openStartupDialog()
[alert addButtonWithTitle:@"OK"];
[alert runModal];
}
+
+bool checkLayoutTestSystemDependencies()
+{
+ return true;
+}
+
diff --git a/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp b/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp
index 0d818c4..9efcf5a 100644
--- a/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/TestShellWin.cpp
@@ -35,9 +35,18 @@
#include "webkit/support/webkit_support.h"
#include <fcntl.h>
#include <io.h>
+#include <list>
#include <process.h>
#include <shlwapi.h>
+#include <string>
#include <sys/stat.h>
+#include <windows.h>
+
+#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \
+ offsetof(structName, member) + \
+ (sizeof static_cast<structName*>(0)->member)
+#define NONCLIENTMETRICS_SIZE_PRE_VISTA \
+ SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
// Theme engine
static WebThemeEngineDRT themeEngine;
@@ -154,3 +163,82 @@ void openStartupDialog()
{
::MessageBox(0, L"Attach to me?", L"DumpRenderTree", MB_OK);
}
+
+bool checkLayoutTestSystemDependencies()
+{
+ std::list<std::string> errors;
+
+ OSVERSIONINFOEX versionInfo;
+ ::ZeroMemory(&versionInfo, sizeof(OSVERSIONINFOEX));
+ versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ ::GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&versionInfo));
+
+ // Default to XP metrics, override if on Vista or win 7.
+ int requiredVScrollSize = 17;
+ int requiredFontSize = -11; // 8 pt
+ const wchar_t* requiredFont = L"Tahoma";
+ bool isVista = false;
+ bool isWin7 = false;
+ const DWORD major = versionInfo.dwMajorVersion;
+ const DWORD minor = versionInfo.dwMinorVersion;
+ const WORD type = versionInfo.wProductType;
+ if (major == 6 && minor == 1 && type == VER_NT_WORKSTATION) {
+ requiredFont = L"Segoe UI";
+ requiredFontSize = -12;
+ isWin7 = true;
+ } else if (major == 6 && !minor && type == VER_NT_WORKSTATION) {
+ requiredFont = L"Segoe UI";
+ requiredFontSize = -12; // 9 pt
+ isVista = true;
+ } else if (!(major == 5 && minor == 1 && type == VER_NT_WORKSTATION)) {
+ // The above check is for XP, so that means ...
+ errors.push_back("Unsupported Operating System version "
+ "(must use XP, Vista, or Windows 7).");
+ }
+
+ // This metric will be 17 when font size is "Normal".
+ // The size of drop-down menus depends on it.
+ int verticalScrollSize = ::GetSystemMetrics(SM_CXVSCROLL);
+ if (verticalScrollSize != requiredVScrollSize)
+ errors.push_back("Must use normal size fonts (96 dpi).");
+
+ // ClearType must be disabled, because the rendering is unpredictable.
+ BOOL fontSmoothingEnabled;
+ ::SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0);
+ int fontSmoothingType;
+ ::SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothingType, 0);
+ if (fontSmoothingEnabled && (fontSmoothingType == FE_FONTSMOOTHINGCLEARTYPE))
+ errors.push_back("ClearType must be disabled.");
+
+ // Check that we're using the default system fonts
+ NONCLIENTMETRICS metrics;
+ // Checks Vista or later.
+ metrics.cbSize = major >= 6 ? sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
+ const bool success = !!::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
+ ASSERT(success);
+ LOGFONTW* systemFonts[] =
+ {&metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont};
+
+ for (size_t i = 0; i < arraysize(systemFonts); ++i) {
+ if (systemFonts[i]->lfHeight != requiredFontSize || wcscmp(requiredFont, systemFonts[i]->lfFaceName)) {
+ if (isVista || isWin7)
+ errors.push_back("Must use either the Aero or Basic theme.");
+ else
+ errors.push_back("Must use the default XP theme (Luna).");
+ break;
+ }
+ }
+
+ if (!errors.empty()) {
+ fprintf(stderr, "%s",
+ "##################################################################\n"
+ "## Layout test system dependencies check failed.\n"
+ "##\n");
+ for (std::list<std::string>::iterator it = errors.begin(); it != errors.end(); ++it)
+ fprintf(stderr, "## %s\n", it->c_str());
+ fprintf(stderr, "%s",
+ "##\n"
+ "##################################################################\n");
+ }
+ return errors.empty();
+}
diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp
index fae3f56..1e3a4d6 100644
--- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp
+++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.cpp
@@ -512,6 +512,11 @@ WebSpeechInputController* WebViewHost::speechInputController(WebKit::WebSpeechIn
return m_shell->layoutTestController()->speechInputController(listener);
}
+WebKit::WebDeviceOrientationClient* WebViewHost::deviceOrientationClient()
+{
+ return m_shell->layoutTestController()->deviceOrientationClient();
+}
+
// WebWidgetClient -----------------------------------------------------------
void WebViewHost::didInvalidateRect(const WebRect& rect)
diff --git a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h
index 5067342..3a84ebd 100644
--- a/WebKitTools/DumpRenderTree/chromium/WebViewHost.h
+++ b/WebKitTools/DumpRenderTree/chromium/WebViewHost.h
@@ -45,6 +45,7 @@ class LayoutTestController;
class TestShell;
namespace WebKit {
class WebFrame;
+class WebDeviceOrientationClient;
class WebGeolocationServiceMock;
class WebSpeechInputController;
class WebSpeechInputListener;
@@ -130,6 +131,7 @@ class WebViewHost : public WebKit::WebViewClient, public WebKit::WebFrameClient,
virtual WebKit::WebNotificationPresenter* notificationPresenter();
virtual WebKit::WebGeolocationService* geolocationService();
virtual WebKit::WebSpeechInputController* speechInputController(WebKit::WebSpeechInputListener*);
+ virtual WebKit::WebDeviceOrientationClient* deviceOrientationClient();
// WebKit::WebWidgetClient
virtual void didInvalidateRect(const WebKit::WebRect&);
diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
index bd9c0c9..af2e403 100644
--- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp
@@ -96,6 +96,8 @@ static WebKitWebHistoryItem* prevTestBFItem = NULL;
const unsigned historyItemIndent = 8;
+static void runTest(const string& testPathOrURL);
+
static bool shouldLogFrameLoadDelegates(const string& pathOrURL)
{
return pathOrURL.find("loading/") != string::npos;
@@ -128,11 +130,13 @@ static void appendString(gchar*& target, gchar* string)
g_free(oldString);
}
-#if PLATFORM(X11)
static void initializeFonts()
{
+#if PLATFORM(X11)
static int numFonts = -1;
+ FcInit();
+
// Some tests may add or remove fonts via the @font-face rule.
// If that happens, font config should be re-created to suppress any unwanted change.
FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication);
@@ -160,8 +164,8 @@ static void initializeFonts()
appFontSet = FcConfigGetFonts(config, FcSetApplication);
numFonts = appFontSet->nfont;
-}
#endif
+}
static gchar* dumpFramesAsText(WebKitWebFrame* frame)
{
@@ -357,6 +361,50 @@ static void resetDefaultsToConsistentValues()
setlocale(LC_ALL, "");
}
+static bool useLongRunningServerMode(int argc, char *argv[])
+{
+ // This assumes you've already called getopt_long
+ return (argc == optind+1 && !strcmp(argv[optind], "-"));
+}
+
+static void runTestingServerLoop()
+{
+ // When DumpRenderTree runs in server mode, we just wait around for file names
+ // to be passed to us and read each in turn, passing the results back to the client
+ char filenameBuffer[2048];
+ while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
+ char* newLineCharacter = strchr(filenameBuffer, '\n');
+ if (newLineCharacter)
+ *newLineCharacter = '\0';
+
+ if (!strlen(filenameBuffer))
+ continue;
+
+ runTest(filenameBuffer);
+ }
+}
+
+static void initializeGlobalsFromCommandLineOptions(int argc, char *argv[])
+{
+ struct option options[] = {
+ {"notree", no_argument, &dumpTree, false},
+ {"pixel-tests", no_argument, &dumpPixels, true},
+ {"tree", no_argument, &dumpTree, true},
+ {NULL, 0, NULL, 0}
+ };
+
+ int option;
+ while ((option = getopt_long(argc, (char * const *)argv, "", options, NULL)) != -1) {
+ switch (option) {
+ case '?': // unknown or ambiguous option
+ case ':': // missing argument
+ exit(1);
+ break;
+ }
+ }
+}
+
+
void dump()
{
invalidateAnyPreviousWaitToDumpWatchdog();
@@ -516,9 +564,7 @@ static void runTest(const string& testPathOrURL)
if (prevTestBFItem)
g_object_ref(prevTestBFItem);
-#if PLATFORM(X11)
initializeFonts();
-#endif
// Focus the web view before loading the test to avoid focusing problems
gtk_widget_grab_focus(GTK_WIDGET(webView));
@@ -941,26 +987,8 @@ int main(int argc, char* argv[])
// We squelch all debug messages sent to the logger.
g_log_set_default_handler(logHandler, 0);
-#if PLATFORM(X11)
- FcInit();
+ initializeGlobalsFromCommandLineOptions(argc, argv);
initializeFonts();
-#endif
-
- struct option options[] = {
- {"notree", no_argument, &dumpTree, false},
- {"pixel-tests", no_argument, &dumpPixels, true},
- {"tree", no_argument, &dumpTree, true},
- {NULL, 0, NULL, 0}
- };
-
- int option;
- while ((option = getopt_long(argc, (char* const*)argv, "", options, NULL)) != -1)
- switch (option) {
- case '?': // unknown or ambiguous option
- case ':': // missing argument
- exit(1);
- break;
- }
window = gtk_window_new(GTK_WINDOW_POPUP);
container = GTK_WIDGET(gtk_scrolled_window_new(NULL, NULL));
@@ -980,19 +1008,9 @@ int main(int argc, char* argv[])
gcController = new GCController();
axController = new AccessibilityController();
- if (argc == optind+1 && strcmp(argv[optind], "-") == 0) {
- char filenameBuffer[2048];
+ if (useLongRunningServerMode(argc, argv)) {
printSeparators = true;
- while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
- char* newLineCharacter = strchr(filenameBuffer, '\n');
- if (newLineCharacter)
- *newLineCharacter = '\0';
-
- if (strlen(filenameBuffer) == 0)
- continue;
-
- runTest(filenameBuffer);
- }
+ runTestingServerLoop();
} else {
printSeparators = (optind < argc-1 || (dumpPixels && dumpTree));
for (int i = optind; i != argc; ++i)
diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp
index 63a4b81..fc118bc 100644
--- a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp
@@ -110,7 +110,7 @@ static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function
return JSValueMakeUndefined(context);
}
-bool prepareMouseButtonEvent(GdkEvent* event, int eventSenderButtonNumber)
+bool prepareMouseButtonEvent(GdkEvent* event, int eventSenderButtonNumber, guint modifiers)
{
WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
if (!view)
@@ -133,7 +133,7 @@ bool prepareMouseButtonEvent(GdkEvent* event, int eventSenderButtonNumber)
event->button.window = gtk_widget_get_window(GTK_WIDGET(view));
g_object_ref(event->button.window);
event->button.device = getDefaultGDKPointerDevice(event->button.window);
- event->button.state = getStateFlags();
+ event->button.state = modifiers | getStateFlags();
event->button.time = GDK_CURRENT_TIME;
event->button.axes = 0;
@@ -148,7 +148,7 @@ bool prepareMouseButtonEvent(GdkEvent* event, int eventSenderButtonNumber)
static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
GdkEvent* pressEvent = gdk_event_new(GDK_BUTTON_PRESS);
- if (!prepareMouseButtonEvent(pressEvent, 2))
+ if (!prepareMouseButtonEvent(pressEvent, 2, 0))
return JSValueMakeUndefined(context);
GdkEvent* releaseEvent = gdk_event_copy(pressEvent);
@@ -170,6 +170,36 @@ static void updateClickCount(int button)
clickCount++;
}
+static guint gdkModifersFromJSValue(JSContextRef context, const JSValueRef modifiers)
+{
+ JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0);
+ if (!modifiersArray)
+ return 0;
+
+ guint gdkModifiers = 0;
+ int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, JSStringCreateWithUTF8CString("length"), 0), 0);
+ for (int i = 0; i < modifiersCount; ++i) {
+ JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
+ JSStringRef string = JSValueToStringCopy(context, value, 0);
+ if (JSStringIsEqualToUTF8CString(string, "ctrlKey")
+ || JSStringIsEqualToUTF8CString(string, "addSelectionKey"))
+ gdkModifiers |= GDK_CONTROL_MASK;
+ else if (JSStringIsEqualToUTF8CString(string, "shiftKey")
+ || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey"))
+ gdkModifiers |= GDK_SHIFT_MASK;
+ else if (JSStringIsEqualToUTF8CString(string, "altKey"))
+ gdkModifiers |= GDK_MOD1_MASK;
+
+ // Currently the metaKey as defined in WebCore/platform/gtk/MouseEventGtk.cpp
+ // is GDK_MOD2_MASK. This code must be kept in sync with that file.
+ else if (JSStringIsEqualToUTF8CString(string, "metaKey"))
+ gdkModifiers |= GDK_MOD2_MASK;
+
+ JSStringRelease(string);
+ }
+ return gdkModifiers;
+}
+
static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
int button = 0;
@@ -177,9 +207,10 @@ static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function,
button = static_cast<int>(JSValueToNumber(context, arguments[0], exception));
g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
}
+ guint modifiers = argumentCount >= 2 ? gdkModifersFromJSValue(context, arguments[1]) : 0;
GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
- if (!prepareMouseButtonEvent(event, button))
+ if (!prepareMouseButtonEvent(event, button, modifiers))
return JSValueMakeUndefined(context);
buttonCurrentlyDown = event->button.button;
@@ -220,9 +251,10 @@ static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JS
button = static_cast<int>(JSValueToNumber(context, arguments[0], exception));
g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context));
}
+ guint modifiers = argumentCount >= 2 ? gdkModifersFromJSValue(context, arguments[1]) : 0;
GdkEvent* event = gdk_event_new(GDK_BUTTON_RELEASE);
- if (!prepareMouseButtonEvent(event, button))
+ if (!prepareMouseButtonEvent(event, button, modifiers))
return JSValueMakeUndefined(context);
lastClickPositionX = lastMousePositionX;
diff --git a/WebKitTools/DumpRenderTree/gtk/ImageDiff.cpp b/WebKitTools/DumpRenderTree/gtk/ImageDiff.cpp
index c40b232..7e2744a 100644
--- a/WebKitTools/DumpRenderTree/gtk/ImageDiff.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/ImageDiff.cpp
@@ -199,10 +199,15 @@ int main(int argc, char* argv[])
*newLineCharacter = '\0';
if (!strncmp("Content-Length: ", buffer, 16)) {
- char* context;
- strtok_r(buffer, " ", &context);
- long imageSize = strtol(strtok_r(0, " ", &context), 0, 10);
+ gchar** tokens = g_strsplit(buffer, " ", 0);
+ if (!tokens[1]) {
+ g_strfreev(tokens);
+ printf("Error, image size must be specified..\n");
+ return 1;
+ }
+ long imageSize = strtol(tokens[1], 0, 10);
+ g_strfreev(tokens);
if (imageSize > 0 && !actualImage) {
if (!(actualImage = readPixbufFromStdin(imageSize))) {
printf("Error, could not read actual image.\n");
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityTextMarkerMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityTextMarkerMac.mm
new file mode 100644
index 0000000..9170ab6
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityTextMarkerMac.mm
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import "AccessibilityTextMarker.h"
+#import "DumpRenderTree.h"
+
+#pragma mark AccessibilityTextMarker
+
+AccessibilityTextMarker::AccessibilityTextMarker(PlatformTextMarker marker)
+ : m_textMarker(marker)
+{
+}
+
+AccessibilityTextMarker::AccessibilityTextMarker(const AccessibilityTextMarker& marker)
+ : m_textMarker(marker.platformTextMarker())
+{
+}
+
+AccessibilityTextMarker::~AccessibilityTextMarker()
+{
+}
+
+bool AccessibilityTextMarker::isEqual(AccessibilityTextMarker* other)
+{
+ return [(id)platformTextMarker() isEqual:(id)other->platformTextMarker()];
+}
+
+PlatformTextMarker AccessibilityTextMarker::platformTextMarker() const
+{
+ return m_textMarker.get();
+}
+
+#pragma mark AccessibilityTextMarkerRange
+
+AccessibilityTextMarkerRange::AccessibilityTextMarkerRange(PlatformTextMarkerRange markerRange)
+ : m_textMarkerRange(markerRange)
+{
+}
+
+AccessibilityTextMarkerRange::AccessibilityTextMarkerRange(const AccessibilityTextMarkerRange& markerRange)
+ : m_textMarkerRange(markerRange.platformTextMarkerRange())
+{
+}
+
+AccessibilityTextMarkerRange::~AccessibilityTextMarkerRange()
+{
+}
+
+bool AccessibilityTextMarkerRange::isEqual(AccessibilityTextMarkerRange* other)
+{
+ return [(id)platformTextMarkerRange() isEqual:(id)other->platformTextMarkerRange()];
+}
+
+PlatformTextMarkerRange AccessibilityTextMarkerRange::platformTextMarkerRange() const
+{
+ return m_textMarkerRange.get();
+}
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
index d1592b2..fa4acf5 100644
--- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
@@ -1190,3 +1190,70 @@ void AccessibilityUIElement::removeSelection()
{
// FIXME: implement
}
+
+#if SUPPORTS_AX_TEXTMARKERS
+
+// Text markers
+AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUIElement" forParameter:element->platformUIElement()];
+ return AccessibilityTextMarkerRange(textMarkerRange);
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
+int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ NSNumber* lengthValue = [m_element accessibilityAttributeValue:@"AXLengthForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()];
+ return [lengthValue intValue];
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
+
+AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ NSArray* textMarkers = [NSArray arrayWithObjects:(id)startMarker->platformTextMarker(), (id)endMarker->platformTextMarker(), nil];
+ id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUnorderedTextMarkers" forParameter:textMarkers];
+ return AccessibilityTextMarkerRange(textMarkerRange);
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id textMarker = [m_element accessibilityAttributeValue:@"AXStartTextMarkerForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()];
+ return AccessibilityTextMarker(textMarker);
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
+AccessibilityTextMarker AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id textMarker = [m_element accessibilityAttributeValue:@"AXEndTextMarkerForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()];
+ return AccessibilityTextMarker(textMarker);
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
+AccessibilityUIElement AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ id uiElement = [m_element accessibilityAttributeValue:@"AXUIElementForTextMarker" forParameter:(id)marker->platformTextMarker()];
+ return AccessibilityUIElement(uiElement);
+ END_AX_OBJC_EXCEPTIONS
+
+ return 0;
+}
+
+#endif // SUPPORTS_AX_TEXTMARKERS
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
index e756ebf..ffcb18a 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -62,6 +62,7 @@
#import <WebKit/WebDataSourcePrivate.h>
#import <WebKit/WebDatabaseManagerPrivate.h>
#import <WebKit/WebDocumentPrivate.h>
+#import <WebKit/WebDeviceOrientationProviderMock.h>
#import <WebKit/WebEditingDelegate.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/WebHTMLRepresentationInternal.h>
@@ -292,6 +293,7 @@ WebView *createWebViewAndOffscreenWindow()
[webView setEditingDelegate:editingDelegate];
[webView setResourceLoadDelegate:resourceLoadDelegate];
[webView _setGeolocationProvider:[MockGeolocationProvider shared]];
+ [webView _setDeviceOrientationProvider:[[WebDeviceOrientationProviderMock alloc] init]];
// Register the same schemes that Safari does
[WebView registerURLSchemeAsLocal:@"feed"];
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index 97c177d..f55093e 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -45,9 +45,11 @@
#import <WebKit/WebApplicationCache.h>
#import <WebKit/WebBackForwardList.h>
#import <WebKit/WebCoreStatistics.h>
+#import <WebKit/WebDOMOperationsPrivate.h>
#import <WebKit/WebDataSource.h>
#import <WebKit/WebDatabaseManagerPrivate.h>
-#import <WebKit/WebDOMOperationsPrivate.h>
+#import <WebKit/WebDeviceOrientation.h>
+#import <WebKit/WebDeviceOrientationProviderMock.h>
#import <WebKit/WebFrame.h>
#import <WebKit/WebFrameViewPrivate.h>
#import <WebKit/WebGeolocationPosition.h>
@@ -336,9 +338,11 @@ void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidd
void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
{
- // FIXME: Implement for DeviceOrientation layout tests.
- // See https://bugs.webkit.org/show_bug.cgi?id=30335.
-
+ // DumpRenderTree configured the WebView to use WebDeviceOrientationProviderMock.
+ id<WebDeviceOrientationProvider> provider = [[mainFrame webView] _deviceOrientationProvider];
+ WebDeviceOrientationProviderMock* mockProvider = static_cast<WebDeviceOrientationProviderMock*>(provider);
+ WebDeviceOrientation* orientation = [[WebDeviceOrientation alloc] initWithCanProvideAlpha:canProvideAlpha alpha:alpha canProvideBeta:canProvideBeta beta:beta canProvideGamma:canProvideGamma gamma:gamma];
+ [mockProvider setOrientation:orientation];
}
void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy)
diff --git a/WebKitTools/DumpRenderTree/mac/ObjCController.m b/WebKitTools/DumpRenderTree/mac/ObjCController.m
index 641d2cc..f1d1c10 100644
--- a/WebKitTools/DumpRenderTree/mac/ObjCController.m
+++ b/WebKitTools/DumpRenderTree/mac/ObjCController.m
@@ -29,8 +29,12 @@
#import "config.h"
#import "ObjCController.h"
+// Avoid compile error in DOMPrivate.h.
+@class NSFont;
+
#import <JavaScriptCore/JavaScriptCore.h>
#import <WebKit/DOMAbstractView.h>
+#import <WebKit/DOMPrivate.h>
#import <WebKit/WebScriptObject.h>
#import <WebKit/WebView.h>
#import <pthread.h>
@@ -73,6 +77,7 @@ static void* runJavaScriptThread(void* arg)
|| aSelector == @selector(testValueForKey)
|| aSelector == @selector(testHasWebScriptKey:)
|| aSelector == @selector(testArray)
+ || aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:)
)
return NO;
return YES;
@@ -102,6 +107,8 @@ static void* runJavaScriptThread(void* arg)
return @"testHasWebScriptKey";
if (aSelector == @selector(testArray))
return @"testArray";
+ if (aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:))
+ return @"setSelectElementSelectedIndexAllowingMultiple";
return nil;
}
@@ -263,4 +270,16 @@ static void* runJavaScriptThread(void* arg)
return nil;
}
+#pragma mark -
+#pragma mark Testing Objective-C DOM HTML Bindings
+
+- (void)setSelectElement:(WebScriptObject *)element selectedIndex:(int)index allowingMultiple:(BOOL)allowingMultiple
+{
+ if (![element isKindOfClass:[DOMHTMLSelectElement class]])
+ return;
+
+ DOMHTMLSelectElement *select = (DOMHTMLSelectElement*)element;
+ [select _activateItemAtIndex:index allowMultipleSelection:allowingMultiple];
+}
+
@end
diff --git a/WebKitTools/DumpRenderTree/mac/TextInputController.m b/WebKitTools/DumpRenderTree/mac/TextInputController.m
index 3ea9c22..a049ac5 100644
--- a/WebKitTools/DumpRenderTree/mac/TextInputController.m
+++ b/WebKitTools/DumpRenderTree/mac/TextInputController.m
@@ -33,6 +33,7 @@
#import <AppKit/NSInputManager.h>
#import <WebKit/WebDocument.h>
#import <WebKit/WebFrame.h>
+#import <WebKit/WebFramePrivate.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/WebHTMLViewPrivate.h>
#import <WebKit/WebScriptObject.h>
@@ -169,7 +170,8 @@
|| aSelector == @selector(characterIndexForPointX:Y:)
|| aSelector == @selector(validAttributesForMarkedText)
|| aSelector == @selector(attributedStringWithString:)
- || aSelector == @selector(setInputMethodHandler:))
+ || aSelector == @selector(setInputMethodHandler:)
+ || aSelector == @selector(hasSpellingMarker:length:))
return NO;
return YES;
}
@@ -194,6 +196,8 @@
return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
else if (aSelector == @selector(setInputMethodHandler:))
return @"setInputMethodHandler";
+ else if (aSelector == @selector(hasSpellingMarker:length:))
+ return @"hasSpellingMarker";
return nil;
}
@@ -427,4 +431,9 @@
return YES;
}
+- (BOOL)hasSpellingMarker:(int)from length:(int)length
+{
+ return [[webView mainFrame] hasSpellingMarker:from length:length];
+}
+
@end
diff --git a/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp b/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp
index 8ee68db..9282e2f 100644
--- a/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp
+++ b/WebKitTools/DumpRenderTree/qt/ImageDiff.cpp
@@ -132,7 +132,10 @@ int main(int argc, char* argv[])
buffer.close();
const QByteArray &data = buffer.data();
printf("Content-Length: %lu\n", static_cast<unsigned long>(data.length()));
- fwrite(data.constData(), 1, data.length(), stdout);
+
+ // We have to use the return value of fwrite to avoid "ignoring return value" gcc warning
+ // See https://bugs.webkit.org/show_bug.cgi?id=45384 for details.
+ if (fwrite(data.constData(), 1, data.length(), stdout)) {}
fprintf(stdout, "diff: %01.2f%% failed\n", difference);
}
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
index 125c6c6..1e765c6 100644
--- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.vcproj
@@ -578,6 +578,14 @@
>
</File>
<File
+ RelativePath="..\AccessibilityTextMarker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\AccessibilityTextMarker.h"
+ >
+ </File>
+ <File
RelativePath=".\DraggingInfo.h"
>
</File>
diff --git a/WebKit/efl/EWebLauncher/main.c b/WebKitTools/EWebLauncher/main.c
index c1956a2..c1956a2 100644
--- a/WebKit/efl/EWebLauncher/main.c
+++ b/WebKitTools/EWebLauncher/main.c
diff --git a/WebKitTools/GNUmakefile.am b/WebKitTools/GNUmakefile.am
index 39df421..292ca7e 100644
--- a/WebKitTools/GNUmakefile.am
+++ b/WebKitTools/GNUmakefile.am
@@ -49,6 +49,8 @@ Programs_DumpRenderTree_SOURCES = \
WebKitTools/DumpRenderTree/DumpRenderTreePrefix.h \
WebKitTools/DumpRenderTree/AccessibilityController.cpp \
WebKitTools/DumpRenderTree/AccessibilityController.h \
+ WebKitTools/DumpRenderTree/AccessibilityTextMarker.cpp \
+ WebKitTools/DumpRenderTree/AccessibilityTextMarker.h \
WebKitTools/DumpRenderTree/AccessibilityUIElement.cpp \
WebKitTools/DumpRenderTree/AccessibilityUIElement.h \
WebKitTools/DumpRenderTree/GCController.cpp \
diff --git a/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m b/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m
index 17958c7..1fffce6 100644
--- a/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m
+++ b/WebKitTools/MiniBrowser/mac/WebBundle/WebBundleMain.m
@@ -37,7 +37,7 @@ static WKBundleRef globalBundle;
// WKBundlePageClient functions
-void didClearWindowObjectForFrame(WKBundlePageRef page, WKBundleFrameRef frame, JSGlobalContextRef context, JSObjectRef window, const void *clientInfo)
+void didClearWindowObjectForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void *clientInfo)
{
WKURLRef wkURL = WKBundleFrameCopyURL(WKBundlePageGetMainFrame(page));
CFURLRef cfURL = WKURLCopyCFURL(0, wkURL);
diff --git a/WebKitTools/MiniBrowser/qt/BrowserView.cpp b/WebKitTools/MiniBrowser/qt/BrowserView.cpp
new file mode 100644
index 0000000..a5e06ec
--- /dev/null
+++ b/WebKitTools/MiniBrowser/qt/BrowserView.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2010 University of Szeged
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 "BrowserView.h"
+
+#include <QGraphicsScene>
+#include "WKContext.h"
+
+static QWKPage* createNewPage(QWKPage* page)
+{
+ return page;
+}
+
+BrowserView::BrowserView(QWidget* parent)
+ : QGraphicsView(parent)
+ , m_item(0)
+{
+ m_context.adopt(WKContextGetSharedProcessContext());
+
+ WKRetainPtr<WKPageNamespaceRef> pageNamespace(AdoptWK, WKPageNamespaceCreate(m_context.get()));
+
+ m_item = new QGraphicsWKView(pageNamespace.get(), QGraphicsWKView::Simple, 0);
+ setScene(new QGraphicsScene(this));
+ scene()->addItem(m_item);
+
+ setFrameShape(QFrame::NoFrame);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ connect(m_item, SIGNAL(titleChanged(QString)), this, SLOT(setWindowTitle(QString)));
+ m_item->page()->setCreateNewPageFunction(createNewPage);
+}
+
+void BrowserView::resizeEvent(QResizeEvent* event)
+{
+ QGraphicsView::resizeEvent(event);
+ QRectF rect(QPoint(0, 0), event->size());
+ m_item->setGeometry(rect);
+ scene()->setSceneRect(rect);
+}
+
+void BrowserView::load(const QString& url)
+{
+ return m_item->load(QUrl::fromUserInput(url));
+}
+
+QGraphicsWKView* BrowserView::view() const
+{
+ return m_item;
+}
diff --git a/WebKitTools/MiniBrowser/qt/BrowserView.h b/WebKitTools/MiniBrowser/qt/BrowserView.h
new file mode 100644
index 0000000..42b7658
--- /dev/null
+++ b/WebKitTools/MiniBrowser/qt/BrowserView.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2010 University of Szeged
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 BrowserView_h
+#define BrowserView_h
+
+#include <QGraphicsView>
+#include "qgraphicswkview.h"
+#include "WKRetainPtr.h"
+
+class BrowserView : public QGraphicsView {
+ Q_OBJECT
+
+public:
+ BrowserView(QWidget* parent = 0);
+ virtual ~BrowserView() { delete m_item; }
+
+ void load(const QString&);
+ QGraphicsWKView* view() const;
+
+protected:
+ virtual void resizeEvent(QResizeEvent*);
+
+private:
+ QGraphicsWKView* m_item;
+ WKRetainPtr<WKContextRef> m_context;
+};
+
+#endif
diff --git a/WebKitTools/MiniBrowser/qt/BrowserWindow.cpp b/WebKitTools/MiniBrowser/qt/BrowserWindow.cpp
index 2e0dccd..a703788 100644
--- a/WebKitTools/MiniBrowser/qt/BrowserWindow.cpp
+++ b/WebKitTools/MiniBrowser/qt/BrowserWindow.cpp
@@ -27,55 +27,8 @@
*/
#include "BrowserWindow.h"
-#include "WKPageNamespace.h"
-#include "qwkpage.h"
-
-static QWKPage* createNewPage(QWKPage* page)
-{
- return page;
-}
-
-BrowserView::BrowserView(QWidget* parent)
- : QGraphicsView(parent)
- , m_item(0)
-{
- m_context.adopt(WKContextGetSharedProcessContext());
-
- WKRetainPtr<WKPageNamespaceRef> pageNamespace(AdoptWK, WKPageNamespaceCreate(m_context.get()));
-
- m_item = new QGraphicsWKView(pageNamespace.get(), QGraphicsWKView::Simple, 0);
- setScene(new QGraphicsScene(this));
- scene()->addItem(m_item);
-
- setFrameShape(QFrame::NoFrame);
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-
- connect(m_item, SIGNAL(titleChanged(QString)), this, SLOT(setWindowTitle(QString)));
- m_item->page()->setCreateNewPageFunction(createNewPage);
-}
-void BrowserView::resizeEvent(QResizeEvent* event)
-{
- QGraphicsView::resizeEvent(event);
- QRectF rect(QPoint(0, 0), event->size());
- m_item->setGeometry(rect);
- scene()->setSceneRect(rect);
-}
-
-void BrowserView::load(const QUrl& url)
-{
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
- return m_item->load(QUrl::fromUserInput(url.toString()));
-#else
- return m_item->load(url);
-#endif
-}
-
-QGraphicsWKView* BrowserView::view() const
-{
- return m_item;
-}
+#include "WKPageNamespace.h"
BrowserWindow::BrowserWindow()
{
@@ -106,19 +59,20 @@ BrowserWindow::BrowserWindow()
this->setCentralWidget(m_browser);
m_browser->setFocus(Qt::OtherFocusReason);
+
+ resize(960, 640);
+ show();
}
void BrowserWindow::load(const QString& url)
{
m_addressBar->setText(url);
- m_browser->load(QUrl(url));
+ m_browser->load(url);
}
BrowserWindow* BrowserWindow::newWindow(const QString& url)
{
BrowserWindow* window = new BrowserWindow();
- window->resize(960, 640);
- window->show();
window->load(url);
return window;
}
diff --git a/WebKitTools/MiniBrowser/qt/BrowserWindow.h b/WebKitTools/MiniBrowser/qt/BrowserWindow.h
index 99d3e82..47e55b5 100644
--- a/WebKitTools/MiniBrowser/qt/BrowserWindow.h
+++ b/WebKitTools/MiniBrowser/qt/BrowserWindow.h
@@ -26,33 +26,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef BrowserWindow_h
+#define BrowserWindow_h
+
#define PLATFORM(x) 0
-#include "WKContext.h"
-#include "WKRetainPtr.h"
-#include "qgraphicswkview.h"
+#include "BrowserView.h"
#include <QtGui>
-#include <QGraphicsScene>
-#include <QGraphicsView>
-#include <stdint.h>
-
-class BrowserView : public QGraphicsView {
- Q_OBJECT
-
-public:
- BrowserView(QWidget* parent = 0);
- virtual ~BrowserView() { delete m_item; }
-
- void load(const QUrl&);
- QGraphicsWKView* view() const;
-
-protected:
- virtual void resizeEvent(QResizeEvent*);
-
-private:
- QGraphicsWKView* m_item;
- WKRetainPtr<WKContextRef> m_context;
-};
class BrowserWindow : public QMainWindow {
Q_OBJECT
@@ -76,3 +56,5 @@ private:
QMenuBar* m_menu;
QLineEdit* m_addressBar;
};
+
+#endif
diff --git a/WebKitTools/MiniBrowser/qt/MiniBrowser.pro b/WebKitTools/MiniBrowser/qt/MiniBrowser.pro
index 274b9e5..e42c49a 100644
--- a/WebKitTools/MiniBrowser/qt/MiniBrowser.pro
+++ b/WebKitTools/MiniBrowser/qt/MiniBrowser.pro
@@ -3,9 +3,11 @@ TARGET = MiniBrowser
SOURCES += \
main.cpp \
+ BrowserView.cpp \
BrowserWindow.cpp \
HEADERS += \
+ BrowserView.h \
BrowserWindow.h \
CONFIG += uitools
diff --git a/WebKitTools/MiniBrowser/qt/main.cpp b/WebKitTools/MiniBrowser/qt/main.cpp
index 2bc346b..8ff3de8 100644
--- a/WebKitTools/MiniBrowser/qt/main.cpp
+++ b/WebKitTools/MiniBrowser/qt/main.cpp
@@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <QtGui>
#include "BrowserWindow.h"
+#include <QtGui>
int main(int argc, char** argv) {
QApplication app(argc, argv);
@@ -44,11 +44,11 @@ int main(int argc, char** argv) {
urls.append("http://www.google.com");
}
- BrowserWindow* window = 0;
- foreach (QString url, urls) {
- window = new BrowserWindow();
- window->newWindow(url);
- }
+ BrowserWindow* window = new BrowserWindow();
+ window->load(urls[0]);
+
+ for (int i = 1; i < urls.size(); ++i)
+ window->newWindow(urls[i]);
app.exec();
diff --git a/WebKitTools/MiniBrowser/win/BrowserWindow.cpp b/WebKitTools/MiniBrowser/win/BrowserWindow.cpp
index e519b00..dc43a68 100644
--- a/WebKitTools/MiniBrowser/win/BrowserWindow.cpp
+++ b/WebKitTools/MiniBrowser/win/BrowserWindow.cpp
@@ -70,6 +70,10 @@ LRESULT BrowserWindow::wndProc(HWND window, UINT message, WPARAM wParam, LPARAM
bool handled = true;
switch (message) {
+ case WM_ERASEBKGND:
+ lResult = 1;
+ break;
+
case WM_COMMAND:
lResult = onCommand(LOWORD(wParam), handled);
break;
diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm
index 05d7bd8..dd08baa 100644
--- a/WebKitTools/Scripts/VCSUtils.pm
+++ b/WebKitTools/Scripts/VCSUtils.pm
@@ -94,7 +94,7 @@ my $gitDiffStartRegEx = qr#^diff --git (\w/)?(.+) (\w/)?([^\r\n]+)#;
my $svnDiffStartRegEx = qr#^Index: ([^\r\n]+)#;
my $svnPropertiesStartRegEx = qr#^Property changes on: ([^\r\n]+)#; # $1 is normally the same as the index path.
my $svnPropertyStartRegEx = qr#^(Modified|Name|Added|Deleted): ([^\r\n]+)#; # $2 is the name of the property.
-my $svnPropertyValueStartRegEx = qr#^ (\+|-) ([^\r\n]+)#; # $2 is the start of the property's value (which may span multiple lines).
+my $svnPropertyValueStartRegEx = qr#^ (\+|-|Merged|Reverse-merged) ([^\r\n]+)#; # $2 is the start of the property's value (which may span multiple lines).
# This method is for portability. Return the system-appropriate exit
# status of a child process.
@@ -1037,9 +1037,9 @@ sub parseSvnProperty($$)
}
my $propertyChangeDelta;
- if ($propertyValueType eq '+') {
+ if ($propertyValueType eq "+" || $propertyValueType eq "Merged") {
$propertyChangeDelta = 1;
- } elsif ($propertyValueType eq '-') {
+ } elsif ($propertyValueType eq "-" || $propertyValueType eq "Reverse-merged") {
$propertyChangeDelta = -1;
} else {
die("Not reached.");
@@ -1093,7 +1093,7 @@ sub parseSvnPropertyValue($$)
$propertyValue = $2; # Does not include the end-of-line character(s).
$eol = $POSTMATCH;
} else {
- die("Failed to find property value beginning with '+' or '-': \"$_\".");
+ die("Failed to find property value beginning with '+', '-', 'Merged', or 'Reverse-merged': \"$_\".");
}
while (<$fileHandle>) {
diff --git a/WebKitTools/Scripts/do-webcore-rename b/WebKitTools/Scripts/do-webcore-rename
index 54fb0af..a1674de 100755
--- a/WebKitTools/Scripts/do-webcore-rename
+++ b/WebKitTools/Scripts/do-webcore-rename
@@ -96,7 +96,7 @@ sub wanted
my $isDOMTypeRename = 0;
my %renames = (
# Renames go here in the form of:
- # "HTMLDocumentParser" => "LegacyHTMLDocumentParser",
+ "DocLoader" => "CachedResourceLoader",
);
my %renamesContemplatedForTheFuture = (
diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply
index 33b2279..1cf9c01 100755
--- a/WebKitTools/Scripts/svn-apply
+++ b/WebKitTools/Scripts/svn-apply
@@ -280,7 +280,7 @@ sub isDirectoryEmptyForRemoval($)
opendir DIR, $dir or die "Could not open '$dir' to list files: $?";
for (my $item = readdir DIR; $item && $directoryIsEmpty; $item = readdir DIR) {
next if exists $removeDirectoryIgnoreList{$item};
- if (! -d File::Spec->catdir($dir, $item)) {
+ if (-d File::Spec->catdir($dir, $item)) {
$directoryIsEmpty = 0;
} else {
next if (scmWillDeleteFile(File::Spec->catdir($dir, $item)));
diff --git a/WebKitTools/Scripts/validate-committer-lists b/WebKitTools/Scripts/validate-committer-lists
index ad3d358..2519e01 100755
--- a/WebKitTools/Scripts/validate-committer-lists
+++ b/WebKitTools/Scripts/validate-committer-lists
@@ -38,7 +38,7 @@ import urllib2
from datetime import date, datetime, timedelta
from webkitpy.common.config.committers import CommitterList
from webkitpy.common.system.deprecated_logging import log, error
-from webkitpy.scm import Git
+from webkitpy.common.checkout.scm import Git
# WebKit includes a built copy of BeautifulSoup in Scripts/webkitpy
# so this import should always succeed.
diff --git a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl
index e305484..4f05431 100644
--- a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl
+++ b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnDiffFooter.pl
@@ -60,6 +60,55 @@ undef],
},
{
# New test
+ diffName => "simple: add svn:mergeinfo",
+ inputText => <<'END',
+Property changes on: Makefile
+___________________________________________________________________
+Added: svn:mergeinfo
+ Merged /trunk/Makefile:r33020
+END
+ expectedReturn => [
+{
+ propertyPath => "Makefile",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "simple: delete svn:mergeinfo",
+ inputText => <<'END',
+Property changes on: Makefile
+___________________________________________________________________
+Deleted: svn:mergeinfo
+ Reverse-merged /trunk/Makefile:r33020
+END
+ expectedReturn => [
+{
+ propertyPath => "Makefile",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "simple: modified svn:mergeinfo",
+ inputText => <<'END',
+Property changes on: Makefile
+___________________________________________________________________
+Modified: svn:mergeinfo
+ Reverse-merged /trunk/Makefile:r33020
+ Merged /trunk/Makefile:r41697
+END
+ expectedReturn => [
+{
+ propertyPath => "Makefile",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
diffName => "simple: delete svn:executable",
inputText => <<'END',
Property changes on: FileA
diff --git a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnProperty.pl b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnProperty.pl
index bdca1ab..6914051 100644
--- a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnProperty.pl
+++ b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnProperty.pl
@@ -73,11 +73,77 @@ END
undef],
expectedNextLine => undef,
},
+{
+ # New test
+ diffName => "simple: add svn:mergeinfo",
+ inputText => <<'END',
+Added: svn:mergeinfo
+ Merged /trunk/Makefile:r33020
+END
+ expectedReturn => [
+{
+ name => "svn:mergeinfo",
+ propertyChangeDelta => 1,
+ value => "/trunk/Makefile:r33020",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "simple: delete svn:mergeinfo",
+ inputText => <<'END',
+Deleted: svn:mergeinfo
+ Reverse-merged /trunk/Makefile:r33020
+END
+ expectedReturn => [
+{
+ name => "svn:mergeinfo",
+ propertyChangeDelta => -1,
+ value => "/trunk/Makefile:r33020",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "simple: modified svn:mergeinfo",
+ inputText => <<'END',
+Modified: svn:mergeinfo
+ Reverse-merged /trunk/Makefile:r33020
+ Merged /trunk/Makefile:r41697
+END
+ expectedReturn => [
+{
+ name => "svn:mergeinfo",
+ propertyChangeDelta => 1,
+ value => "/trunk/Makefile:r41697",
+},
+undef],
+ expectedNextLine => undef,
+},
####
# Using SVN 1.4 syntax
##
{
# New test
+ diffName => "simple: modified svn:mergeinfo using SVN 1.4 syntax",
+ inputText => <<'END',
+Name: svn:mergeinfo
+ Reverse-merged /trunk/Makefile:r33020
+ Merged /trunk/Makefile:r41697
+END
+ expectedReturn => [
+{
+ name => "svn:mergeinfo",
+ propertyChangeDelta => 1,
+ value => "/trunk/Makefile:r41697",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
diffName => "simple: delete svn:executable using SVN 1.4 syntax",
inputText => <<'END',
Name: svn:executable
@@ -459,6 +525,40 @@ END
"Added: svn:executable\n"],
expectedNextLine => " + *\n",
},
+{
+ # New test
+ diffName => "'Merged' change followed by 'Merged' change",
+ inputText => <<'END',
+Added: svn:mergeinfo
+ Merged /trunk/Makefile:r33020
+ Merged /trunk/Makefile.shared:r58350
+END
+ expectedReturn => [
+{
+ name => "svn:mergeinfo",
+ propertyChangeDelta => 1,
+ value => "/trunk/Makefile.shared:r58350",
+},
+undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "'Reverse-merged' change followed by 'Reverse-merged' change",
+ inputText => <<'END',
+Deleted: svn:mergeinfo
+ Reverse-merged /trunk/Makefile:r33020
+ Reverse-merged /trunk/Makefile.shared:r58350
+END
+ expectedReturn => [
+{
+ name => "svn:mergeinfo",
+ propertyChangeDelta => -1,
+ value => "/trunk/Makefile.shared:r58350",
+},
+undef],
+ expectedNextLine => undef,
+},
####
# Property values with trailing new lines.
##
diff --git a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnPropertyValue.pl b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnPropertyValue.pl
index 5fc2ff1..2de8ae3 100644
--- a/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnPropertyValue.pl
+++ b/WebKitTools/Scripts/webkitperl/VCSUtils_unittest/parseSvnPropertyValue.pl
@@ -58,6 +58,24 @@ END
},
{
# New test
+ diffName => "'Merged' change",
+ inputText => <<'END',
+ Merged /trunk/Makefile:r33020
+END
+ expectedReturn => ["/trunk/Makefile:r33020", undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "'Reverse-merged' change",
+ inputText => <<'END',
+ Reverse-merged /trunk/Makefile:r33020
+END
+ expectedReturn => ["/trunk/Makefile:r33020", undef],
+ expectedNextLine => undef,
+},
+{
+ # New test
diffName => "single-line '-' change followed by empty line with Unix line endings",
inputText => <<'END',
- *
@@ -152,6 +170,47 @@ END
expectedReturn => ["A\nlong sentence that spans\nmultiple lines.", " + Another\n"],
expectedNextLine => "long sentence that spans\n",
},
+{
+ # New test
+ diffName => "'Reverse-merged' change followed by 'Merge' change",
+ inputText => <<'END',
+ Reverse-merged /trunk/Makefile:r33020
+ Merged /trunk/Makefile:r41697
+END
+ expectedReturn => ["/trunk/Makefile:r33020", " Merged /trunk/Makefile:r41697\n"],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "'Merged' change followed by 'Merge' change",
+ inputText => <<'END',
+ Merged /trunk/Makefile:r33020
+ Merged /trunk/Makefile.shared:r58350
+END
+ expectedReturn => ["/trunk/Makefile:r33020", " Merged /trunk/Makefile.shared:r58350\n"],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "'Reverse-merged' change followed by 'Reverse-merged' change",
+ inputText => <<'END',
+ Reverse-merged /trunk/Makefile:r33020
+ Reverse-merged /trunk/Makefile.shared:r58350
+END
+ expectedReturn => ["/trunk/Makefile:r33020", " Reverse-merged /trunk/Makefile.shared:r58350\n"],
+ expectedNextLine => undef,
+},
+{
+ # New test
+ diffName => "'Reverse-merged' change followed by 'Reverse-merged' change followed by 'Merged' change",
+ inputText => <<'END',
+ Reverse-merged /trunk/Makefile:r33020
+ Reverse-merged /trunk/Makefile.shared:r58350
+ Merged /trunk/ChangeLog:r64190
+END
+ expectedReturn => ["/trunk/Makefile:r33020", " Reverse-merged /trunk/Makefile.shared:r58350\n"],
+ expectedNextLine => " Merged /trunk/ChangeLog:r64190\n",
+},
);
my $testCasesCount = @testCaseHashRefs;
diff --git a/WebKitTools/Scripts/webkitpy/common/config/committers.py b/WebKitTools/Scripts/webkitpy/common/config/committers.py
index 19ebc5f..6a45cab 100644
--- a/WebKitTools/Scripts/webkitpy/common/config/committers.py
+++ b/WebKitTools/Scripts/webkitpy/common/config/committers.py
@@ -74,7 +74,6 @@ committers_unable_to_review = [
Committer("Andrei Popescu", "andreip@google.com", "andreip"),
Committer("Andrew Wellington", ["andrew@webkit.org", "proton@wiretapped.net"], "proton"),
Committer("Andras Becsi", "abecsi@webkit.org", "bbandix"),
- Committer("Andreas Kling", "andreas.kling@nokia.com", "kling"),
Committer("Andy Estes", "aestes@apple.com", "estes"),
Committer("Anthony Ricaud", "rik@webkit.org", "rik"),
Committer("Anton Muhin", "antonm@chromium.org", "antonm"),
@@ -90,6 +89,7 @@ committers_unable_to_review = [
Committer("Chang Shu", "Chang.Shu@nokia.com"),
Committer("Chris Evans", "cevans@google.com"),
Committer("Chris Petersen", "cpetersen@apple.com", "cpetersen"),
+ Committer("Chris Rogers", "crogers@google.com", "crogers"),
Committer("Christian Dywan", ["christian@twotoasts.de", "christian@webkit.org"]),
Committer("Collin Jackson", "collinj@webkit.org"),
Committer("Csaba Osztrogonac", "ossy@webkit.org", "ossy"),
@@ -110,12 +110,12 @@ committers_unable_to_review = [
Committer("Girish Ramakrishnan", ["girish@forwardbias.in", "ramakrishnan.girish@gmail.com"]),
Committer("Graham Dennis", ["Graham.Dennis@gmail.com", "gdennis@webkit.org"]),
Committer("Greg Bolsinga", "bolsinga@apple.com"),
+ Committer("Hans Wennborg", "hans@chromium.org", "hwennborg"),
Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]),
Committer("Ilya Tikhonovsky", "loislo@chromium.org", "loislo"),
Committer("Jakob Petsovits", ["jpetsovits@rim.com", "jpetso@gmx.at"], "jpetso"),
Committer("Jakub Wieczorek", "jwieczorek@webkit.org", "fawek"),
Committer("James Hawkins", ["jhawkins@chromium.org", "jhawkins@google.com"], "jhawkins"),
- Committer("James Robinson", ["jamesr@chromium.org", "jamesr@google.com"], "jamesr"),
Committer("Jay Civelli", "jcivelli@chromium.org", "jcivelli"),
Committer("Jens Alfke", ["snej@chromium.org", "jens@apple.com"]),
Committer("Jer Noble", "jer.noble@apple.com", "jernoble"),
@@ -146,6 +146,7 @@ committers_unable_to_review = [
Committer("Matt Perry", "mpcomplete@chromium.org"),
Committer("Maxime Britto", ["maxime.britto@gmail.com", "britto@apple.com"]),
Committer("Maxime Simon", ["simon.maxime@gmail.com", "maxime.simon@webkit.org"], "maxime.simon"),
+ Committer("Michael Saboff", "msaboff@apple.com"),
Committer("Michelangelo De Simone", "michelangelo@webkit.org", "michelangelo"),
Committer("Mike Belshe", ["mbelshe@chromium.org", "mike@belshe.com"]),
Committer("Mike Fenton", ["mifenton@rim.com", "mike.fenton@torchmobile.com"], "mfenton"),
@@ -159,9 +160,10 @@ committers_unable_to_review = [
Committer("Philippe Normand", ["pnormand@igalia.com", "philn@webkit.org"], "philn-tp"),
Committer("Pierre d'Herbemont", ["pdherbemont@free.fr", "pdherbemont@apple.com"], "pdherbemont"),
Committer("Pierre-Olivier Latour", "pol@apple.com", "pol"),
- Committer("Robert Hogan", ["robert@webkit.org", "robert@roberthogan.net"], "mwenge"),
+ Committer("Robert Hogan", ["robert@webkit.org", "robert@roberthogan.net", "lists@roberthogan.net"], "mwenge"),
Committer("Roland Steiner", "rolandsteiner@chromium.org"),
Committer("Ryosuke Niwa", "rniwa@webkit.org", "rniwa"),
+ Committer("Satish Sampath", "satish@chromium.org"),
Committer("Scott Violet", "sky@chromium.org", "sky"),
Committer("Stephen White", "senorblanco@chromium.org", "senorblanco"),
Committer("Tony Gentilcore", "tonyg@chromium.org", "tonyg-cr"),
@@ -192,14 +194,15 @@ reviewers_list = [
Reviewer("Ada Chan", "adachan@apple.com", "chanada"),
Reviewer("Adam Barth", "abarth@webkit.org", "abarth"),
Reviewer("Adam Roben", "aroben@apple.com", "aroben"),
- Reviewer("Adam Treat", ["treat@kde.org", "treat@webkit.org"], "manyoso"),
+ Reviewer("Adam Treat", ["treat@kde.org", "treat@webkit.org", "atreat@rim.com"], "manyoso"),
Reviewer("Adele Peterson", "adele@apple.com", "adele"),
Reviewer("Alexey Proskuryakov", ["ap@webkit.org", "ap@apple.com"], "ap"),
Reviewer("Alice Liu", "alice.liu@apple.com", "aliu"),
Reviewer("Alp Toker", ["alp@nuanti.com", "alp@atoker.com", "alp@webkit.org"], "alp"),
Reviewer("Anders Carlsson", ["andersca@apple.com", "acarlsson@apple.com"], "andersca"),
- Reviewer("Antonio Gomes", "tonikitoo@webkit.org", "tonikitoo"),
- Reviewer("Antti Koivisto", ["koivisto@iki.fi", "antti@apple.com"], "anttik"),
+ Reviewer("Andreas Kling", "andreas.kling@nokia.com", "kling"),
+ Reviewer("Antonio Gomes", ["tonikitoo@webkit.org", "agomes@rim.com"], "tonikitoo"),
+ Reviewer("Antti Koivisto", ["koivisto@iki.fi", "antti@apple.com", "antti.j.koivisto@nokia.com"], "anttik"),
Reviewer("Ariya Hidayat", ["ariya@sencha.com", "ariya.hidayat@gmail.com", "ariya@webkit.org"], "ariya"),
Reviewer("Beth Dakin", "bdakin@apple.com", "dethbakin"),
Reviewer("Brady Eidson", "beidson@apple.com", "bradee-oh"),
@@ -228,21 +231,22 @@ reviewers_list = [
Reviewer("George Staikos", ["staikos@kde.org", "staikos@webkit.org"]),
Reviewer("Gustavo Noronha Silva", ["gns@gnome.org", "kov@webkit.org", "gustavo.noronha@collabora.co.uk"], "kov"),
Reviewer("Holger Freyther", ["zecke@selfish.org", "zecke@webkit.org"], "zecke"),
+ Reviewer("James Robinson", ["jamesr@chromium.org", "jamesr@google.com"], "jamesr"),
Reviewer("Jan Alonzo", ["jmalonzo@gmail.com", "jmalonzo@webkit.org"], "janm"),
Reviewer("Jeremy Orlow", "jorlow@chromium.org", "jorlow"),
Reviewer("Jian Li", "jianli@chromium.org", "jianli"),
Reviewer("John Sullivan", "sullivan@apple.com", "sullivan"),
Reviewer("Jon Honeycutt", "jhoneycutt@apple.com", "jhoneycutt"),
- Reviewer("Joseph Pecoraro", "joepeck@webkit.org", "JoePeck"),
+ Reviewer("Joseph Pecoraro", ["joepeck@webkit.org", "pecoraro@apple.com"], "JoePeck"),
Reviewer("Justin Garcia", "justin.garcia@apple.com", "justing"),
Reviewer("Ken Kocienda", "kocienda@apple.com"),
- Reviewer("Kenneth Rohde Christiansen", ["kenneth@webkit.org", "kenneth.christiansen@openbossa.org"], "kenne"),
+ Reviewer("Kenneth Rohde Christiansen", ["kenneth@webkit.org", "kenneth.christiansen@openbossa.org", "kenneth.christiansen@gmail.com"], "kenne"),
Reviewer("Kenneth Russell", "kbr@google.com", "kbr_google"),
Reviewer("Kent Tamura", "tkent@chromium.org", "tkent"),
Reviewer("Kevin Decker", "kdecker@apple.com", "superkevin"),
Reviewer("Kevin McCullough", "kmccullough@apple.com", "maculloch"),
Reviewer("Kevin Ollivier", ["kevino@theolliviers.com", "kevino@webkit.org"], "kollivier"),
- Reviewer("Lars Knoll", ["lars@trolltech.com", "lars@kde.org"], "lars"),
+ Reviewer("Lars Knoll", ["lars@trolltech.com", "lars@kde.org", "lars.knoll@nokia.com"], "lars"),
Reviewer("Laszlo Gombos", "laszlo.1.gombos@nokia.com", "lgombos"),
Reviewer("Maciej Stachowiak", "mjs@apple.com", "othermaciej"),
Reviewer("Mark Rowe", "mrowe@apple.com", "bdash"),
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html
new file mode 100644
index 0000000..4e0de08
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/failures/expected/hang.html
@@ -0,0 +1 @@
+timeout-thread
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt
new file mode 100644
index 0000000..2b38a06
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text-expected.txt
@@ -0,0 +1 @@
+text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html
new file mode 100644
index 0000000..8e27be7
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/passes/text.html
@@ -0,0 +1 @@
+text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt
new file mode 100644
index 0000000..2b38a06
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text-expected.txt
@@ -0,0 +1 @@
+text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html
new file mode 100644
index 0000000..8e27be7
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/http/tests/ssl/text.html
@@ -0,0 +1 @@
+text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt
index 16556e3..0619fde 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/platform/test/test_expectations.txt
@@ -8,5 +8,6 @@ WONTFIX : failures/expected/missing_image.html = MISSING PASS
WONTFIX : failures/expected/missing_text.html = MISSING PASS
WONTFIX : failures/expected/text.html = TEXT
WONTFIX : failures/expected/timeout.html = TIMEOUT
+WONTFIX SKIP : failures/expected/hang.html = TIMEOUT
WONTFIX SKIP : failures/expected/keyboard.html = CRASH
WONTFIX SKIP : failures/expected/exception.html = CRASH
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt b/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt
new file mode 100644
index 0000000..2b38a06
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text-expected.txt
@@ -0,0 +1 @@
+text-txt
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html b/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html
new file mode 100644
index 0000000..8e27be7
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/data/websocket/tests/passes/text.html
@@ -0,0 +1 @@
+text
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py
index bb63f5e..c543d91 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests.py
@@ -130,6 +130,32 @@ def extract_platforms(paths):
return platforms
+def has_intermediate_results(test, fallbacks, matching_platform,
+ path_exists=os.path.exists):
+ """Returns True if there is a test result that causes us to not delete
+ this duplicate.
+
+ For example, chromium-linux may be a duplicate of the checked in result,
+ but chromium-win may have a different result checked in. In this case,
+ we need to keep the duplicate results.
+
+ Args:
+ test: The test name.
+ fallbacks: A list of platforms we fall back on.
+ matching_platform: The platform that we found the duplicate test
+ result. We can stop checking here.
+ path_exists: Optional parameter that allows us to stub out
+ os.path.exists for testing.
+ """
+ for platform in fallbacks:
+ if platform == matching_platform:
+ return False
+ test_path = os.path.join('LayoutTests', 'platform', platform, test)
+ if path_exists(test_path):
+ return True
+ return False
+
+
def find_dups(hashes, port_fallbacks):
"""Yields info about redundant test expectations.
Args:
@@ -151,7 +177,12 @@ def find_dups(hashes, port_fallbacks):
for platform in platforms.keys():
for fallback in port_fallbacks[platform]:
if fallback in platforms.keys():
- yield test, platform, fallback, platforms[platform]
+ # We have to verify that there isn't an intermediate result
+ # that causes this duplicate hash to exist.
+ if not has_intermediate_results(test,
+ port_fallbacks[platform], fallback):
+ path = os.path.join('LayoutTests', platforms[platform])
+ yield test, platform, fallback, path
def deduplicate(glob_pattern):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py
index 66dda32..be2e381 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/deduplicate_tests_unittest.py
@@ -89,6 +89,47 @@ class ListDuplicatesTest(unittest.TestCase):
deduplicate_tests._BASE_PLATFORM: 'what/'},
deduplicate_tests.extract_platforms(['platform/foo/bar', 'what/']))
+ def test_has_intermediate_results(self):
+ test_cases = (
+ # If we found a duplicate in our first fallback, we have no
+ # intermediate results.
+ (False, ('fast/foo-expected.txt',
+ ['chromium-win', 'chromium', 'base'],
+ 'chromium-win',
+ lambda path: True)),
+ # Since chromium-win has a result, we have an intermediate result.
+ (True, ('fast/foo-expected.txt',
+ ['chromium-win', 'chromium', 'base'],
+ 'chromium',
+ lambda path: True)),
+ # There are no intermediate results.
+ (False, ('fast/foo-expected.txt',
+ ['chromium-win', 'chromium', 'base'],
+ 'chromium',
+ lambda path: False)),
+ # There are no intermediate results since a result for chromium is
+ # our duplicate file.
+ (False, ('fast/foo-expected.txt',
+ ['chromium-win', 'chromium', 'base'],
+ 'chromium',
+ lambda path: path == 'LayoutTests/platform/chromium/fast/foo-expected.txt')),
+ # We have an intermediate result in 'chromium' even though our
+ # duplicate is with the file in 'base'.
+ (True, ('fast/foo-expected.txt',
+ ['chromium-win', 'chromium', 'base'],
+ 'base',
+ lambda path: path == 'LayoutTests/platform/chromium/fast/foo-expected.txt')),
+ # We have an intermediate result in 'chromium-win' even though our
+ # duplicate is in 'base'.
+ (True, ('fast/foo-expected.txt',
+ ['chromium-win', 'chromium', 'base'],
+ 'base',
+ lambda path: path == 'LayoutTests/platform/chromium-win/fast/foo-expected.txt')),
+ )
+ for expected, inputs in test_cases:
+ self.assertEquals(expected,
+ deduplicate_tests.has_intermediate_results(*inputs))
+
def test_unique(self):
MockExecutive.response = (
'100644 blob 5053240b3353f6eb39f7cb00259785f16d121df2\tLayoutTests/mac/foo-expected.txt\n'
@@ -116,12 +157,12 @@ class ListDuplicatesTest(unittest.TestCase):
self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
self.assertEquals(2, len(result))
self.assertEquals({'test': 'animage.png',
- 'path': 'platform/chromium-linux/animage.png',
+ 'path': 'LayoutTests/platform/chromium-linux/animage.png',
'fallback': 'chromium-win',
'platform': 'chromium-linux'},
result[0])
self.assertEquals({'test': 'foo-expected.txt',
- 'path': 'platform/chromium-linux/foo-expected.txt',
+ 'path': 'LayoutTests/platform/chromium-linux/foo-expected.txt',
'fallback': 'chromium-win',
'platform': 'chromium-linux'},
result[1])
@@ -131,7 +172,7 @@ class ListDuplicatesTest(unittest.TestCase):
self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
self.assertEquals(1, len(result))
self.assertEquals({'test': 'foo-expected.txt',
- 'path': 'platform/chromium-linux/foo-expected.txt',
+ 'path': 'LayoutTests/platform/chromium-linux/foo-expected.txt',
'fallback': 'chromium-win',
'platform': 'chromium-linux'},
result[0])
@@ -141,7 +182,7 @@ class ListDuplicatesTest(unittest.TestCase):
self.assertEquals(('git', 'ls-tree', '-r', 'HEAD', 'LayoutTests'), MockExecutive.last_run_command[-1])
self.assertEquals(1, len(result))
self.assertEquals({'test': 'animage.png',
- 'path': 'platform/chromium-linux/animage.png',
+ 'path': 'LayoutTests/platform/chromium-linux/animage.png',
'fallback': 'chromium-win',
'platform': 'chromium-linux'},
result[0])
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
index ec33086..9b963ca 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
@@ -47,6 +47,7 @@ import sys
import thread
import threading
import time
+import traceback
import test_failures
@@ -54,6 +55,23 @@ _log = logging.getLogger("webkitpy.layout_tests.layout_package."
"dump_render_tree_thread")
+def find_thread_stack(id):
+ """Returns a stack object that can be used to dump a stack trace for
+ the given thread id (or None if the id is not found)."""
+ for thread_id, stack in sys._current_frames().items():
+ if thread_id == id:
+ return stack
+ return None
+
+
+def log_stack(stack):
+ """Log a stack trace to log.error()."""
+ for filename, lineno, name, line in traceback.extract_stack(stack):
+ _log.error('File: "%s", line %d, in %s' % (filename, lineno, name))
+ if line:
+ _log.error(' %s' % line.strip())
+
+
def _process_output(port, test_info, test_types, test_args, configuration,
output_dir, crash, timeout, test_run_time, actual_checksum,
output, error):
@@ -167,6 +185,7 @@ class SingleTestThread(threading.Thread):
self._test_args = test_args
self._configuration = configuration
self._output_dir = output_dir
+ self._driver = None
def run(self):
self._covered_run()
@@ -175,18 +194,19 @@ class SingleTestThread(threading.Thread):
# FIXME: this is a separate routine to work around a bug
# in coverage: see http://bitbucket.org/ned/coveragepy/issue/85.
test_info = self._test_info
- driver = self._port.create_driver(self._image_path, self._shell_args)
- driver.start()
+ self._driver = self._port.create_driver(self._image_path,
+ self._shell_args)
+ self._driver.start()
start = time.time()
crash, timeout, actual_checksum, output, error = \
- driver.run_test(test_info.uri.strip(), test_info.timeout,
- test_info.image_hash())
+ self._driver.run_test(test_info.uri.strip(), test_info.timeout,
+ test_info.image_hash())
end = time.time()
self._test_result = _process_output(self._port,
test_info, self._test_types, self._test_args,
self._configuration, self._output_dir, crash, timeout, end - start,
actual_checksum, output, error)
- driver.stop()
+ self._driver.stop()
def get_test_result(self):
return self._test_result
@@ -312,9 +332,7 @@ class TestShellThread(WatchableThread):
# Save the exception for our caller to see.
self._exception_info = sys.exc_info()
self._stop_time = time.time()
- # Re-raise it and die.
- _log.error('%s dying, exception raised: %s' % (self.getName(),
- self._exception_info))
+ _log.error('%s dying, exception raised' % self.getName())
self._stop_time = time.time()
@@ -426,7 +444,7 @@ class TestShellThread(WatchableThread):
worker.start()
thread_timeout = _milliseconds_to_seconds(
- _pad_timeout(test_info.timeout))
+ _pad_timeout(int(test_info.timeout)))
thread._next_timeout = time.time() + thread_timeout
worker.join(thread_timeout)
if worker.isAlive():
@@ -439,11 +457,13 @@ class TestShellThread(WatchableThread):
# that tradeoff in order to avoid losing the rest of this
# thread's results.
_log.error('Test thread hung: killing all DumpRenderTrees')
- worker._driver.stop()
+ if worker._driver:
+ worker._driver.stop()
try:
result = worker.get_test_result()
except AttributeError, e:
+ # This gets raised if the worker thread has already exited.
failures = []
_log.error('Cannot get results of test: %s' %
test_info.filename)
@@ -476,7 +496,7 @@ class TestShellThread(WatchableThread):
start = time.time()
thread_timeout = _milliseconds_to_seconds(
- _pad_timeout(test_info.timeout))
+ _pad_timeout(int(test_info.timeout)))
self._next_timeout = start + thread_timeout
crash, timeout, actual_checksum, output, error = \
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread_unittest.py
new file mode 100644
index 0000000..63f86d9
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread_unittest.py
@@ -0,0 +1,49 @@
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+""""Tests code paths not covered by the regular unit tests."""
+
+import sys
+import unittest
+
+import dump_render_tree_thread
+
+
+class Test(unittest.TestCase):
+ def test_find_thread_stack_found(self):
+ id, stack = sys._current_frames().items()[0]
+ found_stack = dump_render_tree_thread.find_thread_stack(id)
+ self.assertNotEqual(found_stack, None)
+
+ def test_find_thread_stack_not_found(self):
+ found_stack = dump_render_tree_thread.find_thread_stack(0)
+ self.assertEqual(found_stack, None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
index 15eceee..765b4d8 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
@@ -37,6 +37,8 @@ import time
import urllib2
import xml.dom.minidom
+from webkitpy.layout_tests.layout_package import test_results_uploader
+
import webkitpy.thirdparty.simplejson as simplejson
# A JSON results generator for generic tests.
@@ -85,13 +87,14 @@ class JSONResultsGeneratorBase(object):
INCREMENTAL_RESULTS_FILENAME = "incremental_results.json"
URL_FOR_TEST_LIST_JSON = \
- "http://%s/testfile?builder=%s&name=%s&testlistjson=1"
+ "http://%s/testfile?builder=%s&name=%s&testlistjson=1&testtype=%s"
def __init__(self, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
test_results_map, svn_repositories=None,
generate_incremental_results=False,
- test_results_server=None):
+ test_results_server=None,
+ test_type=""):
"""Modifies the results.json file. Grabs it off the archive directory
if it is not found locally.
@@ -129,6 +132,7 @@ class JSONResultsGeneratorBase(object):
self._svn_repositories = {}
self._test_results_server = test_results_server
+ self._test_type = test_type
self._json = None
self._archived_results = None
@@ -287,7 +291,8 @@ class JSONResultsGeneratorBase(object):
results_file_url = (self.URL_FOR_TEST_LIST_JSON %
(urllib2.quote(self._test_results_server),
urllib2.quote(self._builder_name),
- self.RESULTS_FILENAME))
+ self.RESULTS_FILENAME,
+ urllib2.quote(self._test_type)))
else:
# Check if we have the archived JSON file on the buildbot
# server.
@@ -518,9 +523,33 @@ class JSONResultsGenerator(JSONResultsGeneratorBase):
# The flag is for backward compatibility.
output_json_in_init = True
+ def _upload_json_files(self):
+ if not self._test_results_server or not self._test_type:
+ return
+
+ _log.info("Uploading JSON files for %s to the server: %s",
+ self._builder_name, self._test_results_server)
+ attrs = [("builder", self._builder_name), ("testtype", self._test_type)]
+ json_files = [self.INCREMENTAL_RESULTS_FILENAME]
+
+ files = [(file, os.path.join(self._results_directory, file))
+ for file in json_files]
+ uploader = test_results_uploader.TestResultsUploader(
+ self._test_results_server)
+ try:
+ # Set uploading timeout in case appengine server is having problem.
+ # 120 seconds are more than enough to upload test results.
+ uploader.upload(attrs, files, 120)
+ except Exception, err:
+ _log.error("Upload failed: %s" % err)
+ return
+
+ _log.info("JSON files uploaded.")
+
def __init__(self, port, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
- test_timings, failures, passed_tests, skipped_tests, all_tests):
+ test_timings, failures, passed_tests, skipped_tests, all_tests,
+ test_results_server=None, test_type=None):
"""Generates a JSON results file.
Args
@@ -536,8 +565,13 @@ class JSONResultsGenerator(JSONResultsGeneratorBase):
skipped_tests: A set containing all the skipped tests.
all_tests: List of all the tests that were run. This should not
include skipped tests.
+ test_results_server: server that hosts test results json.
+ test_type: the test type.
"""
+ self._test_type = test_type
+ self._results_directory = results_file_base_path
+
# Create a map of (name, TestResult).
test_results_map = dict()
get = test_results_map.get
@@ -557,10 +591,16 @@ class JSONResultsGenerator(JSONResultsGeneratorBase):
if test not in test_results_map:
test_results_map[test] = TestResult(test)
+ # Generate the JSON with incremental flag enabled.
+ # (This should also output the full result for now.)
super(JSONResultsGenerator, self).__init__(
builder_name, build_name, build_number,
results_file_base_path, builder_base_url, test_results_map,
- svn_repositories=port.test_repository_paths())
+ svn_repositories=port.test_repository_paths(),
+ generate_incremental_results=True,
+ test_results_server=test_results_server,
+ test_type=test_type)
if self.__class__.output_json_in_init:
self.generate_json_output()
+ self._upload_json_files()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
index 0dda774..9125f9e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
@@ -120,7 +120,7 @@ class Port(object):
def check_image_diff(self, override_step=None, logging=True):
"""This routine is used to check whether image_diff binary exists."""
- raise NotImplemented('Port.check_image_diff')
+ raise NotImplementedError('Port.check_image_diff')
def compare_text(self, expected_text, actual_text):
"""Return whether or not the two strings are *not* equal. This
@@ -141,26 +141,9 @@ class Port(object):
|tolerance| should be a percentage value (0.0 - 100.0).
If it is omitted, the port default tolerance value is used.
- While this is a generic routine, we include it in the Port
- interface so that it can be overriden for testing purposes."""
- executable = self._path_to_image_diff()
-
- if diff_filename:
- cmd = [executable, '--diff', expected_filename, actual_filename,
- diff_filename]
- else:
- cmd = [executable, expected_filename, actual_filename]
+ """
+ raise NotImplementedError('Port.diff_image')
- result = True
- try:
- if self._executive.run_command(cmd, return_exit_code=True) == 0:
- return False
- except OSError, e:
- if e.errno == errno.ENOENT or e.errno == errno.EACCES:
- _compare_available = False
- else:
- raise e
- return result
def diff_text(self, expected_text, actual_text,
expected_filename, actual_filename):
@@ -305,6 +288,18 @@ class Port(object):
"""Return the absolute path to the top of the LayoutTests directory."""
return self.path_from_webkit_base('LayoutTests')
+ def skips_layout_test(self, test_name):
+ """Figures out if the givent test is being skipped or not.
+
+ Test categories are handled as well."""
+ for test_or_category in self.skipped_layout_tests():
+ if test_or_category == test_name:
+ return True
+ category = os.path.join(self.layout_tests_dir(), test_or_category)
+ if os.path.isdir(category) and test_name.startswith(test_or_category):
+ return True
+ return False
+
def maybe_make_directory(self, *path):
"""Creates the specified directory if it doesn't already exist."""
try:
@@ -341,84 +336,16 @@ class Port(object):
if the port does not use expectations files."""
raise NotImplementedError('Port.path_to_test_expectations_file')
- def remove_directory(self, *path):
- """Recursively removes a directory, even if it's marked read-only.
-
- Remove the directory located at *path, if it exists.
-
- shutil.rmtree() doesn't work on Windows if any of the files
- or directories are read-only, which svn repositories and
- some .svn files are. We need to be able to force the files
- to be writable (i.e., deletable) as we traverse the tree.
-
- Even with all this, Windows still sometimes fails to delete a file,
- citing a permission error (maybe something to do with antivirus
- scans or disk indexing). The best suggestion any of the user
- forums had was to wait a bit and try again, so we do that too.
- It's hand-waving, but sometimes it works. :/
- """
- file_path = os.path.join(*path)
- if not os.path.exists(file_path):
- return
-
- win32 = False
- if sys.platform == 'win32':
- win32 = True
- # Some people don't have the APIs installed. In that case we'll do
- # without.
- try:
- win32api = __import__('win32api')
- win32con = __import__('win32con')
- except ImportError:
- win32 = False
-
- def remove_with_retry(rmfunc, path):
- os.chmod(path, os.stat.S_IWRITE)
- if win32:
- win32api.SetFileAttributes(path,
- win32con.FILE_ATTRIBUTE_NORMAL)
- try:
- return rmfunc(path)
- except EnvironmentError, e:
- if e.errno != errno.EACCES:
- raise
- print 'Failed to delete %s: trying again' % repr(path)
- time.sleep(0.1)
- return rmfunc(path)
- else:
-
- def remove_with_retry(rmfunc, path):
- if os.path.islink(path):
- return os.remove(path)
- else:
- return rmfunc(path)
-
- for root, dirs, files in os.walk(file_path, topdown=False):
- # For POSIX: making the directory writable guarantees
- # removability. Windows will ignore the non-read-only
- # bits in the chmod value.
- os.chmod(root, 0770)
- for name in files:
- remove_with_retry(os.remove, os.path.join(root, name))
- for name in dirs:
- remove_with_retry(os.rmdir, os.path.join(root, name))
-
- remove_with_retry(os.rmdir, file_path)
-
- def test_platform_name(self):
- return self._name
-
def relative_test_filename(self, filename):
"""Relative unix-style path for a filename under the LayoutTests
directory. Filenames outside the LayoutTests directory should raise
an error."""
- # FIXME This should assert() here but cannot due to printing_unittest.Testprinter
- # assert(filename.startswith(self.layout_tests_dir()))
+ assert(filename.startswith(self.layout_tests_dir()))
return filename[len(self.layout_tests_dir()) + 1:]
def results_directory(self):
"""Absolute path to the place to store the test results."""
- raise NotImplemented('Port.results_directory')
+ raise NotImplementedError('Port.results_directory')
def setup_test_run(self):
"""Perform port-specific work at the beginning of a test run."""
@@ -608,7 +535,6 @@ class Port(object):
_wdiff_available = False
return ""
raise
- assert(False) # Should never be reached.
_pretty_patch_error_html = "Failed to run PrettyPatch, see error console."
@@ -636,7 +562,7 @@ class Port(object):
return self._pretty_patch_error_html
def _webkit_build_directory(self, args):
- args = [self.script_path("webkit-build-directory")] + args
+ args = ["perl", self.script_path("webkit-build-directory")] + args
return self._executive.run_command(args).rstrip()
def _configuration_file_path(self):
@@ -691,6 +617,10 @@ class Port(object):
"""Returns the full path to the test driver (DumpRenderTree)."""
raise NotImplementedError('Port.path_to_driver')
+ def _path_to_webcore_library(self):
+ """Returns the full path to a built copy of WebCore."""
+ raise NotImplementedError('Port.path_to_webcore_library')
+
def _path_to_helper(self):
"""Returns the full path to the layout_test_helper binary, which
is used to help configure the system for the test run, or None
@@ -808,10 +738,5 @@ class Driver:
if it has exited."""
raise NotImplementedError('Driver.poll')
- def returncode(self):
- """Returns the system-specific returncode if the Driver has stopped or
- exited."""
- raise NotImplementedError('Driver.returncode')
-
def stop(self):
raise NotImplementedError('Driver.stop')
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py
index f821353..1cc426f 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base_unittest.py
@@ -27,15 +27,49 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import base
-import unittest
+import os
+import StringIO
+import sys
import tempfile
+import unittest
from webkitpy.common.system.executive import Executive, ScriptError
from webkitpy.thirdparty.mock import Mock
-class PortTest(unittest.TestCase):
+# FIXME: This makes StringIO objects work with "with". Remove
+# when we upgrade to 2.6.
+class NewStringIO(StringIO.StringIO):
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ pass
+
+
+class MockExecutive():
+ def __init__(self, exception):
+ self._exception = exception
+
+ def run_command(self, *args, **kwargs):
+ raise self._exception
+
+class UnitTestPort(base.Port):
+ """Subclass of base.Port used for unit testing."""
+ def __init__(self, configuration_contents=None, executive_exception=None):
+ base.Port.__init__(self)
+ self._configuration_contents = configuration_contents
+ if executive_exception:
+ self._executive = MockExecutive(executive_exception)
+
+ def _open_configuration_file(self):
+ if self._configuration_contents:
+ return NewStringIO(self._configuration_contents)
+ return base.Port._open_configuration_file(self)
+
+
+class PortTest(unittest.TestCase):
def test_format_wdiff_output_as_html(self):
output = "OUTPUT %s %s %s" % (base.Port._WDIFF_DEL, base.Port._WDIFF_ADD, base.Port._WDIFF_END)
html = base.Port()._format_wdiff_output_as_html(output)
@@ -63,6 +97,26 @@ class PortTest(unittest.TestCase):
new_file.flush()
return new_file
+ def test_pretty_patch_os_error(self):
+ port = UnitTestPort(executive_exception=OSError)
+ self.assertEqual(port.pretty_patch_text("patch.txt"),
+ port._pretty_patch_error_html)
+
+ # This tests repeated calls to make sure we cache the result.
+ self.assertEqual(port.pretty_patch_text("patch.txt"),
+ port._pretty_patch_error_html)
+
+ def test_pretty_patch_script_error(self):
+ # FIXME: This is some ugly white-box test hacking ...
+ base._pretty_patch_available = True
+ port = UnitTestPort(executive_exception=ScriptError)
+ self.assertEqual(port.pretty_patch_text("patch.txt"),
+ port._pretty_patch_error_html)
+
+ # This tests repeated calls to make sure we cache the result.
+ self.assertEqual(port.pretty_patch_text("patch.txt"),
+ port._pretty_patch_error_html)
+
def test_run_wdiff(self):
executive = Executive()
# This may fail on some systems. We could ask the port
@@ -109,6 +163,79 @@ class PortTest(unittest.TestCase):
self.assertFalse(base._wdiff_available)
base._wdiff_available = True
+ def test_default_configuration_notfound(self):
+ port = UnitTestPort()
+ self.assertEqual(port.default_configuration(), "Release")
+
+ def test_layout_tests_skipping(self):
+ port = base.Port()
+ port.skipped_layout_tests = lambda: ['foo/bar.html', 'media']
+ self.assertTrue(port.skips_layout_test('foo/bar.html'))
+ self.assertTrue(port.skips_layout_test('media/video-zoom.html'))
+ self.assertFalse(port.skips_layout_test('foo/foo.html'))
+
+ def test_default_configuration_found(self):
+ port = UnitTestPort(configuration_contents="Debug")
+ self.assertEqual(port.default_configuration(), "Debug")
+
+ def test_default_configuration_unknown(self):
+ port = UnitTestPort(configuration_contents="weird_value")
+ self.assertEqual(port.default_configuration(), "weird_value")
+
+ def test_setup_test_run(self):
+ port = base.Port()
+ # This routine is a no-op. We just test it for coverage.
+ port.setup_test_run()
+
+
+class VirtualTest(unittest.TestCase):
+ """Tests that various methods expected to be virtual are."""
+ def assertVirtual(self, method, *args, **kwargs):
+ self.assertRaises(NotImplementedError, method, *args, **kwargs)
+
+ def test_virtual_methods(self):
+ port = base.Port()
+ self.assertVirtual(port.baseline_path)
+ self.assertVirtual(port.baseline_search_path)
+ self.assertVirtual(port.check_build, None)
+ self.assertVirtual(port.check_image_diff)
+ self.assertVirtual(port.create_driver, None, None)
+ self.assertVirtual(port.diff_image, None, None)
+ self.assertVirtual(port.path_to_test_expectations_file)
+ self.assertVirtual(port.test_platform_name)
+ self.assertVirtual(port.results_directory)
+ self.assertVirtual(port.show_html_results_file, None)
+ self.assertVirtual(port.test_expectations)
+ self.assertVirtual(port.test_base_platform_names)
+ self.assertVirtual(port.test_platform_name)
+ self.assertVirtual(port.test_platforms)
+ self.assertVirtual(port.test_platform_name_to_name, None)
+ self.assertVirtual(port.version)
+ self.assertVirtual(port._path_to_apache)
+ self.assertVirtual(port._path_to_apache_config_file)
+ self.assertVirtual(port._path_to_driver)
+ self.assertVirtual(port._path_to_helper)
+ self.assertVirtual(port._path_to_image_diff)
+ self.assertVirtual(port._path_to_lighttpd)
+ self.assertVirtual(port._path_to_lighttpd_modules)
+ self.assertVirtual(port._path_to_lighttpd_php)
+ self.assertVirtual(port._path_to_wdiff)
+ self.assertVirtual(port._shut_down_http_server, None)
+
+ def test_virtual_driver_method(self):
+ self.assertRaises(NotImplementedError, base.Driver, base.Port, "", None)
+ self.assertVirtual(base.Driver, base.Port, "", None)
+
+ def test_virtual_driver_methods(self):
+ class VirtualDriver(base.Driver):
+ def __init__(self):
+ pass
+
+ driver = VirtualDriver()
+ self.assertVirtual(driver.run_test, None, None, None)
+ self.assertVirtual(driver.poll)
+ self.assertVirtual(driver.stop)
+
class DriverTest(unittest.TestCase):
@@ -124,3 +251,7 @@ class DriverTest(unittest.TestCase):
command_with_spaces = "valgrind --smc-check=\"check with spaces!\" --foo"
expected_parse = ["valgrind", "--smc-check=check with spaces!", "--foo"]
self._assert_wrapper(command_with_spaces, expected_parse)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
index 6cfc0b8..896eab1 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
@@ -46,6 +46,8 @@ import base
import http_server
from webkitpy.common.system.executive import Executive
+from webkitpy.layout_tests.layout_package import test_files
+from webkitpy.layout_tests.layout_package import test_expectations
# Chromium DRT on OSX uses WebKitDriver.
if sys.platform == 'darwin':
@@ -124,6 +126,26 @@ class ChromiumPort(base.Port):
return check_file_exists(image_diff_path, 'image diff exe',
override_step, logging)
+ def diff_image(self, expected_filename, actual_filename,
+ diff_filename=None, tolerance=0):
+ executable = self._path_to_image_diff()
+ if diff_filename:
+ cmd = [executable, '--diff', expected_filename, actual_filename,
+ diff_filename]
+ else:
+ cmd = [executable, expected_filename, actual_filename]
+
+ result = True
+ try:
+ if self._executive.run_command(cmd, return_exit_code=True) == 0:
+ return False
+ except OSError, e:
+ if e.errno == errno.ENOENT or e.errno == errno.EACCES:
+ _compare_available = False
+ else:
+ raise e
+ return result
+
def driver_name(self):
return "test_shell"
@@ -162,7 +184,7 @@ class ChromiumPort(base.Port):
shutil.rmtree(cachedir)
def show_results_html_file(self, results_filename):
- uri = self.filename_to_uri(results_filename)
+ uri = self.get_absolute_path(results_filename)
if self._options.use_drt:
# FIXME: This should use User.open_url
webbrowser.open(uri, new=1)
@@ -233,6 +255,24 @@ class ChromiumPort(base.Port):
with codecs.open(overrides_path, "r", "utf-8") as file:
return file.read() + drt_overrides
+ def skipped_layout_tests(self, extra_test_files=None):
+ expectations_str = self.test_expectations()
+ overrides_str = self.test_expectations_overrides()
+ test_platform_name = self.test_platform_name()
+ is_debug_mode = False
+
+ all_test_files = test_files.gather_test_files(self, '*')
+ if extra_test_files:
+ all_test_files.update(extra_test_files)
+
+ expectations = test_expectations.TestExpectations(
+ self, all_test_files, expectations_str, test_platform_name,
+ is_debug_mode, is_lint_mode=True,
+ tests_are_present=False, overrides=overrides_str)
+ tests_dir = self.layout_tests_dir()
+ return [self.relative_test_filename(test)
+ for test in expectations.get_tests_with_result_type(test_expectations.SKIP)]
+
def test_platform_names(self):
return self.test_base_platform_names() + ('win-xp',
'win-vista', 'win-7')
@@ -330,9 +370,6 @@ class ChromiumDriver(base.Driver):
# http://bugs.python.org/issue1731717
return self._proc.poll()
- def returncode(self):
- return self._proc.returncode
-
def _write_command_and_read_line(self, input=None):
"""Returns a tuple: (line, did_crash)"""
try:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py
index a32eafd..7a005b1 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_unittest.py
@@ -32,6 +32,7 @@ import chromium_mac
import chromium_win
import unittest
import StringIO
+import os
from webkitpy.thirdparty.mock import Mock
@@ -95,3 +96,22 @@ class ChromiumDriverTest(unittest.TestCase):
'/xcodebuild/Release/ImageDiff'))
# FIXME: Figure out how this is going to work on Windows.
#port = chromium_win.ChromiumWinPort('test-port', options=MockOptions())
+
+ def test_skipped_layout_tests(self):
+ class MockOptions:
+ def __init__(self):
+ self.use_drt = True
+
+ port = chromium_linux.ChromiumLinuxPort('test-port', options=MockOptions())
+
+ fake_test = os.path.join(port.layout_tests_dir(), "fast/js/not-good.js")
+
+ port.test_expectations = lambda: """BUG_TEST SKIP : fast/js/not-good.js = TEXT
+DEFER LINUX WIN : fast/js/very-good.js = TIMEOUT PASS"""
+ port.test_expectations_overrides = lambda: ''
+
+ skipped_tests = port.skipped_layout_tests(extra_test_files=[fake_test, ])
+ self.assertTrue("fast/js/not-good.js" in skipped_tests)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py
index e01bd2f..1af01ad 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py
@@ -70,14 +70,11 @@ def _read_file(path, mode='r'):
def _write_file(path, contents, mode='w'):
"""Write the string to the specified path.
- Returns nothing if the write fails, instead of raising an IOError.
+ Writes should never fail, so we may raise IOError.
"""
- try:
- with open(path, mode) as f:
+ with open(path, mode) as f:
f.write(contents)
- except IOError:
- pass
class DryRunPort(object):
@@ -134,9 +131,6 @@ class DryrunDriver(base.Driver):
def poll(self):
return None
- def returncode(self):
- return 0
-
def run_test(self, uri, timeoutms, image_hash):
test_name = self._uri_to_test(uri)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
index 258bf33..5704f65 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory.py
@@ -32,6 +32,10 @@
import sys
+ALL_PORT_NAMES = ['test', 'dryrun', 'mac', 'win', 'gtk', 'qt', 'chromium-mac',
+ 'chromium-linux', 'chromium-win', 'google-chrome-win',
+ 'google-chrome-mac', 'google-chrome-linux32', 'google-chrome-linux64']
+
def get(port_name=None, options=None):
"""Returns an object implementing the Port interface. If
@@ -88,3 +92,9 @@ def get(port_name=None, options=None):
return google_chrome.GetGoogleChromePort(port_name, options)
raise NotImplementedError('unsupported port: %s' % port_to_use)
+
+
+def get_all(options=None):
+ """Returns all the objects implementing the Port interface."""
+ return dict([(port_name, get(port_name, options=options))
+ for port_name in ALL_PORT_NAMES])
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py
index d8dffdf..c0a4c5e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/factory_unittest.py
@@ -34,6 +34,7 @@ import chromium_mac
import chromium_win
import dryrun
import factory
+import google_chrome
import gtk
import mac
import qt
@@ -69,16 +70,16 @@ class FactoryTest(unittest.TestCase):
def tearDown(self):
sys.platform = self.real_sys_platform
- def assert_port(self, port_name, expected_port):
+ def assert_port(self, port_name, expected_port, port_obj=None):
"""Helper assert for port_name.
Args:
port_name: port name to get port object.
expected_port: class of expected port object.
-
+ port_obj: optional port object
"""
- self.assertTrue(isinstance(factory.get(port_name=port_name),
- expected_port))
+ port_obj = port_obj or factory.get(port_name=port_name)
+ self.assertTrue(isinstance(port_obj, expected_port))
def assert_platform_port(self, platform, options, expected_port):
"""Helper assert for platform and options.
@@ -114,6 +115,18 @@ class FactoryTest(unittest.TestCase):
self.assert_platform_port("cygwin", None, win.WinPort)
self.assert_platform_port("cygwin", self.webkit_options, win.WinPort)
+ def test_google_chrome(self):
+ # The actual Chrome class names aren't available so we test that the
+ # objects we get are at least subclasses of the Chromium versions.
+ self.assert_port("google-chrome-linux32",
+ chromium_linux.ChromiumLinuxPort)
+ self.assert_port("google-chrome-linux64",
+ chromium_linux.ChromiumLinuxPort)
+ self.assert_port("google-chrome-win",
+ chromium_win.ChromiumWinPort)
+ self.assert_port("google-chrome-mac",
+ chromium_mac.ChromiumMacPort)
+
def test_gtk(self):
self.assert_port("gtk", gtk.GtkPort)
@@ -136,3 +149,38 @@ class FactoryTest(unittest.TestCase):
chromium_win.ChromiumWinPort)
self.assert_platform_port("cygwin", self.chromium_options,
chromium_win.ChromiumWinPort)
+
+ def test_get_all_ports(self):
+ ports = factory.get_all()
+ for name in factory.ALL_PORT_NAMES:
+ self.assertTrue(name in ports.keys())
+ self.assert_port("test", test.TestPort, ports["test"])
+ self.assert_port("dryrun-test", dryrun.DryRunPort, ports["dryrun"])
+ self.assert_port("dryrun-mac", dryrun.DryRunPort, ports["dryrun"])
+ self.assert_port("mac", mac.MacPort, ports["mac"])
+ self.assert_port("win", win.WinPort, ports["win"])
+ self.assert_port("gtk", gtk.GtkPort, ports["gtk"])
+ self.assert_port("qt", qt.QtPort, ports["qt"])
+ self.assert_port("chromium-mac", chromium_mac.ChromiumMacPort,
+ ports["chromium-mac"])
+ self.assert_port("chromium-linux", chromium_linux.ChromiumLinuxPort,
+ ports["chromium-linux"])
+ self.assert_port("chromium-win", chromium_win.ChromiumWinPort,
+ ports["chromium-win"])
+
+ def test_unknown_specified(self):
+ # Test what happens when you specify an unknown port.
+ orig_platform = sys.platform
+ self.assertRaises(NotImplementedError, factory.get,
+ port_name='unknown')
+
+ def test_unknown_default(self):
+ # Test what happens when you're running on an unknown platform.
+ orig_platform = sys.platform
+ sys.platform = 'unknown'
+ self.assertRaises(NotImplementedError, factory.get)
+ sys.platform = orig_platform
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf b/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf
index 2e9c82e..26ca22f 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/lighttpd.conf
@@ -22,7 +22,7 @@ mimetype.assign = (
".htm" => "text/html",
".xhtml" => "application/xhtml+xml",
".xhtmlmp" => "application/vnd.wap.xhtml+xml",
- ".js" => "text/javascript",
+ ".js" => "application/x-javascript",
".log" => "text/plain",
".conf" => "text/plain",
".text" => "text/plain",
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
index ae7d40c..327b19e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
@@ -26,14 +26,27 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import StringIO
+import sys
import unittest
+
import mac
-import StringIO
+import port_testcase
+
-class MacTest(unittest.TestCase):
+class MacTest(port_testcase.PortTestCase):
+ def make_port(self, options=port_testcase.MockOptions()):
+ if sys.platform != 'darwin':
+ return None
+ port_obj = mac.MacPort(options=options)
+ port_obj._options.results_directory = port_obj.results_directory()
+ port_obj._options.configuration = 'Release'
+ return port_obj
def test_skipped_file_paths(self):
- port = mac.MacPort()
+ port = self.make_port()
+ if not port:
+ return
skipped_paths = port._skipped_file_paths()
# FIXME: _skipped_file_paths should return WebKit-relative paths.
# So to make it unit testable, we strip the WebKit directory from the path.
@@ -57,7 +70,9 @@ svg/batik/text/smallFonts.svg
]
def test_skipped_file_paths(self):
- port = mac.MacPort()
+ port = self.make_port()
+ if not port:
+ return
skipped_file = StringIO.StringIO(self.example_skipped_file)
self.assertEqual(port._tests_from_skipped_file(skipped_file), self.example_skipped_tests)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py
new file mode 100644
index 0000000..2d650f5
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/port_testcase.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unit testing base class for Port implementations."""
+
+import os
+import tempfile
+import unittest
+
+
+class MockOptions(object):
+ def __init__(self,
+ results_directory='layout-test-results',
+ use_apache=True,
+ configuration='Release'):
+ self.results_directory = results_directory
+ self.use_apache = use_apache
+ self.configuration = configuration
+
+
+class PortTestCase(unittest.TestCase):
+ """Tests the WebKit port implementation."""
+ def make_port(self, options=MockOptions()):
+ """Override in subclass."""
+ raise NotImplementedError()
+
+ def test_http_server(self):
+ port = self.make_port()
+ if not port:
+ return
+ port.start_http_server()
+ port.stop_http_server()
+
+ def test_image_diff(self):
+ port = self.make_port()
+ if not port:
+ return
+
+ # FIXME: not sure why this shouldn't always be True
+ #self.assertTrue(port.check_image_diff())
+ if not port.check_image_diff():
+ return
+
+ dir = port.layout_tests_dir()
+ file1 = os.path.join(dir, 'fast', 'css', 'button_center.png')
+ file2 = os.path.join(dir, 'fast', 'css',
+ 'remove-shorthand-expected.png')
+ tmpfile = tempfile.mktemp()
+
+ self.assertFalse(port.diff_image(file1, file1))
+ self.assertTrue(port.diff_image(file1, file2))
+
+ self.assertTrue(port.diff_image(file1, file2, tmpfile))
+ # FIXME: this may not be being written?
+ # self.assertTrue(os.path.exists(tmpfile))
+ # os.remove(tmpfile)
+
+ def test_websocket_server(self):
+ port = self.make_port()
+ if not port:
+ return
+ port.start_websocket_server()
+ port.stop_websocket_server()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py
index 41b2ba0..158c633 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/qt.py
@@ -93,6 +93,12 @@ class QtPort(WebKitPort):
def _path_to_driver(self):
return self._build_path('bin/DumpRenderTree')
+ def _path_to_webcore_library(self):
+ return self._build_path('lib/libQtWebKit.so')
+
+ def _runtime_feature_list(self):
+ return None
+
def setup_environ_for_server(self):
env = webkit.WebKitPort.setup_environ_for_server(self)
env['QTWEBKIT_PLUGIN_PATH'] = self._build_path('lib/plugins')
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py
index 62ca693..8e0bc11 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/server_process.py
@@ -29,7 +29,6 @@
"""Package that implements the ServerProcess wrapper class"""
-import fcntl
import logging
import os
import select
@@ -37,6 +36,8 @@ import signal
import subprocess
import sys
import time
+if sys.platform != 'win32':
+ import fcntl
from webkitpy.common.system.executive import Executive
@@ -109,14 +110,6 @@ class ServerProcess:
return self._proc.poll()
return None
- def returncode(self):
- """Returns the exit code from the subprcoess; returns None if the
- process hasn't exited (this is a wrapper around subprocess.returncode).
- """
- if self._proc:
- return self._proc.returncode
- return None
-
def write(self, input):
"""Write a request to the subprocess. The subprocess is (re-)start()'ed
if is not already running."""
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
index e309334..a3a16c3 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
@@ -76,6 +76,9 @@ class TestPort(base.Port):
def options(self):
return self._options
+ def skipped_layout_tests(self):
+ return []
+
def path_to_test_expectations_file(self):
return self.path_from_webkit_base('WebKitTools', 'Scripts',
'webkitpy', 'layout_tests', 'data', 'platform', 'test',
@@ -145,9 +148,6 @@ class TestDriver(base.Driver):
def poll(self):
return True
- def returncode(self):
- return 0
-
def run_test(self, uri, timeoutms, image_hash):
basename = uri[(uri.rfind("/") + 1):uri.rfind(".html")]
@@ -179,6 +179,7 @@ class TestDriver(base.Driver):
raise ValueError('exception from ' + basename)
crash = 'crash' in basename
+ timeout = 'timeout' in basename or 'hang' in basename
timeout = 'timeout' in basename
if 'text' in basename:
output = basename + '_failed-txt\n'
@@ -196,6 +197,9 @@ class TestDriver(base.Driver):
f.write(basename + "-png\n")
if 'checksum' in basename:
checksum = basename + "_failed-checksum\n"
+
+ if 'hang' in basename:
+ time.sleep((float(timeoutms) * 4) / 1000.0)
else:
crash = False
timeout = False
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
index cedc028..b085ceb 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
# Copyright (C) 2010 Google Inc. All rights reserved.
+# Copyright (C) 2010 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>, University of Szeged
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -41,6 +42,9 @@ import signal
import sys
import time
import webbrowser
+import operator
+import tempfile
+import shutil
from webkitpy.common.system.executive import Executive
@@ -217,6 +221,66 @@ class WebKitPort(base.Port):
"platform/win",
]
+ def _runtime_feature_list(self):
+ """Return the supported features of DRT. If a port doesn't support
+ this DRT switch, it has to override this method to return None"""
+ driver_path = self._path_to_driver()
+ feature_list = ' '.join(os.popen(driver_path + " --print-supported-features 2>&1").readlines())
+ if "SupportedFeatures:" in feature_list:
+ return feature_list
+ return None
+
+ def _supported_symbol_list(self):
+ """Return the supported symbols of WebCore."""
+ webcore_library_path = self._path_to_webcore_library()
+ if not webcore_library_path:
+ return None
+ symbol_list = ' '.join(os.popen("nm " + webcore_library_path).readlines())
+ return symbol_list
+
+ def _directories_for_features(self):
+ """Return the supported feature dictionary. The keys are the
+ features and the values are the directories in lists."""
+ directories_for_features = {
+ "Accelerated Compositing": ["compositing"],
+ "3D Rendering": ["animations/3d", "transforms/3d"],
+ }
+ return directories_for_features
+
+ def _directories_for_symbols(self):
+ """Return the supported feature dictionary. The keys are the
+ symbols and the values are the directories in lists."""
+ directories_for_symbol = {
+ "MathMLElement": ["mathml"],
+ "GraphicsLayer": ["compositing"],
+ "WebCoreHas3DRendering": ["animations/3d", "transforms/3d"],
+ "WebGLShader": ["fast/canvas/webgl"],
+ "WMLElement": ["http/tests/wml", "fast/wml", "wml"],
+ "parseWCSSInputProperty": ["fast/wcss"],
+ "isXHTMLMPDocument": ["fast/xhtmlmp"],
+ }
+ return directories_for_symbol
+
+ def _skipped_tests_for_unsupported_features(self):
+ """Return the directories of unsupported tests. Search for the
+ symbols in the symbol_list, if found add the corresponding
+ directories to the skipped directory list."""
+ feature_list = self._runtime_feature_list()
+ directories = self._directories_for_features()
+
+ # if DRT feature detection not supported
+ if not feature_list:
+ feature_list = self._supported_symbol_list()
+ directories = self._directories_for_symbols()
+
+ if not feature_list:
+ return []
+
+ skipped_directories = [directories[feature]
+ for feature in directories.keys()
+ if feature not in feature_list]
+ return reduce(operator.add, skipped_directories)
+
def _tests_for_disabled_features(self):
# FIXME: This should use the feature detection from
# webkitperl/features.pm to match run-webkit-tests.
@@ -238,7 +302,8 @@ class WebKitPort(base.Port):
"http/tests/webarchive",
"svg/custom/image-with-prefix-in-webarchive.svg",
]
- return disabled_feature_tests + webarchive_tests
+ unsupported_feature_tests = self._skipped_tests_for_unsupported_features()
+ return disabled_feature_tests + webarchive_tests + unsupported_feature_tests
def _tests_from_skipped_file(self, skipped_file):
tests_to_skip = []
@@ -279,14 +344,17 @@ class WebKitPort(base.Port):
# This routine reads those files and turns contents into the
# format expected by test_expectations.
+ tests_to_skip = self.skipped_layout_tests()
+ skip_lines = map(lambda test_path: "BUG_SKIPPED SKIP : %s = FAIL" %
+ test_path, tests_to_skip)
+ return "\n".join(skip_lines)
+
+ def skipped_layout_tests(self):
# Use a set to allow duplicates
tests_to_skip = set(self._expectations_from_skipped_files())
-
tests_to_skip.update(self._tests_for_other_platforms())
tests_to_skip.update(self._tests_for_disabled_features())
- skip_lines = map(lambda test_path: "BUG_SKIPPED SKIP : %s = FAIL" %
- test_path, tests_to_skip)
- return "\n".join(skip_lines)
+ return tests_to_skip
def test_platform_name(self):
return self._name + self.version()
@@ -306,6 +374,9 @@ class WebKitPort(base.Port):
def _path_to_driver(self):
return self._build_path('DumpRenderTree')
+ def _path_to_webcore_library(self):
+ return None
+
def _path_to_helper(self):
return None
@@ -338,6 +409,10 @@ class WebKitDriver(base.Driver):
self._port = port
# FIXME: driver_options is never used.
self._image_path = image_path
+ self._driver_tempdir = tempfile.mkdtemp(prefix='DumpRenderTree-')
+
+ def __del__(self):
+ shutil.rmtree(self._driver_tempdir)
def start(self):
command = []
@@ -348,6 +423,7 @@ class WebKitDriver(base.Driver):
command.append('--pixel-tests')
environment = self._port.setup_environ_for_server()
environment['DYLD_FRAMEWORK_PATH'] = self._port._build_path()
+ environment['DUMPRENDERTREE_TEMP'] = self._driver_tempdir
self._server_process = server_process.ServerProcess(self._port,
"DumpRenderTree", command, environment)
@@ -359,9 +435,6 @@ class WebKitDriver(base.Driver):
self._server_process.start()
return
- def returncode(self):
- return self._server_process.returncode()
-
# FIXME: This function is huge.
def run_test(self, uri, timeoutms, image_hash):
if uri.startswith("file:///"):
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py
new file mode 100644
index 0000000..fbfadc3
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>, University of Szeged
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+from webkitpy.layout_tests.port.webkit import WebKitPort
+
+
+class TestWebKitPort(WebKitPort):
+ def __init__(self, symbol_list=None, feature_list=None):
+ self.symbol_list = symbol_list
+ self.feature_list = feature_list
+
+ def _runtime_feature_list(self):
+ return self.feature_list
+
+ def _supported_symbol_list(self):
+ return self.symbol_list
+
+ def _tests_for_other_platforms(self):
+ return ["media", ]
+
+ def _tests_for_disabled_features(self):
+ return ["accessibility", ]
+
+ def _skipped_file_paths(self):
+ return []
+
+class WebKitPortTest(unittest.TestCase):
+
+ def test_skipped_directories_for_symbols(self):
+ supported_symbols = ["GraphicsLayer", "WebCoreHas3DRendering", "isXHTMLMPDocument", "fooSymbol"]
+ expected_directories = set(["mathml", "fast/canvas/webgl", "http/tests/wml", "fast/wml", "wml", "fast/wcss"])
+ result_directories = set(TestWebKitPort(supported_symbols, None)._skipped_tests_for_unsupported_features())
+ self.assertEqual(result_directories, expected_directories)
+
+ def test_skipped_directories_for_features(self):
+ supported_features = ["Accelerated Compositing", "Foo Feature"]
+ expected_directories = set(["animations/3d", "transforms/3d"])
+ result_directories = set(TestWebKitPort(None, supported_features)._skipped_tests_for_unsupported_features())
+ self.assertEqual(result_directories, expected_directories)
+
+ def test_skipped_layout_tests(self):
+ self.assertEqual(TestWebKitPort(None, None).skipped_layout_tests(),
+ set(["media", "accessibility"]))
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 4132260..2e2da6d 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -53,7 +53,6 @@ import logging
import math
import optparse
import os
-import pdb
import platform
import Queue
import random
@@ -371,7 +370,7 @@ class TestRunner:
assert(test_size > 0)
except:
_log.critical("invalid chunk '%s'" % chunk_value)
- sys.exit(1)
+ return None
# Get the number of tests
num_tests = len(test_files)
@@ -675,8 +674,7 @@ class TestRunner:
# clear that testing was aborted. Otherwise,
# the tests that did not run would be assumed
# to have passed.
- raise (exception_info[0], exception_info[1],
- exception_info[2])
+ raise exception_info[0], exception_info[1], exception_info[2]
if thread.isAlive():
some_thread_is_alive = True
@@ -1350,11 +1348,18 @@ class TestRunner:
def read_test_files(files):
tests = []
for file in files:
- # FIXME: This could be cleaner using a list comprehension.
- for line in codecs.open(file, "r", "utf-8"):
- line = test_expectations.strip_comments(line)
- if line:
- tests.append(line)
+ try:
+ with codecs.open(file, 'r', 'utf-8') as file_contents:
+ # FIXME: This could be cleaner using a list comprehension.
+ for line in file_contents:
+ line = test_expectations.strip_comments(line)
+ if line:
+ tests.append(line)
+ except IOError, e:
+ if e.errno == errno.ENOENT:
+ _log.critical('')
+ _log.critical('--test-list file "%s" not found' % file)
+ raise
return tests
@@ -1398,7 +1403,12 @@ def run(port, options, args, regular_output=sys.stderr,
test_runner._print_config()
printer.print_update("Collecting tests ...")
- test_runner.collect_tests(args, last_unexpected_results)
+ try:
+ test_runner.collect_tests(args, last_unexpected_results)
+ except IOError, e:
+ if e.errno == errno.ENOENT:
+ return -1
+ raise
printer.print_update("Parsing expectations ...")
if options.lint_test_files:
@@ -1695,31 +1705,14 @@ def parse_args(args=None):
return options, args
-def _find_thread_stack(id):
- """Returns a stack object that can be used to dump a stack trace for
- the given thread id (or None if the id is not found)."""
- for thread_id, stack in sys._current_frames().items():
- if thread_id == id:
- return stack
- return None
-
-
-def _log_stack(stack):
- """Log a stack trace to log.error()."""
- for filename, lineno, name, line in traceback.extract_stack(stack):
- _log.error('File: "%s", line %d, in %s' % (filename, lineno, name))
- if line:
- _log.error(' %s' % line.strip())
-
-
def _log_wedged_thread(thread):
"""Log information about the given thread state."""
id = thread.id()
- stack = _find_thread_stack(id)
+ stack = dump_render_tree_thread.find_thread_stack(id)
assert(stack is not None)
_log.error("")
_log.error("thread %s (%d) is wedged" % (thread.getName(), id))
- _log_stack(stack)
+ dump_render_tree_thread.log_stack(stack)
_log.error("")
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
index 4cbfdfc..aa96962 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -32,9 +32,9 @@
import codecs
import logging
import os
-import pdb
import Queue
import sys
+import tempfile
import thread
import time
import threading
@@ -59,7 +59,10 @@ def passing_run(args=[], port_obj=None, record_results=False,
new_args.extend(args)
if not tests_included:
# We use the glob to test that globbing works.
- new_args.extend(['passes', 'failures/expected/*'])
+ new_args.extend(['passes',
+ 'http/tests',
+ 'websocket/tests',
+ 'failures/expected/*'])
options, parsed_args = run_webkit_tests.parse_args(new_args)
if port_obj is None:
port_obj = port.get(options.platform, options)
@@ -71,10 +74,12 @@ def logging_run(args=[], tests_included=False):
new_args = ['--no-record-results']
if not '--platform' in args:
new_args.extend(['--platform', 'test'])
- if args:
- new_args.extend(args)
+ new_args.extend(args)
if not tests_included:
- new_args.extend(['passes', 'failures/expected/*'])
+ new_args.extend(['passes',
+ 'http/tests'
+ 'websocket/tests',
+ 'failures/expected/*'])
options, parsed_args = run_webkit_tests.parse_args(new_args)
port_obj = port.get(options.platform, options)
buildbot_output = array_stream.ArrayStream()
@@ -119,6 +124,14 @@ class MainTest(unittest.TestCase):
self.assertTrue(out.empty())
self.assertFalse(err.empty())
+ def test_hung_thread(self):
+ res, out, err = logging_run(['--run-singly', '--time-out-ms=50',
+ 'failures/expected/hang.html'],
+ tests_included=True)
+ self.assertEqual(res, 0)
+ self.assertFalse(out.empty())
+ self.assertFalse(err.empty())
+
def test_keyboard_interrupt(self):
# Note that this also tests running a test marked as SKIP if
# you specify it explicitly.
@@ -175,6 +188,19 @@ class MainTest(unittest.TestCase):
# FIXME: verify # of tests run
self.assertTrue(passing_run(['passes/text.html'], tests_included=True))
+ def test_test_list(self):
+ filename = tempfile.mktemp()
+ tmpfile = file(filename, mode='w+')
+ tmpfile.write('passes/text.html')
+ tmpfile.close()
+ self.assertTrue(passing_run(['--test-list=%s' % filename],
+ tests_included=True))
+ os.remove(filename)
+ res, out, err = logging_run(['--test-list=%s' % filename],
+ tests_included=True)
+ self.assertEqual(res, -1)
+ self.assertFalse(err.empty())
+
def test_unexpected_failures(self):
# Run tests including the unexpected failures.
res, out, err = logging_run(tests_included=True)
@@ -279,6 +305,13 @@ class DryrunTest(unittest.TestCase):
self.assertTrue(passing_run(['--platform', 'dryrun-mac',
'fast/html']))
+ def test_test(self):
+ res, out, err = logging_run(['--platform', 'dryrun-test',
+ '--pixel-tests'])
+ self.assertEqual(res, 2)
+ self.assertFalse(out.empty())
+ self.assertFalse(err.empty())
+
class TestThread(dump_render_tree_thread.WatchableThread):
def __init__(self, started_queue, stopping_queue):
@@ -388,13 +421,6 @@ class StandaloneFunctionsTest(unittest.TestCase):
self.assertFalse(child_thread.isAlive())
oc.restore_output()
- def test_find_thread_stack(self):
- id, stack = sys._current_frames().items()[0]
- found_stack = run_webkit_tests._find_thread_stack(id)
- self.assertNotEqual(found_stack, None)
-
- found_stack = run_webkit_tests._find_thread_stack(0)
- self.assertEqual(found_stack, None)
if __name__ == '__main__':
unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queries.py b/WebKitTools/Scripts/webkitpy/tool/commands/queries.py
index 91ce5e9..9b8d162 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queries.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queries.py
@@ -37,6 +37,7 @@ from webkitpy.common.system.user import User
from webkitpy.tool.grammar import pluralize
from webkitpy.tool.multicommandtool import AbstractDeclarativeCommand
from webkitpy.common.system.deprecated_logging import log
+from webkitpy.layout_tests import port
class BugsToCommit(AbstractDeclarativeCommand):
@@ -284,3 +285,28 @@ and displayes the status of each builder."""
for builder in tool.buildbot.builder_statuses():
status_string = "ok" if builder["is_green"] else "FAIL"
print "%s : %s" % (status_string.ljust(4), builder["name"])
+
+
+class SkippedPorts(AbstractDeclarativeCommand):
+ name = "skipped-ports"
+ help_text = "Print the list of ports skipping the given layout test(s)"
+ long_help = """Scans the the Skipped file of each port and figure
+out what ports are skipping the test(s). Categories are taken in account too."""
+ argument_names = "TEST_NAME"
+
+ def execute(self, options, args, tool):
+ class Options:
+ # Required for chromium port.
+ use_drt = True
+
+ results = dict([(test_name, []) for test_name in args])
+ for port_name, port_object in tool.port_factory.get_all(options=Options).iteritems():
+ for test_name in args:
+ if port_object.skips_layout_test(test_name):
+ results[test_name].append(port_name)
+
+ for test_name, ports in results.iteritems():
+ if ports:
+ print "Ports skipping test %r: %s" % (test_name, ', '.join(ports))
+ else:
+ print "Test %r is not skipped by any port." % test_name
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queries_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queries_unittest.py
index 98ed545..7dddfe7 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queries_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queries_unittest.py
@@ -61,3 +61,13 @@ class QueryCommandsTest(CommandsTest):
def test_tree_status(self):
expected_stdout = "ok : Builder1\nok : Builder2\n"
self.assert_execute_outputs(TreeStatus(), None, expected_stdout)
+
+ def test_skipped_ports(self):
+ expected_stdout = "Ports skipping test 'media/foo/bar.html': test_port1, test_port2\n"
+ self.assert_execute_outputs(SkippedPorts(), ("media/foo/bar.html",), expected_stdout)
+
+ expected_stdout = "Ports skipping test 'foo': test_port1\n"
+ self.assert_execute_outputs(SkippedPorts(), ("foo",), expected_stdout)
+
+ expected_stdout = "Test 'media' is not skipped by any port.\n"
+ self.assert_execute_outputs(SkippedPorts(), ("media",), expected_stdout)
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
index f86e9a2..fd6543c 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/queues_unittest.py
@@ -28,12 +28,14 @@
import os
+from webkitpy.common.checkout.scm import CheckoutNeedsUpdate
from webkitpy.common.net.bugzilla import Attachment
from webkitpy.common.system.outputcapture import OutputCapture
from webkitpy.thirdparty.mock import Mock
from webkitpy.tool.commands.commandtest import CommandsTest
from webkitpy.tool.commands.queues import *
from webkitpy.tool.commands.queuestest import QueuesTest
+from webkitpy.tool.commands.stepsequence import StepSequence
from webkitpy.tool.mocktool import MockTool, MockSCM
@@ -133,6 +135,16 @@ class AbstractReviewQueueTest(CommandsTest):
self.assertFalse(queue.is_terminal_status("Foo"))
+class NeedsUpdateSequence(StepSequence):
+ def _run(self, tool, options, state):
+ raise CheckoutNeedsUpdate([], 1, "", None)
+
+
+class AlwaysCommitQueueTool(object):
+ def command_by_name(self, name):
+ return CommitQueue
+
+
class CommitQueueTest(QueuesTest):
def test_commit_queue(self):
expected_stderr = {
@@ -226,6 +238,20 @@ MOCK: update_work_items: commit-queue [106, 197]
attachments.sort(queue._patch_cmp)
self.assertEqual(attachments, expected_sort)
+ def test_auto_retry(self):
+ queue = CommitQueue()
+ options = Mock()
+ options.parent_command = "commit-queue"
+ tool = AlwaysCommitQueueTool()
+ sequence = NeedsUpdateSequence(None)
+
+ expected_stderr = "Commit failed because the checkout is out of date. Please update and try again.\n"
+ OutputCapture().assert_outputs(self, sequence.run_and_handle_errors, [tool, options], expected_exception=TryAgain, expected_stderr=expected_stderr)
+
+ self.assertEquals(options.update, True)
+ self.assertEquals(options.build, False)
+ self.assertEquals(options.test, False)
+
class RietveldUploadQueueTest(QueuesTest):
def test_rietveld_upload_queue(self):
diff --git a/WebKitTools/Scripts/webkitpy/tool/main.py b/WebKitTools/Scripts/webkitpy/tool/main.py
index 0dd5017..9531b63 100755
--- a/WebKitTools/Scripts/webkitpy/tool/main.py
+++ b/WebKitTools/Scripts/webkitpy/tool/main.py
@@ -40,6 +40,7 @@ from webkitpy.common.net.rietveld import Rietveld
from webkitpy.common.net.irc.ircproxy import IRCProxy
from webkitpy.common.system.executive import Executive
from webkitpy.common.system.user import User
+from webkitpy.layout_tests import port
import webkitpy.tool.commands as commands
# FIXME: Remove these imports once all the commands are in the root of the
# command package.
@@ -76,6 +77,7 @@ class WebKitPatch(MultiCommandTool):
self._checkout = None
self.status_server = StatusServer()
self.codereview = Rietveld(self.executive)
+ self.port_factory = port.factory
def scm(self):
# Lazily initialize SCM to not error-out before command line parsing (or when running non-scm commands).
diff --git a/WebKitTools/Scripts/webkitpy/tool/mocktool.py b/WebKitTools/Scripts/webkitpy/tool/mocktool.py
index 7eb8f4c..e3d36ce 100644
--- a/WebKitTools/Scripts/webkitpy/tool/mocktool.py
+++ b/WebKitTools/Scripts/webkitpy/tool/mocktool.py
@@ -556,6 +556,24 @@ class MockRietveld():
log("MOCK: Uploading patch to rietveld")
+class MockTestPort1():
+
+ def skips_layout_test(self, test_name):
+ return test_name in ["media/foo/bar.html", "foo"]
+
+
+class MockTestPort2():
+
+ def skips_layout_test(self, test_name):
+ return test_name == "media/foo/bar.html"
+
+
+class MockPortFactory():
+
+ def get_all(self, options=None):
+ return {"test_port1": MockTestPort1(), "test_port2": MockTestPort2()}
+
+
class MockTool():
def __init__(self, log_executive=False):
@@ -570,6 +588,7 @@ class MockTool():
self.status_server = MockStatusServer()
self.irc_password = "MOCK irc password"
self.codereview = MockRietveld(self.executive)
+ self.port_factory = MockPortFactory()
def scm(self):
return self._scm
diff --git a/WebKitTools/TestResultServer/model/datastorefile.py b/WebKitTools/TestResultServer/model/datastorefile.py
index dd4c366..ac28d64 100755
--- a/WebKitTools/TestResultServer/model/datastorefile.py
+++ b/WebKitTools/TestResultServer/model/datastorefile.py
@@ -58,6 +58,9 @@ class DataStoreFile(db.Model):
name = db.StringProperty()
data_keys = db.ListProperty(db.Key)
+ # keys to the data store entries that can be reused for new data.
+ # If it is emtpy, create new DataEntry.
+ new_data_keys = db.ListProperty(db.Key)
date = db.DateTimeProperty(auto_now_add=True)
data = None
@@ -82,11 +85,18 @@ class DataStoreFile(db.Model):
return False
start = 0
- keys = self.data_keys
- self.data_keys = []
+ # Use the new_data_keys to store new data. If all new data are saved
+ # successfully, swap new_data_keys and data_keys so we can reuse the
+ # data_keys entries in next run. If unable to save new data for any
+ # reason, only the data pointed by new_data_keys may be corrupted,
+ # the existing data_keys data remains untouched. The corrupted data
+ # in new_data_keys will be overwritten in next update.
+ keys = self.new_data_keys
+ self.new_data_keys = []
+
while start < len(data):
if keys:
- key = keys.pop(0)
+ key = keys[0]
data_entry = DataEntry.get(key)
if not data_entry:
logging.warning("Found key, but no data entry: %s", key)
@@ -95,16 +105,27 @@ class DataStoreFile(db.Model):
data_entry = DataEntry()
data_entry.data = db.Blob(data[start: start + MAX_ENTRY_LEN])
- data_entry.put()
+ try:
+ data_entry.put()
+ except Exception, err:
+ logging.error("Failed to save data store entry: %s", err)
+ if keys:
+ self.delete_data(keys)
+ return False
logging.info("Data saved: %s.", data_entry.key())
- self.data_keys.append(data_entry.key())
+ self.new_data_keys.append(data_entry.key())
+ if keys:
+ keys.pop(0)
start = start + MAX_ENTRY_LEN
if keys:
self.delete_data(keys)
+ temp_keys = self.data_keys
+ self.data_keys = self.new_data_keys
+ self.new_data_keys = temp_keys
self.data = data
return True
diff --git a/WebKitTools/TestResultServer/model/jsonresults.py b/WebKitTools/TestResultServer/model/jsonresults.py
index e5eb7f7..4520e96 100755
--- a/WebKitTools/TestResultServer/model/jsonresults.py
+++ b/WebKitTools/TestResultServer/model/jsonresults.py
@@ -413,6 +413,7 @@ class JsonResults(object):
# Use the incremental data if there is no aggregated file to merge.
file = TestFile()
file.builder = builder
+ file.test_type = test_type
file.name = JSON_RESULTS_FILE
new_results = incremental
logging.info("No existing json results, incremental json is saved.")
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
index c7f9a84..bf7a029 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
@@ -35,6 +35,7 @@
#include <WebKit2/WKBundlePagePrivate.h>
#include <WebKit2/WKRetainPtr.h>
#include <WebKit2/WKBundleRange.h>
+#include <WebKit2/WKBundleScriptWorld.h>
using namespace std;
@@ -198,9 +199,9 @@ void InjectedBundlePage::didReceiveTitleForFrame(WKBundlePageRef page, WKStringR
static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didReceiveTitleForFrame(title, frame);
}
-void InjectedBundlePage::didClearWindowForFrame(WKBundlePageRef page, WKBundleFrameRef frame, JSGlobalContextRef context, JSObjectRef window, const void *clientInfo)
+void InjectedBundlePage::didClearWindowForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void *clientInfo)
{
- static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didClearWindowForFrame(frame, context, window);
+ static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didClearWindowForFrame(frame, world);
}
void InjectedBundlePage::didCancelClientRedirectForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void* clientInfo)
@@ -412,11 +413,17 @@ void InjectedBundlePage::didReceiveTitleForFrame(WKStringRef title, WKBundleFram
InjectedBundle::shared().os() << "TITLE CHANGED: " << title << "\n";
}
-void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, JSGlobalContextRef context, JSObjectRef window)
+void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, WKBundleScriptWorldRef world)
{
if (!InjectedBundle::shared().isTestRunning())
return;
+ if (WKBundleScriptWorldNormalWorld() != world)
+ return;
+
+ JSGlobalContextRef context = WKBundleFrameGetJavaScriptContextForWorld(frame, world);
+ JSObjectRef window = JSContextGetGlobalObject(context);
+
JSValueRef exception = 0;
InjectedBundle::shared().layoutTestController()->makeWindowObject(context, window, &exception);
InjectedBundle::shared().gcController()->makeWindowObject(context, window, &exception);
diff --git a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
index 3f63bf3..cde1655 100644
--- a/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
+++ b/WebKitTools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
@@ -52,7 +52,7 @@ private:
static void didFinishLoadForFrame(WKBundlePageRef, WKBundleFrameRef, const void*);
static void didFailLoadWithErrorForFrame(WKBundlePageRef, WKBundleFrameRef, const void*);
static void didReceiveTitleForFrame(WKBundlePageRef, WKStringRef title, WKBundleFrameRef, const void*);
- static void didClearWindowForFrame(WKBundlePageRef, WKBundleFrameRef, JSGlobalContextRef, JSObjectRef window, const void*);
+ static void didClearWindowForFrame(WKBundlePageRef, WKBundleFrameRef, WKBundleScriptWorldRef, const void*);
static void didCancelClientRedirectForFrame(WKBundlePageRef, WKBundleFrameRef, const void*);
static void willPerformClientRedirectForFrame(WKBundlePageRef, WKBundleFrameRef, WKURLRef url, double delay, double date, const void*);
static void didChangeLocationWithinPageForFrame(WKBundlePageRef, WKBundleFrameRef, const void*);
@@ -67,7 +67,7 @@ private:
void didFinishLoadForFrame(WKBundleFrameRef);
void didFailLoadWithErrorForFrame(WKBundleFrameRef);
void didReceiveTitleForFrame(WKStringRef title, WKBundleFrameRef);
- void didClearWindowForFrame(WKBundleFrameRef, JSGlobalContextRef, JSObjectRef window);
+ void didClearWindowForFrame(WKBundleFrameRef, WKBundleScriptWorldRef);
void didCancelClientRedirectForFrame(WKBundleFrameRef);
void willPerformClientRedirectForFrame(WKBundleFrameRef, WKURLRef url, double delay, double date);
void didChangeLocationWithinPageForFrame(WKBundleFrameRef);